ActivityManagerService.java revision 7b38ea4a0a721bf44bba23fdb3911549fc554d6a
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.TaskRecord.INVALID_TASK_ID;
196import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
197import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
198import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
199import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
200import static android.view.WindowManager.TRANSIT_NONE;
201import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
202import static android.view.WindowManager.TRANSIT_TASK_OPEN;
203import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
204
205import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
206import static org.xmlpull.v1.XmlPullParser.START_TAG;
207
208import android.Manifest;
209import android.Manifest.permission;
210import android.annotation.NonNull;
211import android.annotation.Nullable;
212import android.annotation.UserIdInt;
213import android.app.Activity;
214import android.app.ActivityManager;
215import android.app.ActivityManager.RunningTaskInfo;
216import android.app.ActivityManager.StackInfo;
217import android.app.ActivityManager.TaskSnapshot;
218import android.app.ActivityManagerInternal;
219import android.app.ActivityManagerInternal.ScreenObserver;
220import android.app.ActivityManagerInternal.SleepToken;
221import android.app.ActivityManagerProto;
222import android.app.ActivityOptions;
223import android.app.ActivityThread;
224import android.app.AlertDialog;
225import android.app.AppGlobals;
226import android.app.AppOpsManager;
227import android.app.ApplicationErrorReport;
228import android.app.ApplicationThreadConstants;
229import android.app.BroadcastOptions;
230import android.app.ContentProviderHolder;
231import android.app.Dialog;
232import android.app.GrantedUriPermission;
233import android.app.IActivityController;
234import android.app.IActivityManager;
235import android.app.IApplicationThread;
236import android.app.IAssistDataReceiver;
237import android.app.IInstrumentationWatcher;
238import android.app.INotificationManager;
239import android.app.IProcessObserver;
240import android.app.IServiceConnection;
241import android.app.IStopUserCallback;
242import android.app.ITaskStackListener;
243import android.app.IUiAutomationConnection;
244import android.app.IUidObserver;
245import android.app.IUserSwitchObserver;
246import android.app.Instrumentation;
247import android.app.Notification;
248import android.app.NotificationManager;
249import android.app.PendingIntent;
250import android.app.PictureInPictureParams;
251import android.app.ProfilerInfo;
252import android.app.RemoteAction;
253import android.app.WaitResult;
254import android.app.WindowConfiguration.ActivityType;
255import android.app.WindowConfiguration.WindowingMode;
256import android.app.admin.DevicePolicyManager;
257import android.app.assist.AssistContent;
258import android.app.assist.AssistStructure;
259import android.app.backup.IBackupManager;
260import android.app.servertransaction.ConfigurationChangeItem;
261import android.app.usage.UsageEvents;
262import android.app.usage.UsageStatsManagerInternal;
263import android.appwidget.AppWidgetManager;
264import android.content.ActivityNotFoundException;
265import android.content.BroadcastReceiver;
266import android.content.ClipData;
267import android.content.ComponentCallbacks2;
268import android.content.ComponentName;
269import android.content.ContentProvider;
270import android.content.ContentResolver;
271import android.content.Context;
272import android.content.DialogInterface;
273import android.content.IContentProvider;
274import android.content.IIntentReceiver;
275import android.content.IIntentSender;
276import android.content.Intent;
277import android.content.IntentFilter;
278import android.content.pm.ActivityInfo;
279import android.content.pm.ApplicationInfo;
280import android.content.pm.ConfigurationInfo;
281import android.content.pm.IPackageDataObserver;
282import android.content.pm.IPackageManager;
283import android.content.pm.InstrumentationInfo;
284import android.content.pm.PackageInfo;
285import android.content.pm.PackageManager;
286import android.content.pm.PackageManager.NameNotFoundException;
287import android.content.pm.PackageManagerInternal;
288import android.content.pm.ParceledListSlice;
289import android.content.pm.PathPermission;
290import android.content.pm.PermissionInfo;
291import android.content.pm.ProviderInfo;
292import android.content.pm.ResolveInfo;
293import android.content.pm.SELinuxUtil;
294import android.content.pm.ServiceInfo;
295import android.content.pm.UserInfo;
296import android.content.res.CompatibilityInfo;
297import android.content.res.Configuration;
298import android.content.res.Resources;
299import android.database.ContentObserver;
300import android.graphics.Bitmap;
301import android.graphics.Point;
302import android.graphics.Rect;
303import android.hardware.display.DisplayManagerInternal;
304import android.location.LocationManager;
305import android.media.audiofx.AudioEffect;
306import android.metrics.LogMaker;
307import android.net.Proxy;
308import android.net.ProxyInfo;
309import android.net.Uri;
310import android.os.BatteryStats;
311import android.os.Binder;
312import android.os.Build;
313import android.os.Bundle;
314import android.os.Debug;
315import android.os.DropBoxManager;
316import android.os.Environment;
317import android.os.FactoryTest;
318import android.os.FileObserver;
319import android.os.FileUtils;
320import android.os.Handler;
321import android.os.IBinder;
322import android.os.IDeviceIdentifiersPolicyService;
323import android.os.IPermissionController;
324import android.os.IProcessInfoService;
325import android.os.IProgressListener;
326import android.os.LocaleList;
327import android.os.Looper;
328import android.os.Message;
329import android.os.Parcel;
330import android.os.ParcelFileDescriptor;
331import android.os.PersistableBundle;
332import android.os.PowerManager;
333import android.os.PowerManager.ServiceType;
334import android.os.PowerManagerInternal;
335import android.os.Process;
336import android.os.RemoteCallbackList;
337import android.os.RemoteException;
338import android.os.ResultReceiver;
339import android.os.ServiceManager;
340import android.os.ShellCallback;
341import android.os.StrictMode;
342import android.os.SystemClock;
343import android.os.SystemProperties;
344import android.os.Trace;
345import android.os.TransactionTooLargeException;
346import android.os.UpdateLock;
347import android.os.UserHandle;
348import android.os.UserManager;
349import android.os.WorkSource;
350import android.os.storage.IStorageManager;
351import android.os.storage.StorageManager;
352import android.os.storage.StorageManagerInternal;
353import android.provider.Downloads;
354import android.provider.Settings;
355import android.service.voice.IVoiceInteractionSession;
356import android.service.voice.VoiceInteractionManagerInternal;
357import android.telecom.TelecomManager;
358import android.text.TextUtils;
359import android.text.format.DateUtils;
360import android.text.format.Time;
361import android.text.style.SuggestionSpan;
362import android.util.ArrayMap;
363import android.util.ArraySet;
364import android.util.AtomicFile;
365import android.util.DebugUtils;
366import android.util.EventLog;
367import android.util.Log;
368import android.util.LongSparseArray;
369import android.util.Pair;
370import android.util.PrintWriterPrinter;
371import android.util.Slog;
372import android.util.SparseArray;
373import android.util.SparseIntArray;
374import android.util.StatsLog;
375import android.util.TimeUtils;
376import android.util.TimingsTraceLog;
377import android.util.Xml;
378import android.util.proto.ProtoOutputStream;
379import android.util.proto.ProtoUtils;
380import android.view.Gravity;
381import android.view.IRecentsAnimationRunner;
382import android.view.LayoutInflater;
383import android.view.RemoteAnimationDefinition;
384import android.view.View;
385import android.view.WindowManager;
386
387import android.view.autofill.AutofillManagerInternal;
388import com.android.internal.R;
389import com.android.internal.annotations.GuardedBy;
390import com.android.internal.annotations.VisibleForTesting;
391import com.android.internal.app.AssistUtils;
392import com.android.internal.app.DumpHeapActivity;
393import com.android.internal.app.IAppOpsCallback;
394import com.android.internal.app.IAppOpsService;
395import com.android.internal.app.IVoiceInteractor;
396import com.android.internal.app.ProcessMap;
397import com.android.internal.app.SystemUserHomeActivity;
398import com.android.internal.app.procstats.ProcessStats;
399import com.android.internal.logging.MetricsLogger;
400import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
401import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
402import com.android.internal.notification.SystemNotificationChannels;
403import com.android.internal.os.BackgroundThread;
404import com.android.internal.os.BatteryStatsImpl;
405import com.android.internal.os.BinderInternal;
406import com.android.internal.os.logging.MetricsLoggerWrapper;
407import com.android.internal.os.ByteTransferPipe;
408import com.android.internal.os.IResultReceiver;
409import com.android.internal.os.ProcessCpuTracker;
410import com.android.internal.os.TransferPipe;
411import com.android.internal.os.Zygote;
412import com.android.internal.policy.IKeyguardDismissCallback;
413import com.android.internal.policy.KeyguardDismissCallback;
414import com.android.internal.telephony.TelephonyIntents;
415import com.android.internal.util.ArrayUtils;
416import com.android.internal.util.DumpUtils;
417import com.android.internal.util.FastPrintWriter;
418import com.android.internal.util.FastXmlSerializer;
419import com.android.internal.util.MemInfoReader;
420import com.android.internal.util.Preconditions;
421import com.android.server.AlarmManagerInternal;
422import com.android.server.AppOpsService;
423import com.android.server.AttributeCache;
424import com.android.server.DeviceIdleController;
425import com.android.server.IntentResolver;
426import com.android.server.IoThread;
427import com.android.server.LocalServices;
428import com.android.server.LockGuard;
429import com.android.server.NetworkManagementInternal;
430import com.android.server.RescueParty;
431import com.android.server.ServiceThread;
432import com.android.server.SystemConfig;
433import com.android.server.SystemService;
434import com.android.server.SystemServiceManager;
435import com.android.server.ThreadPriorityBooster;
436import com.android.server.Watchdog;
437import com.android.server.am.ActivityStack.ActivityState;
438import com.android.server.am.proto.ActivityManagerServiceProto;
439import com.android.server.am.proto.BroadcastProto;
440import com.android.server.am.proto.GrantUriProto;
441import com.android.server.am.proto.ImportanceTokenProto;
442import com.android.server.am.proto.MemInfoProto;
443import com.android.server.am.proto.NeededUriGrantsProto;
444import com.android.server.am.proto.ProcessOomProto;
445import com.android.server.am.proto.ProcessToGcProto;
446import com.android.server.am.proto.ProcessesProto;
447import com.android.server.am.proto.ProcessesProto.UidObserverRegistrationProto;
448import com.android.server.am.proto.StickyBroadcastProto;
449import com.android.server.firewall.IntentFirewall;
450import com.android.server.job.JobSchedulerInternal;
451import com.android.server.pm.Installer;
452import com.android.server.pm.Installer.InstallerException;
453import com.android.server.utils.PriorityDump;
454import com.android.server.vr.VrManagerInternal;
455import com.android.server.wm.PinnedStackWindowController;
456import com.android.server.wm.WindowManagerService;
457
458import dalvik.system.VMRuntime;
459
460import libcore.io.IoUtils;
461import libcore.util.EmptyArray;
462
463import com.google.android.collect.Lists;
464import com.google.android.collect.Maps;
465
466import org.xmlpull.v1.XmlPullParser;
467import org.xmlpull.v1.XmlPullParserException;
468import org.xmlpull.v1.XmlSerializer;
469
470import java.io.File;
471import java.io.FileDescriptor;
472import java.io.FileInputStream;
473import java.io.FileNotFoundException;
474import java.io.FileOutputStream;
475import java.io.IOException;
476import java.io.InputStreamReader;
477import java.io.PrintWriter;
478import java.io.StringWriter;
479import java.io.UnsupportedEncodingException;
480import java.lang.ref.WeakReference;
481import java.nio.charset.StandardCharsets;
482import java.text.DateFormat;
483import java.text.SimpleDateFormat;
484import java.util.ArrayList;
485import java.util.Arrays;
486import java.util.Collections;
487import java.util.Comparator;
488import java.util.Date;
489import java.util.HashMap;
490import java.util.HashSet;
491import java.util.Iterator;
492import java.util.List;
493import java.util.Locale;
494import java.util.Map;
495import java.util.Objects;
496import java.util.Set;
497import java.util.concurrent.CountDownLatch;
498import java.util.concurrent.Executor;
499import java.util.concurrent.atomic.AtomicBoolean;
500import java.util.concurrent.atomic.AtomicLong;
501
502public class ActivityManagerService extends IActivityManager.Stub
503        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
504
505    /**
506     * Priority we boost main thread and RT of top app to.
507     */
508    public static final int TOP_APP_PRIORITY_BOOST = -10;
509
510    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
511    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
512    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
513    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
514    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
515    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
516    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
517    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
518    private static final String TAG_LRU = TAG + POSTFIX_LRU;
519    private static final String TAG_MU = TAG + POSTFIX_MU;
520    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
521    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
522    private static final String TAG_POWER = TAG + POSTFIX_POWER;
523    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
524    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
525    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
526    private static final String TAG_PSS = TAG + POSTFIX_PSS;
527    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
528    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
529    private static final String TAG_STACK = TAG + POSTFIX_STACK;
530    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
531    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
532    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
533    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
534
535    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
536    // here so that while the job scheduler can depend on AMS, the other way around
537    // need not be the case.
538    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
539
540    /** Control over CPU and battery monitoring */
541    // write battery stats every 30 minutes.
542    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
543    static final boolean MONITOR_CPU_USAGE = true;
544    // don't sample cpu less than every 5 seconds.
545    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
546    // wait possibly forever for next cpu sample.
547    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
548    static final boolean MONITOR_THREAD_CPU_USAGE = false;
549
550    // The flags that are set for all calls we make to the package manager.
551    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
552
553    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
554
555    // Amount of time after a call to stopAppSwitches() during which we will
556    // prevent further untrusted switches from happening.
557    static final long APP_SWITCH_DELAY_TIME = 5*1000;
558
559    // How long we wait for a launched process to attach to the activity manager
560    // before we decide it's never going to come up for real.
561    static final int PROC_START_TIMEOUT = 10*1000;
562    // How long we wait for an attached process to publish its content providers
563    // before we decide it must be hung.
564    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
565
566    // How long we wait for a launched process to attach to the activity manager
567    // before we decide it's never going to come up for real, when the process was
568    // started with a wrapper for instrumentation (such as Valgrind) because it
569    // could take much longer than usual.
570    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
571
572    // How long we allow a receiver to run before giving up on it.
573    static final int BROADCAST_FG_TIMEOUT = 10*1000;
574    static final int BROADCAST_BG_TIMEOUT = 60*1000;
575
576    // How long we wait until we timeout on key dispatching.
577    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
578
579    // How long we wait until we timeout on key dispatching during instrumentation.
580    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
581
582    // How long to wait in getAssistContextExtras for the activity and foreground services
583    // to respond with the result.
584    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
585
586    // How long top wait when going through the modern assist (which doesn't need to block
587    // on getting this result before starting to launch its UI).
588    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
589
590    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
591    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
592
593    // Maximum number of persisted Uri grants a package is allowed
594    static final int MAX_PERSISTED_URI_GRANTS = 128;
595
596    static final int MY_PID = myPid();
597
598    static final String[] EMPTY_STRING_ARRAY = new String[0];
599
600    // How many bytes to write into the dropbox log before truncating
601    static final int DROPBOX_MAX_SIZE = 192 * 1024;
602    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
603    // as one line, but close enough for now.
604    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
605
606    // Access modes for handleIncomingUser.
607    static final int ALLOW_NON_FULL = 0;
608    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
609    static final int ALLOW_FULL_ONLY = 2;
610
611    // Necessary ApplicationInfo flags to mark an app as persistent
612    private static final int PERSISTENT_MASK =
613            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
614
615    // Intent sent when remote bugreport collection has been completed
616    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
617            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
618
619    // Used to indicate that an app transition should be animated.
620    static final boolean ANIMATE = true;
621
622    // Determines whether to take full screen screenshots
623    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
624
625    /**
626     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
627     */
628    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
629
630    /**
631     * State indicating that there is no need for any blocking for network.
632     */
633    @VisibleForTesting
634    static final int NETWORK_STATE_NO_CHANGE = 0;
635
636    /**
637     * State indicating that the main thread needs to be informed about the network wait.
638     */
639    @VisibleForTesting
640    static final int NETWORK_STATE_BLOCK = 1;
641
642    /**
643     * State indicating that any threads waiting for network state to get updated can be unblocked.
644     */
645    @VisibleForTesting
646    static final int NETWORK_STATE_UNBLOCK = 2;
647
648    // Max character limit for a notification title. If the notification title is larger than this
649    // the notification will not be legible to the user.
650    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
651
652    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
653
654    /** All system services */
655    SystemServiceManager mSystemServiceManager;
656
657    // Wrapper around VoiceInteractionServiceManager
658    private AssistUtils mAssistUtils;
659
660    // Keeps track of the active voice interaction service component, notified from
661    // VoiceInteractionManagerService
662    ComponentName mActiveVoiceInteractionServiceComponent;
663
664    private Installer mInstaller;
665
666    /** Run all ActivityStacks through this */
667    final ActivityStackSupervisor mStackSupervisor;
668    private final KeyguardController mKeyguardController;
669
670    private final ActivityStartController mActivityStartController;
671
672    final ClientLifecycleManager mLifecycleManager;
673
674    final TaskChangeNotificationController mTaskChangeNotificationController;
675
676    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
677
678    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
679
680    public final IntentFirewall mIntentFirewall;
681
682    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
683    // default action automatically.  Important for devices without direct input
684    // devices.
685    private boolean mShowDialogs = true;
686
687    private final VrController mVrController;
688
689    // VR Vr2d Display Id.
690    int mVr2dDisplayId = INVALID_DISPLAY;
691
692    // Whether we should use SCHED_FIFO for UI and RenderThreads.
693    private boolean mUseFifoUiScheduling = false;
694
695    BroadcastQueue mFgBroadcastQueue;
696    BroadcastQueue mBgBroadcastQueue;
697    // Convenient for easy iteration over the queues. Foreground is first
698    // so that dispatch of foreground broadcasts gets precedence.
699    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
700
701    BroadcastStats mLastBroadcastStats;
702    BroadcastStats mCurBroadcastStats;
703
704    BroadcastQueue broadcastQueueForIntent(Intent intent) {
705        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
706        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
707                "Broadcast intent " + intent + " on "
708                + (isFg ? "foreground" : "background") + " queue");
709        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
710    }
711
712    /**
713     * The last resumed activity. This is identical to the current resumed activity most
714     * of the time but could be different when we're pausing one activity before we resume
715     * another activity.
716     */
717    private ActivityRecord mLastResumedActivity;
718
719    /**
720     * If non-null, we are tracking the time the user spends in the currently focused app.
721     */
722    private AppTimeTracker mCurAppTimeTracker;
723
724    /**
725     * List of intents that were used to start the most recent tasks.
726     */
727    private final RecentTasks mRecentTasks;
728
729    /**
730     * For addAppTask: cached of the last activity component that was added.
731     */
732    ComponentName mLastAddedTaskComponent;
733
734    /**
735     * For addAppTask: cached of the last activity uid that was added.
736     */
737    int mLastAddedTaskUid;
738
739    /**
740     * For addAppTask: cached of the last ActivityInfo that was added.
741     */
742    ActivityInfo mLastAddedTaskActivity;
743
744    /**
745     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
746     */
747    String mDeviceOwnerName;
748
749    /**
750     * The controller for all operations related to locktask.
751     */
752    final LockTaskController mLockTaskController;
753
754    final UserController mUserController;
755
756    /**
757     * Packages that are being allowed to perform unrestricted app switches.  Mapping is
758     * User -> Type -> uid.
759     */
760    final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
761
762    final AppErrors mAppErrors;
763
764    final AppWarnings mAppWarnings;
765
766    /**
767     * Dump of the activity state at the time of the last ANR. Cleared after
768     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
769     */
770    String mLastANRState;
771
772    /**
773     * Indicates the maximum time spent waiting for the network rules to get updated.
774     */
775    @VisibleForTesting
776    long mWaitForNetworkTimeoutMs;
777
778    /**
779     * Helper class which strips out priority and proto arguments then calls the dump function with
780     * the appropriate arguments. If priority arguments are omitted, function calls the legacy
781     * dump command.
782     * If priority arguments are omitted all sections are dumped, otherwise sections are dumped
783     * according to their priority.
784     */
785    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
786        @Override
787        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
788                boolean asProto) {
789            if (asProto) return;
790            doDump(fd, pw, new String[]{"activities"}, asProto);
791        }
792
793        @Override
794        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
795            doDump(fd, pw, new String[]{"-a", "--normal-priority"}, asProto);
796        }
797
798        @Override
799        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
800            doDump(fd, pw, args, asProto);
801        }
802    };
803
804    public boolean canShowErrorDialogs() {
805        return mShowDialogs && !mSleeping && !mShuttingDown
806                && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
807                && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
808                        mUserController.getCurrentUserId())
809                && !(UserManager.isDeviceInDemoMode(mContext)
810                        && mUserController.getCurrentUser().isDemo());
811    }
812
813    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
814            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
815
816    static void boostPriorityForLockedSection() {
817        sThreadPriorityBooster.boost();
818    }
819
820    static void resetPriorityAfterLockedSection() {
821        sThreadPriorityBooster.reset();
822    }
823
824    public class PendingAssistExtras extends Binder implements Runnable {
825        public final ActivityRecord activity;
826        public boolean isHome;
827        public final Bundle extras;
828        public final Intent intent;
829        public final String hint;
830        public final IAssistDataReceiver receiver;
831        public final int userHandle;
832        public boolean haveResult = false;
833        public Bundle result = null;
834        public AssistStructure structure = null;
835        public AssistContent content = null;
836        public Bundle receiverExtras;
837
838        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
839                String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
840                int _userHandle) {
841            activity = _activity;
842            extras = _extras;
843            intent = _intent;
844            hint = _hint;
845            receiver = _receiver;
846            receiverExtras = _receiverExtras;
847            userHandle = _userHandle;
848        }
849
850        @Override
851        public void run() {
852            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
853            synchronized (this) {
854                haveResult = true;
855                notifyAll();
856            }
857            pendingAssistExtrasTimedOut(this);
858        }
859    }
860
861    final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
862
863    /**
864     * Process management.
865     */
866    final ProcessList mProcessList = new ProcessList();
867
868    /**
869     * All of the applications we currently have running organized by name.
870     * The keys are strings of the application package name (as
871     * returned by the package manager), and the keys are ApplicationRecord
872     * objects.
873     */
874    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
875
876    /**
877     * Tracking long-term execution of processes to look for abuse and other
878     * bad app behavior.
879     */
880    final ProcessStatsService mProcessStats;
881
882    /**
883     * The currently running isolated processes.
884     */
885    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
886
887    /**
888     * Counter for assigning isolated process uids, to avoid frequently reusing the
889     * same ones.
890     */
891    int mNextIsolatedProcessUid = 0;
892
893    /**
894     * The currently running heavy-weight process, if any.
895     */
896    ProcessRecord mHeavyWeightProcess = null;
897
898    /**
899     * Non-persistent appId whitelist for background restrictions
900     */
901    int[] mBackgroundAppIdWhitelist = new int[] {
902            BLUETOOTH_UID
903    };
904
905    /**
906     * Broadcast actions that will always be deliverable to unlaunched/background apps
907     */
908    ArraySet<String> mBackgroundLaunchBroadcasts;
909
910    /**
911     * All of the processes we currently have running organized by pid.
912     * The keys are the pid running the application.
913     *
914     * <p>NOTE: This object is protected by its own lock, NOT the global
915     * activity manager lock!
916     */
917    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
918
919    /**
920     * All of the processes that have been forced to be important.  The key
921     * is the pid of the caller who requested it (we hold a death
922     * link on it).
923     */
924    abstract class ImportanceToken implements IBinder.DeathRecipient {
925        final int pid;
926        final IBinder token;
927        final String reason;
928
929        ImportanceToken(int _pid, IBinder _token, String _reason) {
930            pid = _pid;
931            token = _token;
932            reason = _reason;
933        }
934
935        @Override
936        public String toString() {
937            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
938                    + " " + reason + " " + pid + " " + token + " }";
939        }
940
941        void writeToProto(ProtoOutputStream proto, long fieldId) {
942            final long pToken = proto.start(fieldId);
943            proto.write(ImportanceTokenProto.PID, pid);
944            if (token != null) {
945                proto.write(ImportanceTokenProto.TOKEN, token.toString());
946            }
947            proto.write(ImportanceTokenProto.REASON, reason);
948            proto.end(pToken);
949        }
950    }
951    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
952
953    /**
954     * List of records for processes that someone had tried to start before the
955     * system was ready.  We don't start them at that point, but ensure they
956     * are started by the time booting is complete.
957     */
958    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
959
960    /**
961     * List of persistent applications that are in the process
962     * of being started.
963     */
964    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
965
966    /**
967     * Processes that are being forcibly torn down.
968     */
969    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
970
971    /**
972     * List of running applications, sorted by recent usage.
973     * The first entry in the list is the least recently used.
974     */
975    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
976
977    /**
978     * Where in mLruProcesses that the processes hosting activities start.
979     */
980    int mLruProcessActivityStart = 0;
981
982    /**
983     * Where in mLruProcesses that the processes hosting services start.
984     * This is after (lower index) than mLruProcessesActivityStart.
985     */
986    int mLruProcessServiceStart = 0;
987
988    /**
989     * List of processes that should gc as soon as things are idle.
990     */
991    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
992
993    /**
994     * Processes we want to collect PSS data from.
995     */
996    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
997
998    private boolean mBinderTransactionTrackingEnabled = false;
999
1000    /**
1001     * Last time we requested PSS data of all processes.
1002     */
1003    long mLastFullPssTime = SystemClock.uptimeMillis();
1004
1005    /**
1006     * If set, the next time we collect PSS data we should do a full collection
1007     * with data from native processes and the kernel.
1008     */
1009    boolean mFullPssPending = false;
1010
1011    /**
1012     * This is the process holding what we currently consider to be
1013     * the "home" activity.
1014     */
1015    ProcessRecord mHomeProcess;
1016
1017    /**
1018     * This is the process holding the activity the user last visited that
1019     * is in a different process from the one they are currently in.
1020     */
1021    ProcessRecord mPreviousProcess;
1022
1023    /**
1024     * The time at which the previous process was last visible.
1025     */
1026    long mPreviousProcessVisibleTime;
1027
1028    /**
1029     * Track all uids that have actively running processes.
1030     */
1031    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1032
1033    /**
1034     * This is for verifying the UID report flow.
1035     */
1036    static final boolean VALIDATE_UID_STATES = true;
1037    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1038
1039    /**
1040     * Packages that the user has asked to have run in screen size
1041     * compatibility mode instead of filling the screen.
1042     */
1043    final CompatModePackages mCompatModePackages;
1044
1045    /**
1046     * Set of IntentSenderRecord objects that are currently active.
1047     */
1048    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1049            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1050
1051    /**
1052     * Fingerprints (hashCode()) of stack traces that we've
1053     * already logged DropBox entries for.  Guarded by itself.  If
1054     * something (rogue user app) forces this over
1055     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1056     */
1057    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1058    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1059
1060    /**
1061     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1062     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1063     */
1064    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1065
1066    /**
1067     * Resolver for broadcast intents to registered receivers.
1068     * Holds BroadcastFilter (subclass of IntentFilter).
1069     */
1070    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1071            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1072        @Override
1073        protected boolean allowFilterResult(
1074                BroadcastFilter filter, List<BroadcastFilter> dest) {
1075            IBinder target = filter.receiverList.receiver.asBinder();
1076            for (int i = dest.size() - 1; i >= 0; i--) {
1077                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1078                    return false;
1079                }
1080            }
1081            return true;
1082        }
1083
1084        @Override
1085        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1086            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1087                    || userId == filter.owningUserId) {
1088                return super.newResult(filter, match, userId);
1089            }
1090            return null;
1091        }
1092
1093        @Override
1094        protected BroadcastFilter[] newArray(int size) {
1095            return new BroadcastFilter[size];
1096        }
1097
1098        @Override
1099        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1100            return packageName.equals(filter.packageName);
1101        }
1102    };
1103
1104    /**
1105     * State of all active sticky broadcasts per user.  Keys are the action of the
1106     * sticky Intent, values are an ArrayList of all broadcasted intents with
1107     * that action (which should usually be one).  The SparseArray is keyed
1108     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1109     * for stickies that are sent to all users.
1110     */
1111    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1112            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1113
1114    final ActiveServices mServices;
1115
1116    final static class Association {
1117        final int mSourceUid;
1118        final String mSourceProcess;
1119        final int mTargetUid;
1120        final ComponentName mTargetComponent;
1121        final String mTargetProcess;
1122
1123        int mCount;
1124        long mTime;
1125
1126        int mNesting;
1127        long mStartTime;
1128
1129        // states of the source process when the bind occurred.
1130        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1131        long mLastStateUptime;
1132        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1133                - ActivityManager.MIN_PROCESS_STATE+1];
1134
1135        Association(int sourceUid, String sourceProcess, int targetUid,
1136                ComponentName targetComponent, String targetProcess) {
1137            mSourceUid = sourceUid;
1138            mSourceProcess = sourceProcess;
1139            mTargetUid = targetUid;
1140            mTargetComponent = targetComponent;
1141            mTargetProcess = targetProcess;
1142        }
1143    }
1144
1145    /**
1146     * When service association tracking is enabled, this is all of the associations we
1147     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1148     * -> association data.
1149     */
1150    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1151            mAssociations = new SparseArray<>();
1152    boolean mTrackingAssociations;
1153
1154    /**
1155     * Backup/restore process management
1156     */
1157    String mBackupAppName = null;
1158    BackupRecord mBackupTarget = null;
1159
1160    final ProviderMap mProviderMap;
1161
1162    /**
1163     * List of content providers who have clients waiting for them.  The
1164     * application is currently being launched and the provider will be
1165     * removed from this list once it is published.
1166     */
1167    final ArrayList<ContentProviderRecord> mLaunchingProviders
1168            = new ArrayList<ContentProviderRecord>();
1169
1170    /**
1171     * File storing persisted {@link #mGrantedUriPermissions}.
1172     */
1173    private final AtomicFile mGrantFile;
1174
1175    /** XML constants used in {@link #mGrantFile} */
1176    private static final String TAG_URI_GRANTS = "uri-grants";
1177    private static final String TAG_URI_GRANT = "uri-grant";
1178    private static final String ATTR_USER_HANDLE = "userHandle";
1179    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1180    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1181    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1182    private static final String ATTR_TARGET_PKG = "targetPkg";
1183    private static final String ATTR_URI = "uri";
1184    private static final String ATTR_MODE_FLAGS = "modeFlags";
1185    private static final String ATTR_CREATED_TIME = "createdTime";
1186    private static final String ATTR_PREFIX = "prefix";
1187
1188    /**
1189     * Global set of specific {@link Uri} permissions that have been granted.
1190     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1191     * to {@link UriPermission#uri} to {@link UriPermission}.
1192     */
1193    @GuardedBy("this")
1194    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1195            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1196
1197    public static class GrantUri {
1198        public final int sourceUserId;
1199        public final Uri uri;
1200        public boolean prefix;
1201
1202        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1203            this.sourceUserId = sourceUserId;
1204            this.uri = uri;
1205            this.prefix = prefix;
1206        }
1207
1208        @Override
1209        public int hashCode() {
1210            int hashCode = 1;
1211            hashCode = 31 * hashCode + sourceUserId;
1212            hashCode = 31 * hashCode + uri.hashCode();
1213            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1214            return hashCode;
1215        }
1216
1217        @Override
1218        public boolean equals(Object o) {
1219            if (o instanceof GrantUri) {
1220                GrantUri other = (GrantUri) o;
1221                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1222                        && prefix == other.prefix;
1223            }
1224            return false;
1225        }
1226
1227        @Override
1228        public String toString() {
1229            String result = uri.toString() + " [user " + sourceUserId + "]";
1230            if (prefix) result += " [prefix]";
1231            return result;
1232        }
1233
1234        public String toSafeString() {
1235            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1236            if (prefix) result += " [prefix]";
1237            return result;
1238        }
1239
1240        public void writeToProto(ProtoOutputStream proto, long fieldId) {
1241            long token = proto.start(fieldId);
1242            proto.write(GrantUriProto.URI, uri.toString());
1243            proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
1244            proto.end(token);
1245        }
1246
1247        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1248            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1249                    ContentProvider.getUriWithoutUserId(uri), false);
1250        }
1251    }
1252
1253    CoreSettingsObserver mCoreSettingsObserver;
1254
1255    FontScaleSettingObserver mFontScaleSettingObserver;
1256
1257    private final class FontScaleSettingObserver extends ContentObserver {
1258        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1259
1260        public FontScaleSettingObserver() {
1261            super(mHandler);
1262            ContentResolver resolver = mContext.getContentResolver();
1263            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1264        }
1265
1266        @Override
1267        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1268            if (mFontScaleUri.equals(uri)) {
1269                updateFontScaleIfNeeded(userId);
1270            }
1271        }
1272    }
1273
1274    DevelopmentSettingsObserver mDevelopmentSettingsObserver;
1275
1276    private final class DevelopmentSettingsObserver extends ContentObserver {
1277        private final Uri mUri = Settings.Global
1278                .getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
1279
1280        private final ComponentName mBugreportStorageProvider = new ComponentName(
1281                "com.android.shell", "com.android.shell.BugreportStorageProvider");
1282
1283        public DevelopmentSettingsObserver() {
1284            super(mHandler);
1285            mContext.getContentResolver().registerContentObserver(mUri, false, this,
1286                    UserHandle.USER_ALL);
1287            // Always kick once to ensure that we match current state
1288            onChange();
1289        }
1290
1291        @Override
1292        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1293            if (mUri.equals(uri)) {
1294                onChange();
1295            }
1296        }
1297
1298        public void onChange() {
1299            final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
1300                    Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, Build.IS_ENG ? 1 : 0) != 0;
1301            mContext.getPackageManager().setComponentEnabledSetting(mBugreportStorageProvider,
1302                    enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1303                            : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
1304                    0);
1305        }
1306    }
1307
1308    /**
1309     * Thread-local storage used to carry caller permissions over through
1310     * indirect content-provider access.
1311     */
1312    private class Identity {
1313        public final IBinder token;
1314        public final int pid;
1315        public final int uid;
1316
1317        Identity(IBinder _token, int _pid, int _uid) {
1318            token = _token;
1319            pid = _pid;
1320            uid = _uid;
1321        }
1322    }
1323
1324    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1325
1326    /**
1327     * All information we have collected about the runtime performance of
1328     * any user id that can impact battery performance.
1329     */
1330    final BatteryStatsService mBatteryStatsService;
1331
1332    /**
1333     * Information about component usage
1334     */
1335    UsageStatsManagerInternal mUsageStatsService;
1336
1337    /**
1338     * Access to DeviceIdleController service.
1339     */
1340    DeviceIdleController.LocalService mLocalDeviceIdleController;
1341
1342    /**
1343     * Set of app ids that are whitelisted for device idle and thus background check.
1344     */
1345    int[] mDeviceIdleWhitelist = new int[0];
1346
1347    /**
1348     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1349     */
1350    int[] mDeviceIdleTempWhitelist = new int[0];
1351
1352    static final class PendingTempWhitelist {
1353        final int targetUid;
1354        final long duration;
1355        final String tag;
1356
1357        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1358            targetUid = _targetUid;
1359            duration = _duration;
1360            tag = _tag;
1361        }
1362
1363        void writeToProto(ProtoOutputStream proto, long fieldId) {
1364            final long token = proto.start(fieldId);
1365            proto.write(ProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
1366            proto.write(ProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
1367            proto.write(ProcessesProto.PendingTempWhitelist.TAG, tag);
1368            proto.end(token);
1369        }
1370    }
1371
1372    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1373
1374    /**
1375     * Information about and control over application operations
1376     */
1377    final AppOpsService mAppOpsService;
1378
1379    /** Current sequencing integer of the configuration, for skipping old configurations. */
1380    private int mConfigurationSeq;
1381
1382    /**
1383     * Temp object used when global and/or display override configuration is updated. It is also
1384     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1385     * anyone...
1386     */
1387    private Configuration mTempConfig = new Configuration();
1388
1389    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1390            new UpdateConfigurationResult();
1391    private static final class UpdateConfigurationResult {
1392        // Configuration changes that were updated.
1393        int changes;
1394        // If the activity was relaunched to match the new configuration.
1395        boolean activityRelaunched;
1396
1397        void reset() {
1398            changes = 0;
1399            activityRelaunched = false;
1400        }
1401    }
1402
1403    boolean mSuppressResizeConfigChanges;
1404
1405    /**
1406     * Hardware-reported OpenGLES version.
1407     */
1408    final int GL_ES_VERSION;
1409
1410    /**
1411     * List of initialization arguments to pass to all processes when binding applications to them.
1412     * For example, references to the commonly used services.
1413     */
1414    HashMap<String, IBinder> mAppBindArgs;
1415    HashMap<String, IBinder> mIsolatedAppBindArgs;
1416
1417    /**
1418     * Temporary to avoid allocations.  Protected by main lock.
1419     */
1420    final StringBuilder mStringBuilder = new StringBuilder(256);
1421
1422    /**
1423     * Used to control how we initialize the service.
1424     */
1425    ComponentName mTopComponent;
1426    String mTopAction = Intent.ACTION_MAIN;
1427    String mTopData;
1428
1429    volatile boolean mProcessesReady = false;
1430    volatile boolean mSystemReady = false;
1431    volatile boolean mOnBattery = false;
1432    volatile int mFactoryTest;
1433
1434    @GuardedBy("this") boolean mBooting = false;
1435    @GuardedBy("this") boolean mCallFinishBooting = false;
1436    @GuardedBy("this") boolean mBootAnimationComplete = false;
1437    @GuardedBy("this") boolean mLaunchWarningShown = false;
1438    private @GuardedBy("this") boolean mCheckedForSetup = false;
1439
1440    final Context mContext;
1441
1442    /**
1443     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1444     * change at runtime. Use mContext for non-UI purposes.
1445     */
1446    final Context mUiContext;
1447
1448    /**
1449     * The time at which we will allow normal application switches again,
1450     * after a call to {@link #stopAppSwitches()}.
1451     */
1452    long mAppSwitchesAllowedTime;
1453
1454    /**
1455     * This is set to true after the first switch after mAppSwitchesAllowedTime
1456     * is set; any switches after that will clear the time.
1457     */
1458    boolean mDidAppSwitch;
1459
1460    /**
1461     * Last time (in uptime) at which we checked for power usage.
1462     */
1463    long mLastPowerCheckUptime;
1464
1465    /**
1466     * Set while we are wanting to sleep, to prevent any
1467     * activities from being started/resumed.
1468     *
1469     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1470     *
1471     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1472     * while in the sleep state until there is a pending transition out of sleep, in which case
1473     * mSleeping is set to false, and remains false while awake.
1474     *
1475     * Whether mSleeping can quickly toggled between true/false without the device actually
1476     * display changing states is undefined.
1477     */
1478    private boolean mSleeping = false;
1479
1480    /**
1481     * The process state used for processes that are running the top activities.
1482     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1483     */
1484    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1485
1486    /**
1487     * Set while we are running a voice interaction.  This overrides
1488     * sleeping while it is active.
1489     */
1490    IVoiceInteractionSession mRunningVoice;
1491
1492    /**
1493     * For some direct access we need to power manager.
1494     */
1495    PowerManagerInternal mLocalPowerManager;
1496
1497    /**
1498     * We want to hold a wake lock while running a voice interaction session, since
1499     * this may happen with the screen off and we need to keep the CPU running to
1500     * be able to continue to interact with the user.
1501     */
1502    PowerManager.WakeLock mVoiceWakeLock;
1503
1504    /**
1505     * State of external calls telling us if the device is awake or asleep.
1506     */
1507    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1508
1509    /**
1510     * Set if we are shutting down the system, similar to sleeping.
1511     */
1512    boolean mShuttingDown = false;
1513
1514    /**
1515     * Current sequence id for oom_adj computation traversal.
1516     */
1517    int mAdjSeq = 0;
1518
1519    /**
1520     * Current sequence id for process LRU updating.
1521     */
1522    int mLruSeq = 0;
1523
1524    /**
1525     * Keep track of the non-cached/empty process we last found, to help
1526     * determine how to distribute cached/empty processes next time.
1527     */
1528    int mNumNonCachedProcs = 0;
1529
1530    /**
1531     * Keep track of the number of cached hidden procs, to balance oom adj
1532     * distribution between those and empty procs.
1533     */
1534    int mNumCachedHiddenProcs = 0;
1535
1536    /**
1537     * Keep track of the number of service processes we last found, to
1538     * determine on the next iteration which should be B services.
1539     */
1540    int mNumServiceProcs = 0;
1541    int mNewNumAServiceProcs = 0;
1542    int mNewNumServiceProcs = 0;
1543
1544    /**
1545     * Allow the current computed overall memory level of the system to go down?
1546     * This is set to false when we are killing processes for reasons other than
1547     * memory management, so that the now smaller process list will not be taken as
1548     * an indication that memory is tighter.
1549     */
1550    boolean mAllowLowerMemLevel = false;
1551
1552    /**
1553     * The last computed memory level, for holding when we are in a state that
1554     * processes are going away for other reasons.
1555     */
1556    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1557
1558    /**
1559     * The last total number of process we have, to determine if changes actually look
1560     * like a shrinking number of process due to lower RAM.
1561     */
1562    int mLastNumProcesses;
1563
1564    /**
1565     * The uptime of the last time we performed idle maintenance.
1566     */
1567    long mLastIdleTime = SystemClock.uptimeMillis();
1568
1569    /**
1570     * Total time spent with RAM that has been added in the past since the last idle time.
1571     */
1572    long mLowRamTimeSinceLastIdle = 0;
1573
1574    /**
1575     * If RAM is currently low, when that horrible situation started.
1576     */
1577    long mLowRamStartTime = 0;
1578
1579    /**
1580     * For reporting to battery stats the current top application.
1581     */
1582    private String mCurResumedPackage = null;
1583    private int mCurResumedUid = -1;
1584
1585    /**
1586     * For reporting to battery stats the apps currently running foreground
1587     * service.  The ProcessMap is package/uid tuples; each of these contain
1588     * an array of the currently foreground processes.
1589     */
1590    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1591            = new ProcessMap<ArrayList<ProcessRecord>>();
1592
1593    /**
1594     * Set if the systemServer made a call to enterSafeMode.
1595     */
1596    boolean mSafeMode;
1597
1598    /**
1599     * If true, we are running under a test environment so will sample PSS from processes
1600     * much more rapidly to try to collect better data when the tests are rapidly
1601     * running through apps.
1602     */
1603    boolean mTestPssMode = false;
1604
1605    String mDebugApp = null;
1606    boolean mWaitForDebugger = false;
1607    boolean mDebugTransient = false;
1608    String mOrigDebugApp = null;
1609    boolean mOrigWaitForDebugger = false;
1610    boolean mAlwaysFinishActivities = false;
1611    boolean mForceResizableActivities;
1612    /**
1613     * Flag that indicates if multi-window is enabled.
1614     *
1615     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1616     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1617     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1618     * At least one of the forms of multi-window must be enabled in order for this flag to be
1619     * initialized to 'true'.
1620     *
1621     * @see #mSupportsSplitScreenMultiWindow
1622     * @see #mSupportsFreeformWindowManagement
1623     * @see #mSupportsPictureInPicture
1624     * @see #mSupportsMultiDisplay
1625     */
1626    boolean mSupportsMultiWindow;
1627    boolean mSupportsSplitScreenMultiWindow;
1628    boolean mSupportsFreeformWindowManagement;
1629    boolean mSupportsPictureInPicture;
1630    boolean mSupportsMultiDisplay;
1631    boolean mSupportsLeanbackOnly;
1632    IActivityController mController = null;
1633    boolean mControllerIsAMonkey = false;
1634    String mProfileApp = null;
1635    ProcessRecord mProfileProc = null;
1636    ProfilerInfo mProfilerInfo = null;
1637
1638    /**
1639     * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
1640     * is not null, this map is checked and the mapped agent installed during bind-time. Note:
1641     * A non-null agent in mProfileInfo overrides this.
1642     */
1643    private @Nullable Map<String, String> mAppAgentMap = null;
1644
1645    int mProfileType = 0;
1646    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1647    String mMemWatchDumpProcName;
1648    String mMemWatchDumpFile;
1649    int mMemWatchDumpPid;
1650    int mMemWatchDumpUid;
1651    String mTrackAllocationApp = null;
1652    String mNativeDebuggingApp = null;
1653
1654    final long[] mTmpLong = new long[3];
1655
1656    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1657
1658    /**
1659     * A global counter for generating sequence numbers.
1660     * This value will be used when incrementing sequence numbers in individual uidRecords.
1661     *
1662     * Having a global counter ensures that seq numbers are monotonically increasing for a
1663     * particular uid even when the uidRecord is re-created.
1664     */
1665    @GuardedBy("this")
1666    @VisibleForTesting
1667    long mProcStateSeqCounter = 0;
1668
1669    /**
1670     * A global counter for generating sequence numbers to uniquely identify pending process starts.
1671     */
1672    @GuardedBy("this")
1673    private long mProcStartSeqCounter = 0;
1674
1675    /**
1676     * Contains {@link ProcessRecord} objects for pending process starts.
1677     *
1678     * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1679     */
1680    @GuardedBy("this")
1681    private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1682
1683    private final Injector mInjector;
1684
1685    static final class ProcessChangeItem {
1686        static final int CHANGE_ACTIVITIES = 1<<0;
1687        int changes;
1688        int uid;
1689        int pid;
1690        int processState;
1691        boolean foregroundActivities;
1692    }
1693
1694    static final class UidObserverRegistration {
1695        final int uid;
1696        final String pkg;
1697        final int which;
1698        final int cutpoint;
1699
1700        final SparseIntArray lastProcStates;
1701
1702        // Please keep the enum lists in sync
1703        private static int[] ORIG_ENUMS = new int[]{
1704                ActivityManager.UID_OBSERVER_IDLE,
1705                ActivityManager.UID_OBSERVER_ACTIVE,
1706                ActivityManager.UID_OBSERVER_GONE,
1707                ActivityManager.UID_OBSERVER_PROCSTATE,
1708        };
1709        private static int[] PROTO_ENUMS = new int[]{
1710                ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
1711                ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
1712                ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
1713                ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
1714        };
1715
1716        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1717            uid = _uid;
1718            pkg = _pkg;
1719            which = _which;
1720            cutpoint = _cutpoint;
1721            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1722                lastProcStates = new SparseIntArray();
1723            } else {
1724                lastProcStates = null;
1725            }
1726        }
1727
1728        void writeToProto(ProtoOutputStream proto, long fieldId) {
1729            final long token = proto.start(fieldId);
1730            proto.write(UidObserverRegistrationProto.UID, uid);
1731            proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
1732            ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
1733                    which, ORIG_ENUMS, PROTO_ENUMS);
1734            proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
1735            if (lastProcStates != null) {
1736                final int NI = lastProcStates.size();
1737                for (int i=0; i<NI; i++) {
1738                    final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
1739                    proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
1740                    proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
1741                    proto.end(pToken);
1742                }
1743            }
1744            proto.end(token);
1745        }
1746    }
1747
1748    final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1749
1750    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1751    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1752
1753    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1754    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1755
1756    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1757    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1758
1759    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1760    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1761
1762    OomAdjObserver mCurOomAdjObserver;
1763    int mCurOomAdjUid;
1764
1765    interface OomAdjObserver {
1766        void onOomAdjMessage(String msg);
1767    }
1768
1769    /**
1770     * Runtime CPU use collection thread.  This object's lock is used to
1771     * perform synchronization with the thread (notifying it to run).
1772     */
1773    final Thread mProcessCpuThread;
1774
1775    /**
1776     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1777     * Must acquire this object's lock when accessing it.
1778     * NOTE: this lock will be held while doing long operations (trawling
1779     * through all processes in /proc), so it should never be acquired by
1780     * any critical paths such as when holding the main activity manager lock.
1781     */
1782    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1783            MONITOR_THREAD_CPU_USAGE);
1784    final AtomicLong mLastCpuTime = new AtomicLong(0);
1785    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1786    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1787
1788    long mLastWriteTime = 0;
1789
1790    /**
1791     * Used to retain an update lock when the foreground activity is in
1792     * immersive mode.
1793     */
1794    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1795
1796    /**
1797     * Set to true after the system has finished booting.
1798     */
1799    boolean mBooted = false;
1800
1801    WindowManagerService mWindowManager;
1802    final ActivityThread mSystemThread;
1803
1804    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1805        final ProcessRecord mApp;
1806        final int mPid;
1807        final IApplicationThread mAppThread;
1808
1809        AppDeathRecipient(ProcessRecord app, int pid,
1810                IApplicationThread thread) {
1811            if (DEBUG_ALL) Slog.v(
1812                TAG, "New death recipient " + this
1813                + " for thread " + thread.asBinder());
1814            mApp = app;
1815            mPid = pid;
1816            mAppThread = thread;
1817        }
1818
1819        @Override
1820        public void binderDied() {
1821            if (DEBUG_ALL) Slog.v(
1822                TAG, "Death received in " + this
1823                + " for thread " + mAppThread.asBinder());
1824            synchronized(ActivityManagerService.this) {
1825                appDiedLocked(mApp, mPid, mAppThread, true);
1826            }
1827        }
1828    }
1829
1830    static final int SHOW_ERROR_UI_MSG = 1;
1831    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1832    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1833    static final int UPDATE_CONFIGURATION_MSG = 4;
1834    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1835    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1836    static final int SERVICE_TIMEOUT_MSG = 12;
1837    static final int UPDATE_TIME_ZONE = 13;
1838    static final int SHOW_UID_ERROR_UI_MSG = 14;
1839    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1840    static final int PROC_START_TIMEOUT_MSG = 20;
1841    static final int KILL_APPLICATION_MSG = 22;
1842    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1843    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1844    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1845    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1846    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1847    static final int CLEAR_DNS_CACHE_MSG = 28;
1848    static final int UPDATE_HTTP_PROXY_MSG = 29;
1849    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1850    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1851    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1852    static final int REPORT_MEM_USAGE_MSG = 33;
1853    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1854    static final int PERSIST_URI_GRANTS_MSG = 38;
1855    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1856    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1857    static final int FINISH_BOOTING_MSG = 45;
1858    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1859    static final int DISMISS_DIALOG_UI_MSG = 48;
1860    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1861    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1862    static final int DELETE_DUMPHEAP_MSG = 51;
1863    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1864    static final int REPORT_TIME_TRACKER_MSG = 54;
1865    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1866    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1867    static final int IDLE_UIDS_MSG = 58;
1868    static final int LOG_STACK_STATE = 60;
1869    static final int VR_MODE_CHANGE_MSG = 61;
1870    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1871    static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
1872    static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
1873    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1874    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1875    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1876    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1877    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1878
1879    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1880    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1881    static final int FIRST_COMPAT_MODE_MSG = 300;
1882    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1883
1884    static ServiceThread sKillThread = null;
1885    static KillHandler sKillHandler = null;
1886
1887    CompatModeDialog mCompatModeDialog;
1888    long mLastMemUsageReportTime = 0;
1889
1890    /**
1891     * Flag whether the current user is a "monkey", i.e. whether
1892     * the UI is driven by a UI automation tool.
1893     */
1894    private boolean mUserIsMonkey;
1895
1896    /** The dimensions of the thumbnails in the Recents UI. */
1897    int mThumbnailWidth;
1898    int mThumbnailHeight;
1899    float mFullscreenThumbnailScale;
1900
1901    final ServiceThread mHandlerThread;
1902    final MainHandler mHandler;
1903    final Handler mUiHandler;
1904    final ServiceThread mProcStartHandlerThread;
1905    final Handler mProcStartHandler;
1906
1907    final ActivityManagerConstants mConstants;
1908
1909    // Encapsulates the global setting "hidden_api_blacklist_exemptions"
1910    final HiddenApiBlacklist mHiddenApiBlacklist;
1911
1912    PackageManagerInternal mPackageManagerInt;
1913
1914    // VoiceInteraction session ID that changes for each new request except when
1915    // being called for multiwindow assist in a single session.
1916    private int mViSessionId = 1000;
1917
1918    final boolean mPermissionReviewRequired;
1919
1920    /**
1921     * Whether to force background check on all apps (for battery saver) or not.
1922     */
1923    boolean mForceBackgroundCheck;
1924
1925    private static String sTheRealBuildSerial = Build.UNKNOWN;
1926
1927    /**
1928     * Current global configuration information. Contains general settings for the entire system,
1929     * also corresponds to the merged configuration of the default display.
1930     */
1931    Configuration getGlobalConfiguration() {
1932        return mStackSupervisor.getConfiguration();
1933    }
1934
1935    final class KillHandler extends Handler {
1936        static final int KILL_PROCESS_GROUP_MSG = 4000;
1937
1938        public KillHandler(Looper looper) {
1939            super(looper, null, true);
1940        }
1941
1942        @Override
1943        public void handleMessage(Message msg) {
1944            switch (msg.what) {
1945                case KILL_PROCESS_GROUP_MSG:
1946                {
1947                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1948                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1949                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1950                }
1951                break;
1952
1953                default:
1954                    super.handleMessage(msg);
1955            }
1956        }
1957    }
1958
1959    final class UiHandler extends Handler {
1960        public UiHandler() {
1961            super(com.android.server.UiThread.get().getLooper(), null, true);
1962        }
1963
1964        @Override
1965        public void handleMessage(Message msg) {
1966            switch (msg.what) {
1967            case SHOW_ERROR_UI_MSG: {
1968                mAppErrors.handleShowAppErrorUi(msg);
1969                ensureBootCompleted();
1970            } break;
1971            case SHOW_NOT_RESPONDING_UI_MSG: {
1972                mAppErrors.handleShowAnrUi(msg);
1973                ensureBootCompleted();
1974            } break;
1975            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1976                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1977                synchronized (ActivityManagerService.this) {
1978                    ProcessRecord proc = (ProcessRecord) data.get("app");
1979                    if (proc == null) {
1980                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1981                        break;
1982                    }
1983                    if (proc.crashDialog != null) {
1984                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1985                        return;
1986                    }
1987                    AppErrorResult res = (AppErrorResult) data.get("result");
1988                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1989                        Dialog d = new StrictModeViolationDialog(mUiContext,
1990                                ActivityManagerService.this, res, proc);
1991                        d.show();
1992                        proc.crashDialog = d;
1993                    } else {
1994                        // The device is asleep, so just pretend that the user
1995                        // saw a crash dialog and hit "force quit".
1996                        res.set(0);
1997                    }
1998                }
1999                ensureBootCompleted();
2000            } break;
2001            case SHOW_FACTORY_ERROR_UI_MSG: {
2002                Dialog d = new FactoryErrorDialog(
2003                        mUiContext, msg.getData().getCharSequence("msg"));
2004                d.show();
2005                ensureBootCompleted();
2006            } break;
2007            case WAIT_FOR_DEBUGGER_UI_MSG: {
2008                synchronized (ActivityManagerService.this) {
2009                    ProcessRecord app = (ProcessRecord)msg.obj;
2010                    if (msg.arg1 != 0) {
2011                        if (!app.waitedForDebugger) {
2012                            Dialog d = new AppWaitingForDebuggerDialog(
2013                                    ActivityManagerService.this,
2014                                    mUiContext, app);
2015                            app.waitDialog = d;
2016                            app.waitedForDebugger = true;
2017                            d.show();
2018                        }
2019                    } else {
2020                        if (app.waitDialog != null) {
2021                            app.waitDialog.dismiss();
2022                            app.waitDialog = null;
2023                        }
2024                    }
2025                }
2026            } break;
2027            case SHOW_UID_ERROR_UI_MSG: {
2028                if (mShowDialogs) {
2029                    AlertDialog d = new BaseErrorDialog(mUiContext);
2030                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2031                    d.setCancelable(false);
2032                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2033                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
2034                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2035                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2036                    d.show();
2037                }
2038            } break;
2039            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
2040                if (mShowDialogs) {
2041                    AlertDialog d = new BaseErrorDialog(mUiContext);
2042                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2043                    d.setCancelable(false);
2044                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2045                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
2046                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2047                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2048                    d.show();
2049                }
2050            } break;
2051            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
2052                synchronized (ActivityManagerService.this) {
2053                    ActivityRecord ar = (ActivityRecord) msg.obj;
2054                    if (mCompatModeDialog != null) {
2055                        if (mCompatModeDialog.mAppInfo.packageName.equals(
2056                                ar.info.applicationInfo.packageName)) {
2057                            return;
2058                        }
2059                        mCompatModeDialog.dismiss();
2060                        mCompatModeDialog = null;
2061                    }
2062                    if (ar != null && false) {
2063                        if (mCompatModePackages.getPackageAskCompatModeLocked(
2064                                ar.packageName)) {
2065                            int mode = mCompatModePackages.computeCompatModeLocked(
2066                                    ar.info.applicationInfo);
2067                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
2068                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
2069                                mCompatModeDialog = new CompatModeDialog(
2070                                        ActivityManagerService.this, mUiContext,
2071                                        ar.info.applicationInfo);
2072                                mCompatModeDialog.show();
2073                            }
2074                        }
2075                    }
2076                }
2077                break;
2078            }
2079            case DISMISS_DIALOG_UI_MSG: {
2080                final Dialog d = (Dialog) msg.obj;
2081                d.dismiss();
2082                break;
2083            }
2084            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
2085                dispatchProcessesChanged();
2086                break;
2087            }
2088            case DISPATCH_PROCESS_DIED_UI_MSG: {
2089                final int pid = msg.arg1;
2090                final int uid = msg.arg2;
2091                dispatchProcessDied(pid, uid);
2092                break;
2093            }
2094            case DISPATCH_UIDS_CHANGED_UI_MSG: {
2095                dispatchUidsChanged();
2096            } break;
2097            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
2098                dispatchOomAdjObserver((String)msg.obj);
2099            } break;
2100            case PUSH_TEMP_WHITELIST_UI_MSG: {
2101                pushTempWhitelist();
2102            } break;
2103            }
2104        }
2105    }
2106
2107    final class MainHandler extends Handler {
2108        public MainHandler(Looper looper) {
2109            super(looper, null, true);
2110        }
2111
2112        @Override
2113        public void handleMessage(Message msg) {
2114            switch (msg.what) {
2115            case UPDATE_CONFIGURATION_MSG: {
2116                final ContentResolver resolver = mContext.getContentResolver();
2117                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
2118                        msg.arg1);
2119            } break;
2120            case GC_BACKGROUND_PROCESSES_MSG: {
2121                synchronized (ActivityManagerService.this) {
2122                    performAppGcsIfAppropriateLocked();
2123                }
2124            } break;
2125            case SERVICE_TIMEOUT_MSG: {
2126                mServices.serviceTimeout((ProcessRecord)msg.obj);
2127            } break;
2128            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
2129                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
2130            } break;
2131            case SERVICE_FOREGROUND_CRASH_MSG: {
2132                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
2133            } break;
2134            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
2135                RemoteCallbackList<IResultReceiver> callbacks
2136                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
2137                int N = callbacks.beginBroadcast();
2138                for (int i = 0; i < N; i++) {
2139                    try {
2140                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2141                    } catch (RemoteException e) {
2142                    }
2143                }
2144                callbacks.finishBroadcast();
2145            } break;
2146            case UPDATE_TIME_ZONE: {
2147                synchronized (ActivityManagerService.this) {
2148                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2149                        ProcessRecord r = mLruProcesses.get(i);
2150                        if (r.thread != null) {
2151                            try {
2152                                r.thread.updateTimeZone();
2153                            } catch (RemoteException ex) {
2154                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2155                            }
2156                        }
2157                    }
2158                }
2159            } break;
2160            case CLEAR_DNS_CACHE_MSG: {
2161                synchronized (ActivityManagerService.this) {
2162                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2163                        ProcessRecord r = mLruProcesses.get(i);
2164                        if (r.thread != null) {
2165                            try {
2166                                r.thread.clearDnsCache();
2167                            } catch (RemoteException ex) {
2168                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2169                            }
2170                        }
2171                    }
2172                }
2173            } break;
2174            case UPDATE_HTTP_PROXY_MSG: {
2175                ProxyInfo proxy = (ProxyInfo)msg.obj;
2176                String host = "";
2177                String port = "";
2178                String exclList = "";
2179                Uri pacFileUrl = Uri.EMPTY;
2180                if (proxy != null) {
2181                    host = proxy.getHost();
2182                    port = Integer.toString(proxy.getPort());
2183                    exclList = proxy.getExclusionListAsString();
2184                    pacFileUrl = proxy.getPacFileUrl();
2185                }
2186                synchronized (ActivityManagerService.this) {
2187                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2188                        ProcessRecord r = mLruProcesses.get(i);
2189                        // Don't dispatch to isolated processes as they can't access
2190                        // ConnectivityManager and don't have network privileges anyway.
2191                        if (r.thread != null && !r.isolated) {
2192                            try {
2193                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2194                            } catch (RemoteException ex) {
2195                                Slog.w(TAG, "Failed to update http proxy for: " +
2196                                        r.info.processName);
2197                            }
2198                        }
2199                    }
2200                }
2201            } break;
2202            case PROC_START_TIMEOUT_MSG: {
2203                ProcessRecord app = (ProcessRecord)msg.obj;
2204                synchronized (ActivityManagerService.this) {
2205                    processStartTimedOutLocked(app);
2206                }
2207            } break;
2208            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2209                ProcessRecord app = (ProcessRecord)msg.obj;
2210                synchronized (ActivityManagerService.this) {
2211                    processContentProviderPublishTimedOutLocked(app);
2212                }
2213            } break;
2214            case KILL_APPLICATION_MSG: {
2215                synchronized (ActivityManagerService.this) {
2216                    final int appId = msg.arg1;
2217                    final int userId = msg.arg2;
2218                    Bundle bundle = (Bundle)msg.obj;
2219                    String pkg = bundle.getString("pkg");
2220                    String reason = bundle.getString("reason");
2221                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2222                            false, userId, reason);
2223                }
2224            } break;
2225            case FINALIZE_PENDING_INTENT_MSG: {
2226                ((PendingIntentRecord)msg.obj).completeFinalize();
2227            } break;
2228            case POST_HEAVY_NOTIFICATION_MSG: {
2229                INotificationManager inm = NotificationManager.getService();
2230                if (inm == null) {
2231                    return;
2232                }
2233
2234                ActivityRecord root = (ActivityRecord)msg.obj;
2235                ProcessRecord process = root.app;
2236                if (process == null) {
2237                    return;
2238                }
2239
2240                try {
2241                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2242                    String text = mContext.getString(R.string.heavy_weight_notification,
2243                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2244                    Notification notification =
2245                            new Notification.Builder(context,
2246                                    SystemNotificationChannels.HEAVY_WEIGHT_APP)
2247                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2248                            .setWhen(0)
2249                            .setOngoing(true)
2250                            .setTicker(text)
2251                            .setColor(mContext.getColor(
2252                                    com.android.internal.R.color.system_notification_accent_color))
2253                            .setContentTitle(text)
2254                            .setContentText(
2255                                    mContext.getText(R.string.heavy_weight_notification_detail))
2256                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2257                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2258                                    new UserHandle(root.userId)))
2259                            .build();
2260                    try {
2261                        inm.enqueueNotificationWithTag("android", "android", null,
2262                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2263                                notification, root.userId);
2264                    } catch (RuntimeException e) {
2265                        Slog.w(ActivityManagerService.TAG,
2266                                "Error showing notification for heavy-weight app", e);
2267                    } catch (RemoteException e) {
2268                    }
2269                } catch (NameNotFoundException e) {
2270                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2271                }
2272            } break;
2273            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2274                INotificationManager inm = NotificationManager.getService();
2275                if (inm == null) {
2276                    return;
2277                }
2278                try {
2279                    inm.cancelNotificationWithTag("android", null,
2280                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2281                } catch (RuntimeException e) {
2282                    Slog.w(ActivityManagerService.TAG,
2283                            "Error canceling notification for service", e);
2284                } catch (RemoteException e) {
2285                }
2286            } break;
2287            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2288                synchronized (ActivityManagerService.this) {
2289                    checkExcessivePowerUsageLocked();
2290                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2291                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2292                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2293                }
2294            } break;
2295            case REPORT_MEM_USAGE_MSG: {
2296                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2297                Thread thread = new Thread() {
2298                    @Override public void run() {
2299                        reportMemUsage(memInfos);
2300                    }
2301                };
2302                thread.start();
2303                break;
2304            }
2305            case IMMERSIVE_MODE_LOCK_MSG: {
2306                final boolean nextState = (msg.arg1 != 0);
2307                if (mUpdateLock.isHeld() != nextState) {
2308                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2309                            "Applying new update lock state '" + nextState
2310                            + "' for " + (ActivityRecord)msg.obj);
2311                    if (nextState) {
2312                        mUpdateLock.acquire();
2313                    } else {
2314                        mUpdateLock.release();
2315                    }
2316                }
2317                break;
2318            }
2319            case PERSIST_URI_GRANTS_MSG: {
2320                writeGrantedUriPermissions();
2321                break;
2322            }
2323            case UPDATE_TIME_PREFERENCE_MSG: {
2324                // The user's time format preference might have changed.
2325                // For convenience we re-use the Intent extra values.
2326                synchronized (ActivityManagerService.this) {
2327                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2328                        ProcessRecord r = mLruProcesses.get(i);
2329                        if (r.thread != null) {
2330                            try {
2331                                r.thread.updateTimePrefs(msg.arg1);
2332                            } catch (RemoteException ex) {
2333                                Slog.w(TAG, "Failed to update preferences for: "
2334                                        + r.info.processName);
2335                            }
2336                        }
2337                    }
2338                }
2339                break;
2340            }
2341            case ENTER_ANIMATION_COMPLETE_MSG: {
2342                synchronized (ActivityManagerService.this) {
2343                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2344                    if (r != null && r.app != null && r.app.thread != null) {
2345                        try {
2346                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2347                        } catch (RemoteException e) {
2348                        }
2349                    }
2350                }
2351                break;
2352            }
2353            case FINISH_BOOTING_MSG: {
2354                if (msg.arg1 != 0) {
2355                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2356                    finishBooting();
2357                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2358                }
2359                if (msg.arg2 != 0) {
2360                    enableScreenAfterBoot();
2361                }
2362                break;
2363            }
2364            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2365                try {
2366                    Locale l = (Locale) msg.obj;
2367                    IBinder service = ServiceManager.getService("mount");
2368                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2369                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2370                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2371                } catch (RemoteException e) {
2372                    Log.e(TAG, "Error storing locale for decryption UI", e);
2373                }
2374                break;
2375            }
2376            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2377                final int uid = msg.arg1;
2378                final byte[] firstPacket = (byte[]) msg.obj;
2379
2380                synchronized (mPidsSelfLocked) {
2381                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2382                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2383                        if (p.uid == uid) {
2384                            try {
2385                                p.thread.notifyCleartextNetwork(firstPacket);
2386                            } catch (RemoteException ignored) {
2387                            }
2388                        }
2389                    }
2390                }
2391                break;
2392            }
2393            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2394                final String procName;
2395                final int uid;
2396                final long memLimit;
2397                final String reportPackage;
2398                synchronized (ActivityManagerService.this) {
2399                    procName = mMemWatchDumpProcName;
2400                    uid = mMemWatchDumpUid;
2401                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2402                    if (val == null) {
2403                        val = mMemWatchProcesses.get(procName, 0);
2404                    }
2405                    if (val != null) {
2406                        memLimit = val.first;
2407                        reportPackage = val.second;
2408                    } else {
2409                        memLimit = 0;
2410                        reportPackage = null;
2411                    }
2412                }
2413                if (procName == null) {
2414                    return;
2415                }
2416
2417                if (DEBUG_PSS) Slog.d(TAG_PSS,
2418                        "Showing dump heap notification from " + procName + "/" + uid);
2419
2420                INotificationManager inm = NotificationManager.getService();
2421                if (inm == null) {
2422                    return;
2423                }
2424
2425                String text = mContext.getString(R.string.dump_heap_notification, procName);
2426
2427
2428                Intent deleteIntent = new Intent();
2429                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2430                Intent intent = new Intent();
2431                intent.setClassName("android", DumpHeapActivity.class.getName());
2432                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2433                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2434                if (reportPackage != null) {
2435                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2436                }
2437                int userId = UserHandle.getUserId(uid);
2438                Notification notification =
2439                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2440                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2441                        .setWhen(0)
2442                        .setOngoing(true)
2443                        .setAutoCancel(true)
2444                        .setTicker(text)
2445                        .setColor(mContext.getColor(
2446                                com.android.internal.R.color.system_notification_accent_color))
2447                        .setContentTitle(text)
2448                        .setContentText(
2449                                mContext.getText(R.string.dump_heap_notification_detail))
2450                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2451                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2452                                new UserHandle(userId)))
2453                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2454                                deleteIntent, 0, UserHandle.SYSTEM))
2455                        .build();
2456
2457                try {
2458                    inm.enqueueNotificationWithTag("android", "android", null,
2459                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2460                            notification, userId);
2461                } catch (RuntimeException e) {
2462                    Slog.w(ActivityManagerService.TAG,
2463                            "Error showing notification for dump heap", e);
2464                } catch (RemoteException e) {
2465                }
2466            } break;
2467            case DELETE_DUMPHEAP_MSG: {
2468                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2469                        null, DumpHeapActivity.JAVA_URI,
2470                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2471                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2472                        UserHandle.myUserId());
2473                synchronized (ActivityManagerService.this) {
2474                    mMemWatchDumpFile = null;
2475                    mMemWatchDumpProcName = null;
2476                    mMemWatchDumpPid = -1;
2477                    mMemWatchDumpUid = -1;
2478                }
2479            } break;
2480            case REPORT_TIME_TRACKER_MSG: {
2481                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2482                tracker.deliverResult(mContext);
2483            } break;
2484            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2485                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2486                try {
2487                    connection.shutdown();
2488                } catch (RemoteException e) {
2489                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2490                }
2491                // Only a UiAutomation can set this flag and now that
2492                // it is finished we make sure it is reset to its default.
2493                mUserIsMonkey = false;
2494            } break;
2495            case IDLE_UIDS_MSG: {
2496                idleUids();
2497            } break;
2498            case VR_MODE_CHANGE_MSG: {
2499                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2500                    return;
2501                }
2502                synchronized (ActivityManagerService.this) {
2503                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2504                    mWindowManager.disableNonVrUi(disableNonVrUi);
2505                    if (disableNonVrUi) {
2506                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2507                        // then remove the pinned stack.
2508                        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2509                    }
2510                }
2511            } break;
2512            case DISPATCH_SCREEN_AWAKE_MSG: {
2513                final boolean isAwake = msg.arg1 != 0;
2514                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2515                    mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2516                }
2517            } break;
2518            case DISPATCH_SCREEN_KEYGUARD_MSG: {
2519                final boolean isShowing = msg.arg1 != 0;
2520                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2521                    mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2522                }
2523            } break;
2524            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2525                synchronized (ActivityManagerService.this) {
2526                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2527                        ProcessRecord r = mLruProcesses.get(i);
2528                        if (r.thread != null) {
2529                            try {
2530                                r.thread.handleTrustStorageUpdate();
2531                            } catch (RemoteException ex) {
2532                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2533                                        r.info.processName);
2534                            }
2535                        }
2536                    }
2537                }
2538            } break;
2539            }
2540        }
2541    };
2542
2543    static final int COLLECT_PSS_BG_MSG = 1;
2544
2545    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2546        @Override
2547        public void handleMessage(Message msg) {
2548            switch (msg.what) {
2549            case COLLECT_PSS_BG_MSG: {
2550                long start = SystemClock.uptimeMillis();
2551                MemInfoReader memInfo = null;
2552                synchronized (ActivityManagerService.this) {
2553                    if (mFullPssPending) {
2554                        mFullPssPending = false;
2555                        memInfo = new MemInfoReader();
2556                    }
2557                }
2558                if (memInfo != null) {
2559                    updateCpuStatsNow();
2560                    long nativeTotalPss = 0;
2561                    final List<ProcessCpuTracker.Stats> stats;
2562                    synchronized (mProcessCpuTracker) {
2563                        stats = mProcessCpuTracker.getStats( (st)-> {
2564                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2565                        });
2566                    }
2567                    final int N = stats.size();
2568                    for (int j = 0; j < N; j++) {
2569                        synchronized (mPidsSelfLocked) {
2570                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2571                                // This is one of our own processes; skip it.
2572                                continue;
2573                            }
2574                        }
2575                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2576                    }
2577                    memInfo.readMemInfo();
2578                    synchronized (ActivityManagerService.this) {
2579                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2580                                + (SystemClock.uptimeMillis()-start) + "ms");
2581                        final long cachedKb = memInfo.getCachedSizeKb();
2582                        final long freeKb = memInfo.getFreeSizeKb();
2583                        final long zramKb = memInfo.getZramTotalSizeKb();
2584                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2585                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2586                                kernelKb*1024, nativeTotalPss*1024);
2587                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2588                                nativeTotalPss);
2589                    }
2590                }
2591
2592                int num = 0;
2593                long[] tmp = new long[3];
2594                do {
2595                    ProcessRecord proc;
2596                    int procState;
2597                    int statType;
2598                    int pid;
2599                    long lastPssTime;
2600                    synchronized (ActivityManagerService.this) {
2601                        if (mPendingPssProcesses.size() <= 0) {
2602                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2603                                    "Collected pss of " + num + " processes in "
2604                                    + (SystemClock.uptimeMillis() - start) + "ms");
2605                            mPendingPssProcesses.clear();
2606                            return;
2607                        }
2608                        proc = mPendingPssProcesses.remove(0);
2609                        procState = proc.pssProcState;
2610                        statType = proc.pssStatType;
2611                        lastPssTime = proc.lastPssTime;
2612                        long now = SystemClock.uptimeMillis();
2613                        if (proc.thread != null && procState == proc.setProcState
2614                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2615                                        < now) {
2616                            pid = proc.pid;
2617                        } else {
2618                            ProcessList.abortNextPssTime(proc.procStateMemTracker);
2619                            if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2620                                    ": still need " +
2621                                    (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE-now) +
2622                                    "ms until safe");
2623                            proc = null;
2624                            pid = 0;
2625                        }
2626                    }
2627                    if (proc != null) {
2628                        long startTime = SystemClock.currentThreadTimeMillis();
2629                        long pss = Debug.getPss(pid, tmp, null);
2630                        long endTime = SystemClock.currentThreadTimeMillis();
2631                        synchronized (ActivityManagerService.this) {
2632                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2633                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2634                                num++;
2635                                ProcessList.commitNextPssTime(proc.procStateMemTracker);
2636                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2],
2637                                        statType, endTime-startTime, SystemClock.uptimeMillis());
2638                            } else {
2639                                ProcessList.abortNextPssTime(proc.procStateMemTracker);
2640                                if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2641                                        ": " + (proc.thread == null ? "NO_THREAD " : "") +
2642                                        (proc.pid != pid ? "PID_CHANGED " : "") +
2643                                        " initState=" + procState + " curState=" +
2644                                        proc.setProcState + " " +
2645                                        (proc.lastPssTime != lastPssTime ? "TIME_CHANGED" : ""));
2646                            }
2647                        }
2648                    }
2649                } while (true);
2650            }
2651            }
2652        }
2653    };
2654
2655    public void setSystemProcess() {
2656        try {
2657            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
2658                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
2659            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2660            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
2661                    DUMP_FLAG_PRIORITY_HIGH);
2662            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2663            ServiceManager.addService("dbinfo", new DbBinder(this));
2664            if (MONITOR_CPU_USAGE) {
2665                ServiceManager.addService("cpuinfo", new CpuBinder(this),
2666                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
2667            }
2668            ServiceManager.addService("permission", new PermissionController(this));
2669            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2670
2671            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2672                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2673            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2674
2675            synchronized (this) {
2676                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2677                app.persistent = true;
2678                app.pid = MY_PID;
2679                app.maxAdj = ProcessList.SYSTEM_ADJ;
2680                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2681                synchronized (mPidsSelfLocked) {
2682                    mPidsSelfLocked.put(app.pid, app);
2683                }
2684                updateLruProcessLocked(app, false, null);
2685                updateOomAdjLocked();
2686            }
2687        } catch (PackageManager.NameNotFoundException e) {
2688            throw new RuntimeException(
2689                    "Unable to find android system package", e);
2690        }
2691    }
2692
2693    public void setWindowManager(WindowManagerService wm) {
2694        synchronized (this) {
2695            mWindowManager = wm;
2696            mStackSupervisor.setWindowManager(wm);
2697            mLockTaskController.setWindowManager(wm);
2698        }
2699    }
2700
2701    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2702        mUsageStatsService = usageStatsManager;
2703    }
2704
2705    public void startObservingNativeCrashes() {
2706        final NativeCrashListener ncl = new NativeCrashListener(this);
2707        ncl.start();
2708    }
2709
2710    public IAppOpsService getAppOpsService() {
2711        return mAppOpsService;
2712    }
2713
2714    static class MemBinder extends Binder {
2715        ActivityManagerService mActivityManagerService;
2716        private final PriorityDump.PriorityDumper mPriorityDumper =
2717                new PriorityDump.PriorityDumper() {
2718            @Override
2719            public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
2720                    boolean asProto) {
2721                dump(fd, pw, new String[] {"-a"}, asProto);
2722            }
2723
2724            @Override
2725            public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
2726                mActivityManagerService.dumpApplicationMemoryUsage(
2727                        fd, pw, "  ", args, false, null, asProto);
2728            }
2729        };
2730
2731        MemBinder(ActivityManagerService activityManagerService) {
2732            mActivityManagerService = activityManagerService;
2733        }
2734
2735        @Override
2736        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2737            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2738                    "meminfo", pw)) return;
2739            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2740        }
2741    }
2742
2743    static class GraphicsBinder extends Binder {
2744        ActivityManagerService mActivityManagerService;
2745        GraphicsBinder(ActivityManagerService activityManagerService) {
2746            mActivityManagerService = activityManagerService;
2747        }
2748
2749        @Override
2750        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2751            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2752                    "gfxinfo", pw)) return;
2753            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2754        }
2755    }
2756
2757    static class DbBinder extends Binder {
2758        ActivityManagerService mActivityManagerService;
2759        DbBinder(ActivityManagerService activityManagerService) {
2760            mActivityManagerService = activityManagerService;
2761        }
2762
2763        @Override
2764        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2765            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2766                    "dbinfo", pw)) return;
2767            mActivityManagerService.dumpDbInfo(fd, pw, args);
2768        }
2769    }
2770
2771    static class CpuBinder extends Binder {
2772        ActivityManagerService mActivityManagerService;
2773        private final PriorityDump.PriorityDumper mPriorityDumper =
2774                new PriorityDump.PriorityDumper() {
2775            @Override
2776            public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
2777                    boolean asProto) {
2778                if (asProto) return;
2779                if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2780                        "cpuinfo", pw)) return;
2781                synchronized (mActivityManagerService.mProcessCpuTracker) {
2782                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2783                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2784                            SystemClock.uptimeMillis()));
2785                }
2786            }
2787        };
2788
2789        CpuBinder(ActivityManagerService activityManagerService) {
2790            mActivityManagerService = activityManagerService;
2791        }
2792
2793        @Override
2794        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2795            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2796        }
2797    }
2798
2799    public static final class Lifecycle extends SystemService {
2800        private final ActivityManagerService mService;
2801
2802        public Lifecycle(Context context) {
2803            super(context);
2804            mService = new ActivityManagerService(context);
2805        }
2806
2807        @Override
2808        public void onStart() {
2809            mService.start();
2810        }
2811
2812        @Override
2813        public void onBootPhase(int phase) {
2814            if (phase == PHASE_SYSTEM_SERVICES_READY) {
2815                mService.mBatteryStatsService.systemServicesReady();
2816            }
2817        }
2818
2819        @Override
2820        public void onCleanupUser(int userId) {
2821            mService.mBatteryStatsService.onCleanupUser(userId);
2822        }
2823
2824        public ActivityManagerService getService() {
2825            return mService;
2826        }
2827    }
2828
2829    /**
2830     * Encapsulates the globla setting "hidden_api_blacklist_exemptions", including tracking the
2831     * latest value via a content observer.
2832     */
2833    static class HiddenApiBlacklist extends ContentObserver {
2834
2835        private final Context mContext;
2836        private boolean mBlacklistDisabled;
2837
2838        public HiddenApiBlacklist(Handler handler, Context context) {
2839            super(handler);
2840            mContext = context;
2841        }
2842
2843        public void registerObserver() {
2844            mContext.getContentResolver().registerContentObserver(
2845                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
2846                    false,
2847                    this);
2848            update();
2849        }
2850
2851        private void update() {
2852            mBlacklistDisabled = "*".equals(Settings.Global.getString(mContext.getContentResolver(),
2853                    Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS));
2854        }
2855
2856        boolean isDisabled() {
2857            return mBlacklistDisabled;
2858        }
2859
2860        public void onChange(boolean selfChange) {
2861            update();
2862        }
2863    }
2864
2865    @VisibleForTesting
2866    public ActivityManagerService(Injector injector) {
2867        mInjector = injector;
2868        mContext = mInjector.getContext();
2869        mUiContext = null;
2870        GL_ES_VERSION = 0;
2871        mActivityStartController = null;
2872        mAppErrors = null;
2873        mAppWarnings = null;
2874        mAppOpsService = mInjector.getAppOpsService(null, null);
2875        mBatteryStatsService = null;
2876        mCompatModePackages = null;
2877        mConstants = null;
2878        mGrantFile = null;
2879        mHandler = null;
2880        mHandlerThread = null;
2881        mIntentFirewall = null;
2882        mKeyguardController = null;
2883        mPermissionReviewRequired = false;
2884        mProcessCpuThread = null;
2885        mProcessStats = null;
2886        mProviderMap = null;
2887        mRecentTasks = null;
2888        mServices = null;
2889        mStackSupervisor = null;
2890        mSystemThread = null;
2891        mTaskChangeNotificationController = null;
2892        mUiHandler = injector.getUiHandler(null);
2893        mUserController = null;
2894        mVrController = null;
2895        mLockTaskController = null;
2896        mLifecycleManager = null;
2897        mProcStartHandlerThread = null;
2898        mProcStartHandler = null;
2899        mHiddenApiBlacklist = null;
2900    }
2901
2902    // Note: This method is invoked on the main thread but may need to attach various
2903    // handlers to other threads.  So take care to be explicit about the looper.
2904    public ActivityManagerService(Context systemContext) {
2905        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2906        mInjector = new Injector();
2907        mContext = systemContext;
2908
2909        mFactoryTest = FactoryTest.getMode();
2910        mSystemThread = ActivityThread.currentActivityThread();
2911        mUiContext = mSystemThread.getSystemUiContext();
2912
2913        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2914
2915        mPermissionReviewRequired = mContext.getResources().getBoolean(
2916                com.android.internal.R.bool.config_permissionReviewRequired);
2917
2918        mHandlerThread = new ServiceThread(TAG,
2919                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2920        mHandlerThread.start();
2921        mHandler = new MainHandler(mHandlerThread.getLooper());
2922        mUiHandler = mInjector.getUiHandler(this);
2923
2924        mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
2925                THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
2926        mProcStartHandlerThread.start();
2927        mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
2928
2929        mConstants = new ActivityManagerConstants(this, mHandler);
2930
2931        /* static; one-time init here */
2932        if (sKillHandler == null) {
2933            sKillThread = new ServiceThread(TAG + ":kill",
2934                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2935            sKillThread.start();
2936            sKillHandler = new KillHandler(sKillThread.getLooper());
2937        }
2938
2939        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2940                "foreground", BROADCAST_FG_TIMEOUT, false);
2941        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2942                "background", BROADCAST_BG_TIMEOUT, true);
2943        mBroadcastQueues[0] = mFgBroadcastQueue;
2944        mBroadcastQueues[1] = mBgBroadcastQueue;
2945
2946        mServices = new ActiveServices(this);
2947        mProviderMap = new ProviderMap(this);
2948        mAppErrors = new AppErrors(mUiContext, this);
2949
2950        File dataDir = Environment.getDataDirectory();
2951        File systemDir = new File(dataDir, "system");
2952        systemDir.mkdirs();
2953
2954        mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
2955
2956        // TODO: Move creation of battery stats service outside of activity manager service.
2957        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2958        mBatteryStatsService.getActiveStatistics().readLocked();
2959        mBatteryStatsService.scheduleWriteToDisk();
2960        mOnBattery = DEBUG_POWER ? true
2961                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2962        mBatteryStatsService.getActiveStatistics().setCallback(this);
2963
2964        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2965
2966        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2967        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2968                new IAppOpsCallback.Stub() {
2969                    @Override public void opChanged(int op, int uid, String packageName) {
2970                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2971                            if (mAppOpsService.checkOperation(op, uid, packageName)
2972                                    != AppOpsManager.MODE_ALLOWED) {
2973                                runInBackgroundDisabled(uid);
2974                            }
2975                        }
2976                    }
2977                });
2978
2979        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
2980
2981        mUserController = new UserController(this);
2982
2983        mVrController = new VrController(this);
2984
2985        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2986            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2987
2988        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2989            mUseFifoUiScheduling = true;
2990        }
2991
2992        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2993        mTempConfig.setToDefaults();
2994        mTempConfig.setLocales(LocaleList.getDefault());
2995        mConfigurationSeq = mTempConfig.seq = 1;
2996        mStackSupervisor = createStackSupervisor();
2997        mStackSupervisor.onConfigurationChanged(mTempConfig);
2998        mKeyguardController = mStackSupervisor.getKeyguardController();
2999        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
3000        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
3001        mTaskChangeNotificationController =
3002                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
3003        mActivityStartController = new ActivityStartController(this);
3004        mRecentTasks = createRecentTasks();
3005        mStackSupervisor.setRecentTasks(mRecentTasks);
3006        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
3007        mLifecycleManager = new ClientLifecycleManager();
3008
3009        mProcessCpuThread = new Thread("CpuTracker") {
3010            @Override
3011            public void run() {
3012                synchronized (mProcessCpuTracker) {
3013                    mProcessCpuInitLatch.countDown();
3014                    mProcessCpuTracker.init();
3015                }
3016                while (true) {
3017                    try {
3018                        try {
3019                            synchronized(this) {
3020                                final long now = SystemClock.uptimeMillis();
3021                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
3022                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
3023                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
3024                                //        + ", write delay=" + nextWriteDelay);
3025                                if (nextWriteDelay < nextCpuDelay) {
3026                                    nextCpuDelay = nextWriteDelay;
3027                                }
3028                                if (nextCpuDelay > 0) {
3029                                    mProcessCpuMutexFree.set(true);
3030                                    this.wait(nextCpuDelay);
3031                                }
3032                            }
3033                        } catch (InterruptedException e) {
3034                        }
3035                        updateCpuStatsNow();
3036                    } catch (Exception e) {
3037                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
3038                    }
3039                }
3040            }
3041        };
3042
3043        mHiddenApiBlacklist = new HiddenApiBlacklist(mHandler, mContext);
3044
3045        Watchdog.getInstance().addMonitor(this);
3046        Watchdog.getInstance().addThread(mHandler);
3047
3048        // bind background thread to little cores
3049        // this is expected to fail inside of framework tests because apps can't touch cpusets directly
3050        try {
3051            Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(),
3052                    Process.THREAD_GROUP_BG_NONINTERACTIVE);
3053        } catch (Exception e) {
3054            Slog.w(TAG, "Setting background thread cpuset failed");
3055        }
3056
3057    }
3058
3059    protected ActivityStackSupervisor createStackSupervisor() {
3060        final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
3061        supervisor.initialize();
3062        return supervisor;
3063    }
3064
3065    protected RecentTasks createRecentTasks() {
3066        return new RecentTasks(this, mStackSupervisor);
3067    }
3068
3069    RecentTasks getRecentTasks() {
3070        return mRecentTasks;
3071    }
3072
3073    public void setSystemServiceManager(SystemServiceManager mgr) {
3074        mSystemServiceManager = mgr;
3075    }
3076
3077    public void setInstaller(Installer installer) {
3078        mInstaller = installer;
3079    }
3080
3081    private void start() {
3082        removeAllProcessGroups();
3083        mProcessCpuThread.start();
3084
3085        mBatteryStatsService.publish();
3086        mAppOpsService.publish(mContext);
3087        Slog.d("AppOps", "AppOpsService published");
3088        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
3089        // Wait for the synchronized block started in mProcessCpuThread,
3090        // so that any other acccess to mProcessCpuTracker from main thread
3091        // will be blocked during mProcessCpuTracker initialization.
3092        try {
3093            mProcessCpuInitLatch.await();
3094        } catch (InterruptedException e) {
3095            Slog.wtf(TAG, "Interrupted wait during start", e);
3096            Thread.currentThread().interrupt();
3097            throw new IllegalStateException("Interrupted wait during start");
3098        }
3099    }
3100
3101    void onUserStoppedLocked(int userId) {
3102        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
3103        mAllowAppSwitchUids.remove(userId);
3104    }
3105
3106    public void initPowerManagement() {
3107        mStackSupervisor.initPowerManagement();
3108        mBatteryStatsService.initPowerManagement();
3109        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
3110        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
3111        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
3112        mVoiceWakeLock.setReferenceCounted(false);
3113    }
3114
3115    private ArraySet<String> getBackgroundLaunchBroadcasts() {
3116        if (mBackgroundLaunchBroadcasts == null) {
3117            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
3118        }
3119        return mBackgroundLaunchBroadcasts;
3120    }
3121
3122    @Override
3123    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3124            throws RemoteException {
3125        if (code == SYSPROPS_TRANSACTION) {
3126            // We need to tell all apps about the system property change.
3127            ArrayList<IBinder> procs = new ArrayList<IBinder>();
3128            synchronized(this) {
3129                final int NP = mProcessNames.getMap().size();
3130                for (int ip=0; ip<NP; ip++) {
3131                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3132                    final int NA = apps.size();
3133                    for (int ia=0; ia<NA; ia++) {
3134                        ProcessRecord app = apps.valueAt(ia);
3135                        if (app.thread != null) {
3136                            procs.add(app.thread.asBinder());
3137                        }
3138                    }
3139                }
3140            }
3141
3142            int N = procs.size();
3143            for (int i=0; i<N; i++) {
3144                Parcel data2 = Parcel.obtain();
3145                try {
3146                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
3147                            Binder.FLAG_ONEWAY);
3148                } catch (RemoteException e) {
3149                }
3150                data2.recycle();
3151            }
3152        }
3153        try {
3154            return super.onTransact(code, data, reply, flags);
3155        } catch (RuntimeException e) {
3156            // The activity manager only throws certain exceptions intentionally, so let's
3157            // log all others.
3158            if (!(e instanceof SecurityException
3159                    || e instanceof IllegalArgumentException
3160                    || e instanceof IllegalStateException)) {
3161                Slog.wtf(TAG, "Activity Manager Crash."
3162                        + " UID:" + Binder.getCallingUid()
3163                        + " PID:" + Binder.getCallingPid()
3164                        + " TRANS:" + code, e);
3165            }
3166            throw e;
3167        }
3168    }
3169
3170    void updateCpuStats() {
3171        final long now = SystemClock.uptimeMillis();
3172        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3173            return;
3174        }
3175        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3176            synchronized (mProcessCpuThread) {
3177                mProcessCpuThread.notify();
3178            }
3179        }
3180    }
3181
3182    void updateCpuStatsNow() {
3183        synchronized (mProcessCpuTracker) {
3184            mProcessCpuMutexFree.set(false);
3185            final long now = SystemClock.uptimeMillis();
3186            boolean haveNewCpuStats = false;
3187
3188            if (MONITOR_CPU_USAGE &&
3189                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3190                mLastCpuTime.set(now);
3191                mProcessCpuTracker.update();
3192                if (mProcessCpuTracker.hasGoodLastStats()) {
3193                    haveNewCpuStats = true;
3194                    //Slog.i(TAG, mProcessCpu.printCurrentState());
3195                    //Slog.i(TAG, "Total CPU usage: "
3196                    //        + mProcessCpu.getTotalCpuPercent() + "%");
3197
3198                    // Slog the cpu usage if the property is set.
3199                    if ("true".equals(SystemProperties.get("events.cpu"))) {
3200                        int user = mProcessCpuTracker.getLastUserTime();
3201                        int system = mProcessCpuTracker.getLastSystemTime();
3202                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
3203                        int irq = mProcessCpuTracker.getLastIrqTime();
3204                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3205                        int idle = mProcessCpuTracker.getLastIdleTime();
3206
3207                        int total = user + system + iowait + irq + softIrq + idle;
3208                        if (total == 0) total = 1;
3209
3210                        EventLog.writeEvent(EventLogTags.CPU,
3211                                ((user+system+iowait+irq+softIrq) * 100) / total,
3212                                (user * 100) / total,
3213                                (system * 100) / total,
3214                                (iowait * 100) / total,
3215                                (irq * 100) / total,
3216                                (softIrq * 100) / total);
3217                    }
3218                }
3219            }
3220
3221            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3222            synchronized(bstats) {
3223                synchronized(mPidsSelfLocked) {
3224                    if (haveNewCpuStats) {
3225                        if (bstats.startAddingCpuLocked()) {
3226                            int totalUTime = 0;
3227                            int totalSTime = 0;
3228                            final int N = mProcessCpuTracker.countStats();
3229                            for (int i=0; i<N; i++) {
3230                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3231                                if (!st.working) {
3232                                    continue;
3233                                }
3234                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3235                                totalUTime += st.rel_utime;
3236                                totalSTime += st.rel_stime;
3237                                if (pr != null) {
3238                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3239                                    if (ps == null || !ps.isActive()) {
3240                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3241                                                pr.info.uid, pr.processName);
3242                                    }
3243                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3244                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3245                                    if (pr.lastCpuTime == 0) {
3246                                        pr.lastCpuTime = pr.curCpuTime;
3247                                    }
3248                                } else {
3249                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3250                                    if (ps == null || !ps.isActive()) {
3251                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3252                                                bstats.mapUid(st.uid), st.name);
3253                                    }
3254                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3255                                }
3256                            }
3257                            final int userTime = mProcessCpuTracker.getLastUserTime();
3258                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3259                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3260                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3261                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3262                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3263                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3264                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3265                        }
3266                    }
3267                }
3268
3269                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3270                    mLastWriteTime = now;
3271                    mBatteryStatsService.scheduleWriteToDisk();
3272                }
3273            }
3274        }
3275    }
3276
3277    @Override
3278    public void batteryNeedsCpuUpdate() {
3279        updateCpuStatsNow();
3280    }
3281
3282    @Override
3283    public void batteryPowerChanged(boolean onBattery) {
3284        // When plugging in, update the CPU stats first before changing
3285        // the plug state.
3286        updateCpuStatsNow();
3287        synchronized (this) {
3288            synchronized(mPidsSelfLocked) {
3289                mOnBattery = DEBUG_POWER ? true : onBattery;
3290            }
3291        }
3292    }
3293
3294    @Override
3295    public void batterySendBroadcast(Intent intent) {
3296        synchronized (this) {
3297            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3298                    OP_NONE, null, false, false,
3299                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3300        }
3301    }
3302
3303    /**
3304     * Initialize the application bind args. These are passed to each
3305     * process when the bindApplication() IPC is sent to the process. They're
3306     * lazily setup to make sure the services are running when they're asked for.
3307     */
3308    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3309        // Isolated processes won't get this optimization, so that we don't
3310        // violate the rules about which services they have access to.
3311        if (isolated) {
3312            if (mIsolatedAppBindArgs == null) {
3313                mIsolatedAppBindArgs = new HashMap<>();
3314                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3315            }
3316            return mIsolatedAppBindArgs;
3317        }
3318
3319        if (mAppBindArgs == null) {
3320            mAppBindArgs = new HashMap<>();
3321
3322            // Setup the application init args
3323            mAppBindArgs.put("package", ServiceManager.getService("package"));
3324            mAppBindArgs.put("window", ServiceManager.getService("window"));
3325            mAppBindArgs.put(Context.ALARM_SERVICE,
3326                    ServiceManager.getService(Context.ALARM_SERVICE));
3327        }
3328        return mAppBindArgs;
3329    }
3330
3331    /**
3332     * Update AMS states when an activity is resumed. This should only be called by
3333     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3334     */
3335    @GuardedBy("this")
3336    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3337        final TaskRecord task = r.getTask();
3338        if (task.isActivityTypeStandard()) {
3339            if (mCurAppTimeTracker != r.appTimeTracker) {
3340                // We are switching app tracking.  Complete the current one.
3341                if (mCurAppTimeTracker != null) {
3342                    mCurAppTimeTracker.stop();
3343                    mHandler.obtainMessage(
3344                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3345                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3346                    mCurAppTimeTracker = null;
3347                }
3348                if (r.appTimeTracker != null) {
3349                    mCurAppTimeTracker = r.appTimeTracker;
3350                    startTimeTrackingFocusedActivityLocked();
3351                }
3352            } else {
3353                startTimeTrackingFocusedActivityLocked();
3354            }
3355        } else {
3356            r.appTimeTracker = null;
3357        }
3358        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3359        // TODO: Probably not, because we don't want to resume voice on switching
3360        // back to this activity
3361        if (task.voiceInteractor != null) {
3362            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3363        } else {
3364            finishRunningVoiceLocked();
3365
3366            if (mLastResumedActivity != null) {
3367                final IVoiceInteractionSession session;
3368
3369                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3370                if (lastResumedActivityTask != null
3371                        && lastResumedActivityTask.voiceSession != null) {
3372                    session = lastResumedActivityTask.voiceSession;
3373                } else {
3374                    session = mLastResumedActivity.voiceSession;
3375                }
3376
3377                if (session != null) {
3378                    // We had been in a voice interaction session, but now focused has
3379                    // move to something different.  Just finish the session, we can't
3380                    // return to it and retain the proper state and synchronization with
3381                    // the voice interaction service.
3382                    finishVoiceTask(session);
3383                }
3384            }
3385        }
3386
3387        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3388            mUserController.sendForegroundProfileChanged(r.userId);
3389        }
3390        mLastResumedActivity = r;
3391
3392        mWindowManager.setFocusedApp(r.appToken, true);
3393
3394        applyUpdateLockStateLocked(r);
3395        applyUpdateVrModeLocked(r);
3396
3397        EventLogTags.writeAmSetResumedActivity(
3398                r == null ? -1 : r.userId,
3399                r == null ? "NULL" : r.shortComponentName,
3400                reason);
3401    }
3402
3403    @Override
3404    public void setFocusedStack(int stackId) {
3405        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3406        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3407        final long callingId = Binder.clearCallingIdentity();
3408        try {
3409            synchronized (this) {
3410                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3411                if (stack == null) {
3412                    Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3413                    return;
3414                }
3415                final ActivityRecord r = stack.topRunningActivityLocked();
3416                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3417                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3418                }
3419            }
3420        } finally {
3421            Binder.restoreCallingIdentity(callingId);
3422        }
3423    }
3424
3425    @Override
3426    public void setFocusedTask(int taskId) {
3427        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3428        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3429        final long callingId = Binder.clearCallingIdentity();
3430        try {
3431            synchronized (this) {
3432                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3433                if (task == null) {
3434                    return;
3435                }
3436                final ActivityRecord r = task.topRunningActivityLocked();
3437                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3438                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3439                }
3440            }
3441        } finally {
3442            Binder.restoreCallingIdentity(callingId);
3443        }
3444    }
3445
3446    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3447    @Override
3448    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3449        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3450                "registerTaskStackListener()");
3451        mTaskChangeNotificationController.registerTaskStackListener(listener);
3452    }
3453
3454    /**
3455     * Unregister a task stack listener so that it stops receiving callbacks.
3456     */
3457    @Override
3458    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3459        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3460                "unregisterTaskStackListener()");
3461         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3462     }
3463
3464    @Override
3465    public void notifyActivityDrawn(IBinder token) {
3466        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3467        synchronized (this) {
3468            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3469            if (r != null) {
3470                r.getStack().notifyActivityDrawnLocked(r);
3471            }
3472        }
3473    }
3474
3475    final void applyUpdateLockStateLocked(ActivityRecord r) {
3476        // Modifications to the UpdateLock state are done on our handler, outside
3477        // the activity manager's locks.  The new state is determined based on the
3478        // state *now* of the relevant activity record.  The object is passed to
3479        // the handler solely for logging detail, not to be consulted/modified.
3480        final boolean nextState = r != null && r.immersive;
3481        mHandler.sendMessage(
3482                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3483    }
3484
3485    final void applyUpdateVrModeLocked(ActivityRecord r) {
3486        // VR apps are expected to run in a main display. If an app is turning on VR for
3487        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3488        // fullscreen stack before enabling VR Mode.
3489        // TODO: The goal of this code is to keep the VR app on the main display. When the
3490        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3491        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3492        // option would be a better choice here.
3493        if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3494            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3495                    + " to main stack for VR");
3496            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3497                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3498            moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3499        }
3500        mHandler.sendMessage(
3501                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3502    }
3503
3504    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3505        Message msg = Message.obtain();
3506        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3507        msg.obj = r.getTask().askedCompatMode ? null : r;
3508        mUiHandler.sendMessage(msg);
3509    }
3510
3511    final AppWarnings getAppWarningsLocked() {
3512        return mAppWarnings;
3513    }
3514
3515    /**
3516     * Shows app warning dialogs, if necessary.
3517     *
3518     * @param r activity record for which the warnings may be displayed
3519     */
3520    final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3521        mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3522        mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3523        mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
3524    }
3525
3526    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3527            String what, Object obj, ProcessRecord srcApp) {
3528        app.lastActivityTime = now;
3529
3530        if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3531            // Don't want to touch dependent processes that are hosting activities.
3532            return index;
3533        }
3534
3535        int lrui = mLruProcesses.lastIndexOf(app);
3536        if (lrui < 0) {
3537            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3538                    + what + " " + obj + " from " + srcApp);
3539            return index;
3540        }
3541
3542        if (lrui >= index) {
3543            // Don't want to cause this to move dependent processes *back* in the
3544            // list as if they were less frequently used.
3545            return index;
3546        }
3547
3548        if (lrui >= mLruProcessActivityStart) {
3549            // Don't want to touch dependent processes that are hosting activities.
3550            return index;
3551        }
3552
3553        mLruProcesses.remove(lrui);
3554        if (index > 0) {
3555            index--;
3556        }
3557        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3558                + " in LRU list: " + app);
3559        mLruProcesses.add(index, app);
3560        return index;
3561    }
3562
3563    static void killProcessGroup(int uid, int pid) {
3564        if (sKillHandler != null) {
3565            sKillHandler.sendMessage(
3566                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3567        } else {
3568            Slog.w(TAG, "Asked to kill process group before system bringup!");
3569            Process.killProcessGroup(uid, pid);
3570        }
3571    }
3572
3573    final void removeLruProcessLocked(ProcessRecord app) {
3574        int lrui = mLruProcesses.lastIndexOf(app);
3575        if (lrui >= 0) {
3576            if (!app.killed) {
3577                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3578                if (app.pid > 0) {
3579                    killProcessQuiet(app.pid);
3580                    killProcessGroup(app.uid, app.pid);
3581                } else {
3582                    app.pendingStart = false;
3583                }
3584            }
3585            if (lrui <= mLruProcessActivityStart) {
3586                mLruProcessActivityStart--;
3587            }
3588            if (lrui <= mLruProcessServiceStart) {
3589                mLruProcessServiceStart--;
3590            }
3591            mLruProcesses.remove(lrui);
3592        }
3593    }
3594
3595    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3596            ProcessRecord client) {
3597        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3598                || app.treatLikeActivity || app.recentTasks.size() > 0;
3599        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3600        if (!activityChange && hasActivity) {
3601            // The process has activities, so we are only allowing activity-based adjustments
3602            // to move it.  It should be kept in the front of the list with other
3603            // processes that have activities, and we don't want those to change their
3604            // order except due to activity operations.
3605            return;
3606        }
3607
3608        mLruSeq++;
3609        final long now = SystemClock.uptimeMillis();
3610        app.lastActivityTime = now;
3611
3612        // First a quick reject: if the app is already at the position we will
3613        // put it, then there is nothing to do.
3614        if (hasActivity) {
3615            final int N = mLruProcesses.size();
3616            if (N > 0 && mLruProcesses.get(N-1) == app) {
3617                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3618                return;
3619            }
3620        } else {
3621            if (mLruProcessServiceStart > 0
3622                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3623                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3624                return;
3625            }
3626        }
3627
3628        int lrui = mLruProcesses.lastIndexOf(app);
3629
3630        if (app.persistent && lrui >= 0) {
3631            // We don't care about the position of persistent processes, as long as
3632            // they are in the list.
3633            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3634            return;
3635        }
3636
3637        /* In progress: compute new position first, so we can avoid doing work
3638           if the process is not actually going to move.  Not yet working.
3639        int addIndex;
3640        int nextIndex;
3641        boolean inActivity = false, inService = false;
3642        if (hasActivity) {
3643            // Process has activities, put it at the very tipsy-top.
3644            addIndex = mLruProcesses.size();
3645            nextIndex = mLruProcessServiceStart;
3646            inActivity = true;
3647        } else if (hasService) {
3648            // Process has services, put it at the top of the service list.
3649            addIndex = mLruProcessActivityStart;
3650            nextIndex = mLruProcessServiceStart;
3651            inActivity = true;
3652            inService = true;
3653        } else  {
3654            // Process not otherwise of interest, it goes to the top of the non-service area.
3655            addIndex = mLruProcessServiceStart;
3656            if (client != null) {
3657                int clientIndex = mLruProcesses.lastIndexOf(client);
3658                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3659                        + app);
3660                if (clientIndex >= 0 && addIndex > clientIndex) {
3661                    addIndex = clientIndex;
3662                }
3663            }
3664            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3665        }
3666
3667        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3668                + mLruProcessActivityStart + "): " + app);
3669        */
3670
3671        if (lrui >= 0) {
3672            if (lrui < mLruProcessActivityStart) {
3673                mLruProcessActivityStart--;
3674            }
3675            if (lrui < mLruProcessServiceStart) {
3676                mLruProcessServiceStart--;
3677            }
3678            /*
3679            if (addIndex > lrui) {
3680                addIndex--;
3681            }
3682            if (nextIndex > lrui) {
3683                nextIndex--;
3684            }
3685            */
3686            mLruProcesses.remove(lrui);
3687        }
3688
3689        /*
3690        mLruProcesses.add(addIndex, app);
3691        if (inActivity) {
3692            mLruProcessActivityStart++;
3693        }
3694        if (inService) {
3695            mLruProcessActivityStart++;
3696        }
3697        */
3698
3699        int nextIndex;
3700        if (hasActivity) {
3701            final int N = mLruProcesses.size();
3702            if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
3703                    && mLruProcessActivityStart < (N - 1)) {
3704                // Process doesn't have activities, but has clients with
3705                // activities...  move it up, but one below the top (the top
3706                // should always have a real activity).
3707                if (DEBUG_LRU) Slog.d(TAG_LRU,
3708                        "Adding to second-top of LRU activity list: " + app);
3709                mLruProcesses.add(N - 1, app);
3710                // To keep it from spamming the LRU list (by making a bunch of clients),
3711                // we will push down any other entries owned by the app.
3712                final int uid = app.info.uid;
3713                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3714                    ProcessRecord subProc = mLruProcesses.get(i);
3715                    if (subProc.info.uid == uid) {
3716                        // We want to push this one down the list.  If the process after
3717                        // it is for the same uid, however, don't do so, because we don't
3718                        // want them internally to be re-ordered.
3719                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3720                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3721                                    "Pushing uid " + uid + " swapping at " + i + ": "
3722                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3723                            ProcessRecord tmp = mLruProcesses.get(i);
3724                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3725                            mLruProcesses.set(i - 1, tmp);
3726                            i--;
3727                        }
3728                    } else {
3729                        // A gap, we can stop here.
3730                        break;
3731                    }
3732                }
3733            } else {
3734                // Process has activities, put it at the very tipsy-top.
3735                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3736                mLruProcesses.add(app);
3737            }
3738            nextIndex = mLruProcessServiceStart;
3739        } else if (hasService) {
3740            // Process has services, put it at the top of the service list.
3741            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3742            mLruProcesses.add(mLruProcessActivityStart, app);
3743            nextIndex = mLruProcessServiceStart;
3744            mLruProcessActivityStart++;
3745        } else  {
3746            // Process not otherwise of interest, it goes to the top of the non-service area.
3747            int index = mLruProcessServiceStart;
3748            if (client != null) {
3749                // If there is a client, don't allow the process to be moved up higher
3750                // in the list than that client.
3751                int clientIndex = mLruProcesses.lastIndexOf(client);
3752                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3753                        + " when updating " + app);
3754                if (clientIndex <= lrui) {
3755                    // Don't allow the client index restriction to push it down farther in the
3756                    // list than it already is.
3757                    clientIndex = lrui;
3758                }
3759                if (clientIndex >= 0 && index > clientIndex) {
3760                    index = clientIndex;
3761                }
3762            }
3763            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3764            mLruProcesses.add(index, app);
3765            nextIndex = index-1;
3766            mLruProcessActivityStart++;
3767            mLruProcessServiceStart++;
3768        }
3769
3770        // If the app is currently using a content provider or service,
3771        // bump those processes as well.
3772        for (int j=app.connections.size()-1; j>=0; j--) {
3773            ConnectionRecord cr = app.connections.valueAt(j);
3774            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3775                    && cr.binding.service.app != null
3776                    && cr.binding.service.app.lruSeq != mLruSeq
3777                    && !cr.binding.service.app.persistent) {
3778                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3779                        "service connection", cr, app);
3780            }
3781        }
3782        for (int j=app.conProviders.size()-1; j>=0; j--) {
3783            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3784            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3785                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3786                        "provider reference", cpr, app);
3787            }
3788        }
3789    }
3790
3791    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3792        if (uid == SYSTEM_UID) {
3793            // The system gets to run in any process.  If there are multiple
3794            // processes with the same uid, just pick the first (this
3795            // should never happen).
3796            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3797            if (procs == null) return null;
3798            final int procCount = procs.size();
3799            for (int i = 0; i < procCount; i++) {
3800                final int procUid = procs.keyAt(i);
3801                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3802                    // Don't use an app process or different user process for system component.
3803                    continue;
3804                }
3805                return procs.valueAt(i);
3806            }
3807        }
3808        ProcessRecord proc = mProcessNames.get(processName, uid);
3809        if (false && proc != null && !keepIfLarge
3810                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3811                && proc.lastCachedPss >= 4000) {
3812            // Turn this condition on to cause killing to happen regularly, for testing.
3813            if (proc.baseProcessTracker != null) {
3814                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3815            }
3816            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3817        } else if (proc != null && !keepIfLarge
3818                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3819                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3820            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3821            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3822                if (proc.baseProcessTracker != null) {
3823                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3824                }
3825                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3826            }
3827        }
3828        return proc;
3829    }
3830
3831    void notifyPackageUse(String packageName, int reason) {
3832        synchronized(this) {
3833            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3834        }
3835    }
3836
3837    boolean isNextTransitionForward() {
3838        int transit = mWindowManager.getPendingAppTransition();
3839        return transit == TRANSIT_ACTIVITY_OPEN
3840                || transit == TRANSIT_TASK_OPEN
3841                || transit == TRANSIT_TASK_TO_FRONT;
3842    }
3843
3844    boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3845            String processName, String abiOverride, int uid, Runnable crashHandler) {
3846        synchronized(this) {
3847            ApplicationInfo info = new ApplicationInfo();
3848            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3849            // For isolated processes, the former contains the parent's uid and the latter the
3850            // actual uid of the isolated process.
3851            // In the special case introduced by this method (which is, starting an isolated
3852            // process directly from the SystemServer without an actual parent app process) the
3853            // closest thing to a parent's uid is SYSTEM_UID.
3854            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3855            // the |isolated| logic in the ProcessRecord constructor.
3856            info.uid = SYSTEM_UID;
3857            info.processName = processName;
3858            info.className = entryPoint;
3859            info.packageName = "android";
3860            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3861            info.targetSdkVersion = Build.VERSION.SDK_INT;
3862            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3863                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3864                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3865                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3866                    crashHandler);
3867            return proc != null;
3868        }
3869    }
3870
3871    @GuardedBy("this")
3872    final ProcessRecord startProcessLocked(String processName,
3873            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3874            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3875            boolean isolated, boolean keepIfLarge) {
3876        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3877                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3878                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3879                null /* crashHandler */);
3880    }
3881
3882    @GuardedBy("this")
3883    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3884            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3885            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3886            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3887        long startTime = SystemClock.elapsedRealtime();
3888        ProcessRecord app;
3889        if (!isolated) {
3890            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3891            checkTime(startTime, "startProcess: after getProcessRecord");
3892
3893            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3894                // If we are in the background, then check to see if this process
3895                // is bad.  If so, we will just silently fail.
3896                if (mAppErrors.isBadProcessLocked(info)) {
3897                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3898                            + "/" + info.processName);
3899                    return null;
3900                }
3901            } else {
3902                // When the user is explicitly starting a process, then clear its
3903                // crash count so that we won't make it bad until they see at
3904                // least one crash dialog again, and make the process good again
3905                // if it had been bad.
3906                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3907                        + "/" + info.processName);
3908                mAppErrors.resetProcessCrashTimeLocked(info);
3909                if (mAppErrors.isBadProcessLocked(info)) {
3910                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3911                            UserHandle.getUserId(info.uid), info.uid,
3912                            info.processName);
3913                    mAppErrors.clearBadProcessLocked(info);
3914                    if (app != null) {
3915                        app.bad = false;
3916                    }
3917                }
3918            }
3919        } else {
3920            // If this is an isolated process, it can't re-use an existing process.
3921            app = null;
3922        }
3923
3924        // We don't have to do anything more if:
3925        // (1) There is an existing application record; and
3926        // (2) The caller doesn't think it is dead, OR there is no thread
3927        //     object attached to it so we know it couldn't have crashed; and
3928        // (3) There is a pid assigned to it, so it is either starting or
3929        //     already running.
3930        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3931                + " app=" + app + " knownToBeDead=" + knownToBeDead
3932                + " thread=" + (app != null ? app.thread : null)
3933                + " pid=" + (app != null ? app.pid : -1));
3934        if (app != null && app.pid > 0) {
3935            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3936                // We already have the app running, or are waiting for it to
3937                // come up (we have a pid but not yet its thread), so keep it.
3938                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3939                // If this is a new package in the process, add the package to the list
3940                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3941                checkTime(startTime, "startProcess: done, added package to proc");
3942                return app;
3943            }
3944
3945            // An application record is attached to a previous process,
3946            // clean it up now.
3947            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3948            checkTime(startTime, "startProcess: bad proc running, killing");
3949            killProcessGroup(app.uid, app.pid);
3950            handleAppDiedLocked(app, true, true);
3951            checkTime(startTime, "startProcess: done killing old proc");
3952        }
3953
3954        String hostingNameStr = hostingName != null
3955                ? hostingName.flattenToShortString() : null;
3956
3957        if (app == null) {
3958            checkTime(startTime, "startProcess: creating new process record");
3959            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3960            if (app == null) {
3961                Slog.w(TAG, "Failed making new process record for "
3962                        + processName + "/" + info.uid + " isolated=" + isolated);
3963                return null;
3964            }
3965            app.crashHandler = crashHandler;
3966            app.isolatedEntryPoint = entryPoint;
3967            app.isolatedEntryPointArgs = entryPointArgs;
3968            checkTime(startTime, "startProcess: done creating new process record");
3969        } else {
3970            // If this is a new package in the process, add the package to the list
3971            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3972            checkTime(startTime, "startProcess: added package to existing proc");
3973        }
3974
3975        // If the system is not ready yet, then hold off on starting this
3976        // process until it is.
3977        if (!mProcessesReady
3978                && !isAllowedWhileBooting(info)
3979                && !allowWhileBooting) {
3980            if (!mProcessesOnHold.contains(app)) {
3981                mProcessesOnHold.add(app);
3982            }
3983            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3984                    "System not ready, putting on hold: " + app);
3985            checkTime(startTime, "startProcess: returning with proc on hold");
3986            return app;
3987        }
3988
3989        checkTime(startTime, "startProcess: stepping in to startProcess");
3990        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
3991        checkTime(startTime, "startProcess: done starting proc!");
3992        return success ? app : null;
3993    }
3994
3995    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3996        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3997    }
3998
3999    @GuardedBy("this")
4000    private final void startProcessLocked(ProcessRecord app,
4001            String hostingType, String hostingNameStr) {
4002        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
4003    }
4004
4005    /**
4006     * @return {@code true} if process start is successful, false otherwise.
4007     */
4008    @GuardedBy("this")
4009    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
4010            String hostingNameStr, String abiOverride) {
4011        if (app.pendingStart) {
4012            return true;
4013        }
4014        long startTime = SystemClock.elapsedRealtime();
4015        if (app.pid > 0 && app.pid != MY_PID) {
4016            checkTime(startTime, "startProcess: removing from pids map");
4017            synchronized (mPidsSelfLocked) {
4018                mPidsSelfLocked.remove(app.pid);
4019                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4020            }
4021            checkTime(startTime, "startProcess: done removing from pids map");
4022            app.setPid(0);
4023        }
4024
4025        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
4026                "startProcessLocked removing on hold: " + app);
4027        mProcessesOnHold.remove(app);
4028
4029        checkTime(startTime, "startProcess: starting to update cpu stats");
4030        updateCpuStats();
4031        checkTime(startTime, "startProcess: done updating cpu stats");
4032
4033        try {
4034            try {
4035                final int userId = UserHandle.getUserId(app.uid);
4036                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
4037            } catch (RemoteException e) {
4038                throw e.rethrowAsRuntimeException();
4039            }
4040
4041            int uid = app.uid;
4042            int[] gids = null;
4043            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
4044            if (!app.isolated) {
4045                int[] permGids = null;
4046                try {
4047                    checkTime(startTime, "startProcess: getting gids from package manager");
4048                    final IPackageManager pm = AppGlobals.getPackageManager();
4049                    permGids = pm.getPackageGids(app.info.packageName,
4050                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
4051                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
4052                            StorageManagerInternal.class);
4053                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
4054                            app.info.packageName);
4055                } catch (RemoteException e) {
4056                    throw e.rethrowAsRuntimeException();
4057                }
4058
4059                /*
4060                 * Add shared application and profile GIDs so applications can share some
4061                 * resources like shared libraries and access user-wide resources
4062                 */
4063                if (ArrayUtils.isEmpty(permGids)) {
4064                    gids = new int[3];
4065                } else {
4066                    gids = new int[permGids.length + 3];
4067                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
4068                }
4069                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
4070                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
4071                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
4072
4073                // Replace any invalid GIDs
4074                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
4075                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
4076            }
4077            checkTime(startTime, "startProcess: building args");
4078            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
4079                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4080                        && mTopComponent != null
4081                        && app.processName.equals(mTopComponent.getPackageName())) {
4082                    uid = 0;
4083                }
4084                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
4085                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
4086                    uid = 0;
4087                }
4088            }
4089            int runtimeFlags = 0;
4090            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4091                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
4092                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
4093                // Also turn on CheckJNI for debuggable apps. It's quite
4094                // awkward to turn on otherwise.
4095                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4096            }
4097            // Run the app in safe mode if its manifest requests so or the
4098            // system is booted in safe mode.
4099            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
4100                mSafeMode == true) {
4101                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
4102            }
4103            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4104                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4105            }
4106            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4107            if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
4108                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4109            }
4110            String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
4111            if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
4112                runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
4113            }
4114            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4115                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4116            }
4117            if ("1".equals(SystemProperties.get("debug.assert"))) {
4118                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
4119            }
4120            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
4121                // Enable all debug flags required by the native debugger.
4122                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
4123                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
4124                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
4125                mNativeDebuggingApp = null;
4126            }
4127
4128            if (app.info.isPrivilegedApp() &&
4129                    SystemProperties.getBoolean("pm.dexopt.priv-apps-oob", false)) {
4130                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
4131            }
4132
4133            if (!app.info.isAllowedToUseHiddenApi() && !mHiddenApiBlacklist.isDisabled()) {
4134                // This app is not allowed to use undocumented and private APIs, or blacklisting is
4135                // enabled. Set up its runtime with the appropriate flag.
4136                runtimeFlags |= Zygote.ENABLE_HIDDEN_API_CHECKS;
4137            }
4138
4139            String invokeWith = null;
4140            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4141                // Debuggable apps may include a wrapper script with their library directory.
4142                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
4143                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4144                try {
4145                    if (new File(wrapperFileName).exists()) {
4146                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4147                    }
4148                } finally {
4149                    StrictMode.setThreadPolicy(oldPolicy);
4150                }
4151            }
4152
4153            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4154            if (requiredAbi == null) {
4155                requiredAbi = Build.SUPPORTED_ABIS[0];
4156            }
4157
4158            String instructionSet = null;
4159            if (app.info.primaryCpuAbi != null) {
4160                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4161            }
4162
4163            app.gids = gids;
4164            app.requiredAbi = requiredAbi;
4165            app.instructionSet = instructionSet;
4166
4167            // the per-user SELinux context must be set
4168            if (TextUtils.isEmpty(app.info.seInfoUser)) {
4169                Slog.wtf(TAG, "SELinux tag not defined",
4170                        new IllegalStateException("SELinux tag not defined for "
4171                        + app.info.packageName + " (uid " + app.uid + ")"));
4172            }
4173            final String seInfo = app.info.seInfo
4174                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
4175            // Start the process.  It will either succeed and return a result containing
4176            // the PID of the new process, or else throw a RuntimeException.
4177            final String entryPoint = "android.app.ActivityThread";
4178
4179            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4180                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4181                    startTime);
4182        } catch (RuntimeException e) {
4183            Slog.e(TAG, "Failure starting process " + app.processName, e);
4184
4185            // Something went very wrong while trying to start this process; one
4186            // common case is when the package is frozen due to an active
4187            // upgrade. To recover, clean up any active bookkeeping related to
4188            // starting this process. (We already invoked this method once when
4189            // the package was initially frozen through KILL_APPLICATION_MSG, so
4190            // it doesn't hurt to use it again.)
4191            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4192                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4193            return false;
4194        }
4195    }
4196
4197    @GuardedBy("this")
4198    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4199            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4200            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4201            long startTime) {
4202        app.pendingStart = true;
4203        app.killedByAm = false;
4204        app.removed = false;
4205        app.killed = false;
4206        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4207        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4208        if (mConstants.FLAG_PROCESS_START_ASYNC) {
4209            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4210                    "Posting procStart msg for " + app.toShortString());
4211            mProcStartHandler.post(() -> {
4212                try {
4213                    synchronized (ActivityManagerService.this) {
4214                        final String reason = isProcStartValidLocked(app, startSeq);
4215                        if (reason != null) {
4216                            Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4217                                    + " don't start process, " + reason);
4218                            app.pendingStart = false;
4219                            return;
4220                        }
4221                        app.usingWrapper = invokeWith != null
4222                                || SystemProperties.get("wrap." + app.processName) != null;
4223                        mPendingStarts.put(startSeq, app);
4224                    }
4225                    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4226                            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4227                            requiredAbi, instructionSet, invokeWith, app.startTime);
4228                    synchronized (ActivityManagerService.this) {
4229                        handleProcessStartedLocked(app, startResult, startSeq);
4230                    }
4231                } catch (RuntimeException e) {
4232                    synchronized (ActivityManagerService.this) {
4233                        Slog.e(TAG, "Failure starting process " + app.processName, e);
4234                        mPendingStarts.remove(startSeq);
4235                        app.pendingStart = false;
4236                        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4237                                false, false, true, false, false,
4238                                UserHandle.getUserId(app.userId), "start failure");
4239                    }
4240                }
4241            });
4242            return true;
4243        } else {
4244            try {
4245                final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4246                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4247                        invokeWith, startTime);
4248                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4249                        startSeq, false);
4250            } catch (RuntimeException e) {
4251                Slog.e(TAG, "Failure starting process " + app.processName, e);
4252                app.pendingStart = false;
4253                forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4254                        false, false, true, false, false,
4255                        UserHandle.getUserId(app.userId), "start failure");
4256            }
4257            return app.pid > 0;
4258        }
4259    }
4260
4261    private ProcessStartResult startProcess(String hostingType, String entryPoint,
4262            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4263            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4264            long startTime) {
4265        try {
4266            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4267                    app.processName);
4268            checkTime(startTime, "startProcess: asking zygote to start proc");
4269            final ProcessStartResult startResult;
4270            if (hostingType.equals("webview_service")) {
4271                startResult = startWebView(entryPoint,
4272                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4273                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4274                        app.info.dataDir, null,
4275                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4276            } else {
4277                startResult = Process.start(entryPoint,
4278                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4279                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4280                        app.info.dataDir, invokeWith,
4281                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4282            }
4283            checkTime(startTime, "startProcess: returned from zygote!");
4284            return startResult;
4285        } finally {
4286            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4287        }
4288    }
4289
4290    @GuardedBy("this")
4291    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4292        StringBuilder sb = null;
4293        if (app.killedByAm) {
4294            if (sb == null) sb = new StringBuilder();
4295            sb.append("killedByAm=true;");
4296        }
4297        if (mProcessNames.get(app.processName, app.uid) != app) {
4298            if (sb == null) sb = new StringBuilder();
4299            sb.append("No entry in mProcessNames;");
4300        }
4301        if (!app.pendingStart) {
4302            if (sb == null) sb = new StringBuilder();
4303            sb.append("pendingStart=false;");
4304        }
4305        if (app.startSeq > expectedStartSeq) {
4306            if (sb == null) sb = new StringBuilder();
4307            sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4308        }
4309        return sb == null ? null : sb.toString();
4310    }
4311
4312    @GuardedBy("this")
4313    private boolean handleProcessStartedLocked(ProcessRecord pending,
4314            ProcessStartResult startResult, long expectedStartSeq) {
4315        // Indicates that this process start has been taken care of.
4316        if (mPendingStarts.get(expectedStartSeq) == null) {
4317            if (pending.pid == startResult.pid) {
4318                pending.usingWrapper = startResult.usingWrapper;
4319                // TODO: Update already existing clients of usingWrapper
4320            }
4321            return false;
4322        }
4323        return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4324                expectedStartSeq, false);
4325    }
4326
4327    @GuardedBy("this")
4328    private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4329            long expectedStartSeq, boolean procAttached) {
4330        mPendingStarts.remove(expectedStartSeq);
4331        final String reason = isProcStartValidLocked(app, expectedStartSeq);
4332        if (reason != null) {
4333            Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4334                    + ", " + reason);
4335            app.pendingStart = false;
4336            Process.killProcessQuiet(pid);
4337            Process.killProcessGroup(app.uid, app.pid);
4338            return false;
4339        }
4340        mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4341        checkTime(app.startTime, "startProcess: done updating battery stats");
4342
4343        EventLog.writeEvent(EventLogTags.AM_PROC_START,
4344                UserHandle.getUserId(app.startUid), pid, app.startUid,
4345                app.processName, app.hostingType,
4346                app.hostingNameStr != null ? app.hostingNameStr : "");
4347
4348        try {
4349            AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4350                    app.seInfo, app.info.sourceDir, pid);
4351        } catch (RemoteException ex) {
4352            // Ignore
4353        }
4354
4355        if (app.persistent) {
4356            Watchdog.getInstance().processStarted(app.processName, pid);
4357        }
4358
4359        checkTime(app.startTime, "startProcess: building log message");
4360        StringBuilder buf = mStringBuilder;
4361        buf.setLength(0);
4362        buf.append("Start proc ");
4363        buf.append(pid);
4364        buf.append(':');
4365        buf.append(app.processName);
4366        buf.append('/');
4367        UserHandle.formatUid(buf, app.startUid);
4368        if (app.isolatedEntryPoint != null) {
4369            buf.append(" [");
4370            buf.append(app.isolatedEntryPoint);
4371            buf.append("]");
4372        }
4373        buf.append(" for ");
4374        buf.append(app.hostingType);
4375        if (app.hostingNameStr != null) {
4376            buf.append(" ");
4377            buf.append(app.hostingNameStr);
4378        }
4379        Slog.i(TAG, buf.toString());
4380        app.setPid(pid);
4381        app.usingWrapper = usingWrapper;
4382        app.pendingStart = false;
4383        checkTime(app.startTime, "startProcess: starting to update pids map");
4384        ProcessRecord oldApp;
4385        synchronized (mPidsSelfLocked) {
4386            oldApp = mPidsSelfLocked.get(pid);
4387        }
4388        // If there is already an app occupying that pid that hasn't been cleaned up
4389        if (oldApp != null && !app.isolated) {
4390            // Clean up anything relating to this pid first
4391            Slog.w(TAG, "Reusing pid " + pid
4392                    + " while app is still mapped to it");
4393            cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4394                    true /*replacingPid*/);
4395        }
4396        synchronized (mPidsSelfLocked) {
4397            this.mPidsSelfLocked.put(pid, app);
4398            if (!procAttached) {
4399                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4400                msg.obj = app;
4401                mHandler.sendMessageDelayed(msg, usingWrapper
4402                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4403            }
4404        }
4405        checkTime(app.startTime, "startProcess: done updating pids map");
4406        return true;
4407    }
4408
4409    void updateUsageStats(ActivityRecord component, boolean resumed) {
4410        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4411                "updateUsageStats: comp=" + component + "res=" + resumed);
4412        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4413        StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4414            component.app.uid, component.realActivity.getPackageName(),
4415            component.realActivity.getShortClassName(), resumed ?
4416                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_FOREGROUND :
4417                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_BACKGROUND);
4418        if (resumed) {
4419            if (mUsageStatsService != null) {
4420                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4421                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4422
4423            }
4424            synchronized (stats) {
4425                stats.noteActivityResumedLocked(component.app.uid);
4426            }
4427        } else {
4428            if (mUsageStatsService != null) {
4429                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4430                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4431            }
4432            synchronized (stats) {
4433                stats.noteActivityPausedLocked(component.app.uid);
4434            }
4435        }
4436    }
4437
4438    Intent getHomeIntent() {
4439        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4440        intent.setComponent(mTopComponent);
4441        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4442        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4443            intent.addCategory(Intent.CATEGORY_HOME);
4444        }
4445        return intent;
4446    }
4447
4448    boolean startHomeActivityLocked(int userId, String reason) {
4449        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4450                && mTopAction == null) {
4451            // We are running in factory test mode, but unable to find
4452            // the factory test app, so just sit around displaying the
4453            // error message and don't try to start anything.
4454            return false;
4455        }
4456        Intent intent = getHomeIntent();
4457        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4458        if (aInfo != null) {
4459            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4460            // Don't do this if the home app is currently being
4461            // instrumented.
4462            aInfo = new ActivityInfo(aInfo);
4463            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4464            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4465                    aInfo.applicationInfo.uid, true);
4466            if (app == null || app.instr == null) {
4467                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4468                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4469                // For ANR debugging to verify if the user activity is the one that actually
4470                // launched.
4471                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4472                mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4473            }
4474        } else {
4475            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4476        }
4477
4478        return true;
4479    }
4480
4481    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4482        ActivityInfo ai = null;
4483        ComponentName comp = intent.getComponent();
4484        try {
4485            if (comp != null) {
4486                // Factory test.
4487                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4488            } else {
4489                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4490                        intent,
4491                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4492                        flags, userId);
4493
4494                if (info != null) {
4495                    ai = info.activityInfo;
4496                }
4497            }
4498        } catch (RemoteException e) {
4499            // ignore
4500        }
4501
4502        return ai;
4503    }
4504
4505    boolean getCheckedForSetup() {
4506        return mCheckedForSetup;
4507    }
4508
4509    void setCheckedForSetup(boolean checked) {
4510        mCheckedForSetup = checked;
4511    }
4512
4513    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4514        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4515    }
4516
4517    void enforceNotIsolatedCaller(String caller) {
4518        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4519            throw new SecurityException("Isolated process not allowed to call " + caller);
4520        }
4521    }
4522
4523    @Override
4524    public int getFrontActivityScreenCompatMode() {
4525        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4526        synchronized (this) {
4527            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4528        }
4529    }
4530
4531    @Override
4532    public void setFrontActivityScreenCompatMode(int mode) {
4533        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4534                "setFrontActivityScreenCompatMode");
4535        synchronized (this) {
4536            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4537        }
4538    }
4539
4540    @Override
4541    public int getPackageScreenCompatMode(String packageName) {
4542        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4543        synchronized (this) {
4544            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4545        }
4546    }
4547
4548    @Override
4549    public void setPackageScreenCompatMode(String packageName, int mode) {
4550        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4551                "setPackageScreenCompatMode");
4552        synchronized (this) {
4553            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4554        }
4555    }
4556
4557    @Override
4558    public boolean getPackageAskScreenCompat(String packageName) {
4559        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4560        synchronized (this) {
4561            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4562        }
4563    }
4564
4565    @Override
4566    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4567        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4568                "setPackageAskScreenCompat");
4569        synchronized (this) {
4570            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4571        }
4572    }
4573
4574    private boolean hasUsageStatsPermission(String callingPackage) {
4575        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4576                Binder.getCallingUid(), callingPackage);
4577        if (mode == AppOpsManager.MODE_DEFAULT) {
4578            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4579                    == PackageManager.PERMISSION_GRANTED;
4580        }
4581        return mode == AppOpsManager.MODE_ALLOWED;
4582    }
4583
4584    @Override
4585    public int getPackageProcessState(String packageName, String callingPackage) {
4586        if (!hasUsageStatsPermission(callingPackage)) {
4587            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4588                    "getPackageProcessState");
4589        }
4590
4591        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4592        synchronized (this) {
4593            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4594                final ProcessRecord proc = mLruProcesses.get(i);
4595                if (procState > proc.setProcState) {
4596                    if (proc.pkgList.containsKey(packageName) ||
4597                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4598                        procState = proc.setProcState;
4599                    }
4600                }
4601            }
4602        }
4603        return procState;
4604    }
4605
4606    @Override
4607    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4608            throws RemoteException {
4609        synchronized (this) {
4610            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4611            if (app == null) {
4612                throw new IllegalArgumentException("Unknown process: " + process);
4613            }
4614            if (app.thread == null) {
4615                throw new IllegalArgumentException("Process has no app thread");
4616            }
4617            if (app.trimMemoryLevel >= level) {
4618                throw new IllegalArgumentException(
4619                        "Unable to set a higher trim level than current level");
4620            }
4621            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4622                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4623                throw new IllegalArgumentException("Unable to set a background trim level "
4624                    + "on a foreground process");
4625            }
4626            app.thread.scheduleTrimMemory(level);
4627            app.trimMemoryLevel = level;
4628            return true;
4629        }
4630    }
4631
4632    private void dispatchProcessesChanged() {
4633        int N;
4634        synchronized (this) {
4635            N = mPendingProcessChanges.size();
4636            if (mActiveProcessChanges.length < N) {
4637                mActiveProcessChanges = new ProcessChangeItem[N];
4638            }
4639            mPendingProcessChanges.toArray(mActiveProcessChanges);
4640            mPendingProcessChanges.clear();
4641            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4642                    "*** Delivering " + N + " process changes");
4643        }
4644
4645        int i = mProcessObservers.beginBroadcast();
4646        while (i > 0) {
4647            i--;
4648            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4649            if (observer != null) {
4650                try {
4651                    for (int j=0; j<N; j++) {
4652                        ProcessChangeItem item = mActiveProcessChanges[j];
4653                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4654                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4655                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4656                                    + item.uid + ": " + item.foregroundActivities);
4657                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4658                                    item.foregroundActivities);
4659                        }
4660                    }
4661                } catch (RemoteException e) {
4662                }
4663            }
4664        }
4665        mProcessObservers.finishBroadcast();
4666
4667        synchronized (this) {
4668            for (int j=0; j<N; j++) {
4669                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4670            }
4671        }
4672    }
4673
4674    private void dispatchProcessDied(int pid, int uid) {
4675        int i = mProcessObservers.beginBroadcast();
4676        while (i > 0) {
4677            i--;
4678            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4679            if (observer != null) {
4680                try {
4681                    observer.onProcessDied(pid, uid);
4682                } catch (RemoteException e) {
4683                }
4684            }
4685        }
4686        mProcessObservers.finishBroadcast();
4687    }
4688
4689    @VisibleForTesting
4690    void dispatchUidsChanged() {
4691        int N;
4692        synchronized (this) {
4693            N = mPendingUidChanges.size();
4694            if (mActiveUidChanges.length < N) {
4695                mActiveUidChanges = new UidRecord.ChangeItem[N];
4696            }
4697            for (int i=0; i<N; i++) {
4698                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4699                mActiveUidChanges[i] = change;
4700                if (change.uidRecord != null) {
4701                    change.uidRecord.pendingChange = null;
4702                    change.uidRecord = null;
4703                }
4704            }
4705            mPendingUidChanges.clear();
4706            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4707                    "*** Delivering " + N + " uid changes");
4708        }
4709
4710        int i = mUidObservers.beginBroadcast();
4711        while (i > 0) {
4712            i--;
4713            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4714                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4715        }
4716        mUidObservers.finishBroadcast();
4717
4718        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4719            for (int j = 0; j < N; ++j) {
4720                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4721                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4722                    mValidateUids.remove(item.uid);
4723                } else {
4724                    UidRecord validateUid = mValidateUids.get(item.uid);
4725                    if (validateUid == null) {
4726                        validateUid = new UidRecord(item.uid);
4727                        mValidateUids.put(item.uid, validateUid);
4728                    }
4729                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4730                        validateUid.idle = true;
4731                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4732                        validateUid.idle = false;
4733                    }
4734                    validateUid.curProcState = validateUid.setProcState = item.processState;
4735                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4736                }
4737            }
4738        }
4739
4740        synchronized (this) {
4741            for (int j = 0; j < N; j++) {
4742                mAvailUidChanges.add(mActiveUidChanges[j]);
4743            }
4744        }
4745    }
4746
4747    private void dispatchUidsChangedForObserver(IUidObserver observer,
4748            UidObserverRegistration reg, int changesSize) {
4749        if (observer == null) {
4750            return;
4751        }
4752        try {
4753            for (int j = 0; j < changesSize; j++) {
4754                UidRecord.ChangeItem item = mActiveUidChanges[j];
4755                final int change = item.change;
4756                if (change == UidRecord.CHANGE_PROCSTATE &&
4757                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4758                    // No-op common case: no significant change, the observer is not
4759                    // interested in all proc state changes.
4760                    continue;
4761                }
4762                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4763                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4764                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4765                                "UID idle uid=" + item.uid);
4766                        observer.onUidIdle(item.uid, item.ephemeral);
4767                    }
4768                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4769                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4770                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4771                                "UID active uid=" + item.uid);
4772                        observer.onUidActive(item.uid);
4773                    }
4774                }
4775                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4776                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4777                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4778                                "UID cached uid=" + item.uid);
4779                        observer.onUidCachedChanged(item.uid, true);
4780                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4781                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4782                                "UID active uid=" + item.uid);
4783                        observer.onUidCachedChanged(item.uid, false);
4784                    }
4785                }
4786                if ((change & UidRecord.CHANGE_GONE) != 0) {
4787                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4788                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4789                                "UID gone uid=" + item.uid);
4790                        observer.onUidGone(item.uid, item.ephemeral);
4791                    }
4792                    if (reg.lastProcStates != null) {
4793                        reg.lastProcStates.delete(item.uid);
4794                    }
4795                } else {
4796                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4797                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4798                                "UID CHANGED uid=" + item.uid
4799                                        + ": " + item.processState);
4800                        boolean doReport = true;
4801                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4802                            final int lastState = reg.lastProcStates.get(item.uid,
4803                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4804                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4805                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4806                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4807                                doReport = lastAboveCut != newAboveCut;
4808                            } else {
4809                                doReport = item.processState
4810                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4811                            }
4812                        }
4813                        if (doReport) {
4814                            if (reg.lastProcStates != null) {
4815                                reg.lastProcStates.put(item.uid, item.processState);
4816                            }
4817                            observer.onUidStateChanged(item.uid, item.processState,
4818                                    item.procStateSeq);
4819                        }
4820                    }
4821                }
4822            }
4823        } catch (RemoteException e) {
4824        }
4825    }
4826
4827    void dispatchOomAdjObserver(String msg) {
4828        OomAdjObserver observer;
4829        synchronized (this) {
4830            observer = mCurOomAdjObserver;
4831        }
4832
4833        if (observer != null) {
4834            observer.onOomAdjMessage(msg);
4835        }
4836    }
4837
4838    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4839        synchronized (this) {
4840            mCurOomAdjUid = uid;
4841            mCurOomAdjObserver = observer;
4842        }
4843    }
4844
4845    void clearOomAdjObserver() {
4846        synchronized (this) {
4847            mCurOomAdjUid = -1;
4848            mCurOomAdjObserver = null;
4849        }
4850    }
4851
4852    void reportOomAdjMessageLocked(String tag, String msg) {
4853        Slog.d(tag, msg);
4854        if (mCurOomAdjObserver != null) {
4855            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4856        }
4857    }
4858
4859    @Override
4860    public final int startActivity(IApplicationThread caller, String callingPackage,
4861            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4862            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4863        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4864                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4865                UserHandle.getCallingUserId());
4866    }
4867
4868    @Override
4869    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4870            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4871            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4872        enforceNotIsolatedCaller("startActivity");
4873        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4874                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4875        // TODO: Switch to user app stacks here.
4876        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
4877                .setCaller(caller)
4878                .setCallingPackage(callingPackage)
4879                .setResolvedType(resolvedType)
4880                .setResultTo(resultTo)
4881                .setResultWho(resultWho)
4882                .setRequestCode(requestCode)
4883                .setStartFlags(startFlags)
4884                .setProfilerInfo(profilerInfo)
4885                .setActivityOptions(bOptions)
4886                .setMayWait(userId)
4887                .execute();
4888
4889    }
4890
4891    @Override
4892    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4893            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4894            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4895            int userId) {
4896
4897        // This is very dangerous -- it allows you to perform a start activity (including
4898        // permission grants) as any app that may launch one of your own activities.  So
4899        // we will only allow this to be done from activities that are part of the core framework,
4900        // and then only when they are running as the system.
4901        final ActivityRecord sourceRecord;
4902        final int targetUid;
4903        final String targetPackage;
4904        synchronized (this) {
4905            if (resultTo == null) {
4906                throw new SecurityException("Must be called from an activity");
4907            }
4908            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4909            if (sourceRecord == null) {
4910                throw new SecurityException("Called with bad activity token: " + resultTo);
4911            }
4912            if (!sourceRecord.info.packageName.equals("android")) {
4913                throw new SecurityException(
4914                        "Must be called from an activity that is declared in the android package");
4915            }
4916            if (sourceRecord.app == null) {
4917                throw new SecurityException("Called without a process attached to activity");
4918            }
4919            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4920                // This is still okay, as long as this activity is running under the
4921                // uid of the original calling activity.
4922                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4923                    throw new SecurityException(
4924                            "Calling activity in uid " + sourceRecord.app.uid
4925                                    + " must be system uid or original calling uid "
4926                                    + sourceRecord.launchedFromUid);
4927                }
4928            }
4929            if (ignoreTargetSecurity) {
4930                if (intent.getComponent() == null) {
4931                    throw new SecurityException(
4932                            "Component must be specified with ignoreTargetSecurity");
4933                }
4934                if (intent.getSelector() != null) {
4935                    throw new SecurityException(
4936                            "Selector not allowed with ignoreTargetSecurity");
4937                }
4938            }
4939            targetUid = sourceRecord.launchedFromUid;
4940            targetPackage = sourceRecord.launchedFromPackage;
4941        }
4942
4943        if (userId == UserHandle.USER_NULL) {
4944            userId = UserHandle.getUserId(sourceRecord.app.uid);
4945        }
4946
4947        // TODO: Switch to user app stacks here.
4948        try {
4949            return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
4950                    .setCallingUid(targetUid)
4951                    .setCallingPackage(targetPackage)
4952                    .setResolvedType(resolvedType)
4953                    .setResultTo(resultTo)
4954                    .setResultWho(resultWho)
4955                    .setRequestCode(requestCode)
4956                    .setStartFlags(startFlags)
4957                    .setActivityOptions(bOptions)
4958                    .setMayWait(userId)
4959                    .setIgnoreTargetSecurity(ignoreTargetSecurity)
4960                    .execute();
4961        } catch (SecurityException e) {
4962            // XXX need to figure out how to propagate to original app.
4963            // A SecurityException here is generally actually a fault of the original
4964            // calling activity (such as a fairly granting permissions), so propagate it
4965            // back to them.
4966            /*
4967            StringBuilder msg = new StringBuilder();
4968            msg.append("While launching");
4969            msg.append(intent.toString());
4970            msg.append(": ");
4971            msg.append(e.getMessage());
4972            */
4973            throw e;
4974        }
4975    }
4976
4977    @Override
4978    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4979            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4980            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4981        enforceNotIsolatedCaller("startActivityAndWait");
4982        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4983                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4984        WaitResult res = new WaitResult();
4985        // TODO: Switch to user app stacks here.
4986        mActivityStartController.obtainStarter(intent, "startActivityAndWait")
4987                .setCaller(caller)
4988                .setCallingPackage(callingPackage)
4989                .setResolvedType(resolvedType)
4990                .setResultTo(resultTo)
4991                .setResultWho(resultWho)
4992                .setRequestCode(requestCode)
4993                .setStartFlags(startFlags)
4994                .setActivityOptions(bOptions)
4995                .setMayWait(userId)
4996                .setProfilerInfo(profilerInfo)
4997                .setWaitResult(res)
4998                .execute();
4999        return res;
5000    }
5001
5002    @Override
5003    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
5004            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5005            int startFlags, Configuration config, Bundle bOptions, int userId) {
5006        enforceNotIsolatedCaller("startActivityWithConfig");
5007        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5008                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
5009        // TODO: Switch to user app stacks here.
5010        return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
5011                .setCaller(caller)
5012                .setCallingPackage(callingPackage)
5013                .setResolvedType(resolvedType)
5014                .setResultTo(resultTo)
5015                .setResultWho(resultWho)
5016                .setRequestCode(requestCode)
5017                .setStartFlags(startFlags)
5018                .setGlobalConfiguration(config)
5019                .setActivityOptions(bOptions)
5020                .setMayWait(userId)
5021                .execute();
5022    }
5023
5024    @Override
5025    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
5026            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
5027            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
5028            throws TransactionTooLargeException {
5029        enforceNotIsolatedCaller("startActivityIntentSender");
5030        // Refuse possible leaked file descriptors
5031        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
5032            throw new IllegalArgumentException("File descriptors passed in Intent");
5033        }
5034
5035        if (!(target instanceof PendingIntentRecord)) {
5036            throw new IllegalArgumentException("Bad PendingIntent object");
5037        }
5038
5039        PendingIntentRecord pir = (PendingIntentRecord)target;
5040
5041        synchronized (this) {
5042            // If this is coming from the currently resumed activity, it is
5043            // effectively saying that app switches are allowed at this point.
5044            final ActivityStack stack = getFocusedStack();
5045            if (stack.mResumedActivity != null &&
5046                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
5047                mAppSwitchesAllowedTime = 0;
5048            }
5049        }
5050        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
5051                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
5052        return ret;
5053    }
5054
5055    @Override
5056    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
5057            Intent intent, String resolvedType, IVoiceInteractionSession session,
5058            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
5059            Bundle bOptions, int userId) {
5060        enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
5061        if (session == null || interactor == null) {
5062            throw new NullPointerException("null session or interactor");
5063        }
5064        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5065                ALLOW_FULL_ONLY, "startVoiceActivity", null);
5066        // TODO: Switch to user app stacks here.
5067        return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
5068                .setCallingUid(callingUid)
5069                .setCallingPackage(callingPackage)
5070                .setResolvedType(resolvedType)
5071                .setVoiceSession(session)
5072                .setVoiceInteractor(interactor)
5073                .setStartFlags(startFlags)
5074                .setProfilerInfo(profilerInfo)
5075                .setActivityOptions(bOptions)
5076                .setMayWait(userId)
5077                .execute();
5078    }
5079
5080    @Override
5081    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
5082            Intent intent, String resolvedType, Bundle bOptions, int userId) {
5083        enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
5084        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5085                ALLOW_FULL_ONLY, "startAssistantActivity", null);
5086
5087        return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
5088                .setCallingUid(callingUid)
5089                .setCallingPackage(callingPackage)
5090                .setResolvedType(resolvedType)
5091                .setActivityOptions(bOptions)
5092                .setMayWait(userId)
5093                .execute();
5094    }
5095
5096    @Override
5097    public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
5098                IRecentsAnimationRunner recentsAnimationRunner) {
5099        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
5100        final long origId = Binder.clearCallingIdentity();
5101        try {
5102            synchronized (this) {
5103                final int recentsUid = mRecentTasks.getRecentsComponentUid();
5104                final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
5105                final String recentsPackage = recentsComponent.getPackageName();
5106
5107                // If provided, kick off the request for the assist data in the background before
5108                // starting the activity
5109                if (assistDataReceiver != null) {
5110                    final AppOpsManager appOpsManager = (AppOpsManager)
5111                            mContext.getSystemService(Context.APP_OPS_SERVICE);
5112                    final AssistDataReceiverProxy proxy = new AssistDataReceiverProxy(
5113                            assistDataReceiver, recentsPackage);
5114                    final AssistDataRequester requester = new AssistDataRequester(mContext, this,
5115                            mWindowManager, appOpsManager, proxy, this,
5116                            OP_ASSIST_STRUCTURE, OP_NONE);
5117                    requester.requestAssistData(mStackSupervisor.getTopVisibleActivities(),
5118                            true /* fetchData */, false /* fetchScreenshots */,
5119                            true /* allowFetchData */, false /* alloweFetchScreenshots */,
5120                            recentsUid, recentsPackage);
5121                }
5122
5123                // Start a new recents animation
5124                final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
5125                        mActivityStartController, mWindowManager, mUserController);
5126                anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
5127                        recentsUid);
5128            }
5129        } finally {
5130            Binder.restoreCallingIdentity(origId);
5131        }
5132    }
5133
5134    @Override
5135    public void cancelRecentsAnimation() {
5136        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
5137        final long origId = Binder.clearCallingIdentity();
5138        try {
5139            synchronized (this) {
5140                mWindowManager.cancelRecentsAnimation();
5141            }
5142        } finally {
5143            Binder.restoreCallingIdentity(origId);
5144        }
5145    }
5146
5147    @Override
5148    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
5149            throws RemoteException {
5150        Slog.i(TAG, "Activity tried to startVoiceInteraction");
5151        synchronized (this) {
5152            ActivityRecord activity = getFocusedStack().getTopActivity();
5153            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
5154                throw new SecurityException("Only focused activity can call startVoiceInteraction");
5155            }
5156            if (mRunningVoice != null || activity.getTask().voiceSession != null
5157                    || activity.voiceSession != null) {
5158                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
5159                return;
5160            }
5161            if (activity.pendingVoiceInteractionStart) {
5162                Slog.w(TAG, "Pending start of voice interaction already.");
5163                return;
5164            }
5165            activity.pendingVoiceInteractionStart = true;
5166        }
5167        LocalServices.getService(VoiceInteractionManagerInternal.class)
5168                .startLocalVoiceInteraction(callingActivity, options);
5169    }
5170
5171    @Override
5172    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5173        LocalServices.getService(VoiceInteractionManagerInternal.class)
5174                .stopLocalVoiceInteraction(callingActivity);
5175    }
5176
5177    @Override
5178    public boolean supportsLocalVoiceInteraction() throws RemoteException {
5179        return LocalServices.getService(VoiceInteractionManagerInternal.class)
5180                .supportsLocalVoiceInteraction();
5181    }
5182
5183    @GuardedBy("this")
5184    void onLocalVoiceInteractionStartedLocked(IBinder activity,
5185            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5186        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
5187        if (activityToCallback == null) return;
5188        activityToCallback.setVoiceSessionLocked(voiceSession);
5189
5190        // Inform the activity
5191        try {
5192            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5193                    voiceInteractor);
5194            long token = Binder.clearCallingIdentity();
5195            try {
5196                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5197            } finally {
5198                Binder.restoreCallingIdentity(token);
5199            }
5200            // TODO: VI Should we cache the activity so that it's easier to find later
5201            // rather than scan through all the stacks and activities?
5202        } catch (RemoteException re) {
5203            activityToCallback.clearVoiceSessionLocked();
5204            // TODO: VI Should this terminate the voice session?
5205        }
5206    }
5207
5208    @Override
5209    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5210        synchronized (this) {
5211            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5212                if (keepAwake) {
5213                    mVoiceWakeLock.acquire();
5214                } else {
5215                    mVoiceWakeLock.release();
5216                }
5217            }
5218        }
5219    }
5220
5221    @Override
5222    public boolean startNextMatchingActivity(IBinder callingActivity,
5223            Intent intent, Bundle bOptions) {
5224        // Refuse possible leaked file descriptors
5225        if (intent != null && intent.hasFileDescriptors() == true) {
5226            throw new IllegalArgumentException("File descriptors passed in Intent");
5227        }
5228        SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5229
5230        synchronized (this) {
5231            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5232            if (r == null) {
5233                SafeActivityOptions.abort(options);
5234                return false;
5235            }
5236            if (r.app == null || r.app.thread == null) {
5237                // The caller is not running...  d'oh!
5238                SafeActivityOptions.abort(options);
5239                return false;
5240            }
5241            intent = new Intent(intent);
5242            // The caller is not allowed to change the data.
5243            intent.setDataAndType(r.intent.getData(), r.intent.getType());
5244            // And we are resetting to find the next component...
5245            intent.setComponent(null);
5246
5247            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5248
5249            ActivityInfo aInfo = null;
5250            try {
5251                List<ResolveInfo> resolves =
5252                    AppGlobals.getPackageManager().queryIntentActivities(
5253                            intent, r.resolvedType,
5254                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5255                            UserHandle.getCallingUserId()).getList();
5256
5257                // Look for the original activity in the list...
5258                final int N = resolves != null ? resolves.size() : 0;
5259                for (int i=0; i<N; i++) {
5260                    ResolveInfo rInfo = resolves.get(i);
5261                    if (rInfo.activityInfo.packageName.equals(r.packageName)
5262                            && rInfo.activityInfo.name.equals(r.info.name)) {
5263                        // We found the current one...  the next matching is
5264                        // after it.
5265                        i++;
5266                        if (i<N) {
5267                            aInfo = resolves.get(i).activityInfo;
5268                        }
5269                        if (debug) {
5270                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
5271                                    + "/" + r.info.name);
5272                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5273                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
5274                        }
5275                        break;
5276                    }
5277                }
5278            } catch (RemoteException e) {
5279            }
5280
5281            if (aInfo == null) {
5282                // Nobody who is next!
5283                SafeActivityOptions.abort(options);
5284                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5285                return false;
5286            }
5287
5288            intent.setComponent(new ComponentName(
5289                    aInfo.applicationInfo.packageName, aInfo.name));
5290            intent.setFlags(intent.getFlags()&~(
5291                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5292                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
5293                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5294                    FLAG_ACTIVITY_NEW_TASK));
5295
5296            // Okay now we need to start the new activity, replacing the
5297            // currently running activity.  This is a little tricky because
5298            // we want to start the new one as if the current one is finished,
5299            // but not finish the current one first so that there is no flicker.
5300            // And thus...
5301            final boolean wasFinishing = r.finishing;
5302            r.finishing = true;
5303
5304            // Propagate reply information over to the new activity.
5305            final ActivityRecord resultTo = r.resultTo;
5306            final String resultWho = r.resultWho;
5307            final int requestCode = r.requestCode;
5308            r.resultTo = null;
5309            if (resultTo != null) {
5310                resultTo.removeResultsLocked(r, resultWho, requestCode);
5311            }
5312
5313            final long origId = Binder.clearCallingIdentity();
5314            // TODO(b/64750076): Check if calling pid should really be -1.
5315            final int res = mActivityStartController
5316                    .obtainStarter(intent, "startNextMatchingActivity")
5317                    .setCaller(r.app.thread)
5318                    .setResolvedType(r.resolvedType)
5319                    .setActivityInfo(aInfo)
5320                    .setResultTo(resultTo != null ? resultTo.appToken : null)
5321                    .setResultWho(resultWho)
5322                    .setRequestCode(requestCode)
5323                    .setCallingPid(-1)
5324                    .setCallingUid(r.launchedFromUid)
5325                    .setCallingPackage(r.launchedFromPackage)
5326                    .setRealCallingPid(-1)
5327                    .setRealCallingUid(r.launchedFromUid)
5328                    .setActivityOptions(options)
5329                    .execute();
5330            Binder.restoreCallingIdentity(origId);
5331
5332            r.finishing = wasFinishing;
5333            if (res != ActivityManager.START_SUCCESS) {
5334                return false;
5335            }
5336            return true;
5337        }
5338    }
5339
5340    @Override
5341    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5342        enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5343                "startActivityFromRecents()");
5344
5345        final int callingPid = Binder.getCallingPid();
5346        final int callingUid = Binder.getCallingUid();
5347        final long origId = Binder.clearCallingIdentity();
5348        try {
5349            synchronized (this) {
5350                return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5351                        SafeActivityOptions.fromBundle(bOptions));
5352            }
5353        } finally {
5354            Binder.restoreCallingIdentity(origId);
5355        }
5356    }
5357
5358    @Override
5359    public final int startActivities(IApplicationThread caller, String callingPackage,
5360            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5361            int userId) {
5362        final String reason = "startActivities";
5363        enforceNotIsolatedCaller(reason);
5364        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5365                userId, false, ALLOW_FULL_ONLY, reason, null);
5366        // TODO: Switch to user app stacks here.
5367        int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
5368                intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
5369                reason);
5370        return ret;
5371    }
5372
5373    @Override
5374    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5375        synchronized (this) {
5376            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5377            if (r == null) {
5378                return;
5379            }
5380            r.reportFullyDrawnLocked(restoredFromBundle);
5381        }
5382    }
5383
5384    @Override
5385    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5386        synchronized (this) {
5387            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5388            if (r == null) {
5389                return;
5390            }
5391            final long origId = Binder.clearCallingIdentity();
5392            try {
5393                r.setRequestedOrientation(requestedOrientation);
5394            } finally {
5395                Binder.restoreCallingIdentity(origId);
5396            }
5397        }
5398    }
5399
5400    @Override
5401    public int getRequestedOrientation(IBinder token) {
5402        synchronized (this) {
5403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5404            if (r == null) {
5405                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5406            }
5407            return r.getRequestedOrientation();
5408        }
5409    }
5410
5411    @Override
5412    public final void requestActivityRelaunch(IBinder token) {
5413        synchronized(this) {
5414            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5415            if (r == null) {
5416                return;
5417            }
5418            final long origId = Binder.clearCallingIdentity();
5419            try {
5420                r.forceNewConfig = true;
5421                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5422                        true /* preserveWindow */);
5423            } finally {
5424                Binder.restoreCallingIdentity(origId);
5425            }
5426        }
5427    }
5428
5429    /**
5430     * This is the internal entry point for handling Activity.finish().
5431     *
5432     * @param token The Binder token referencing the Activity we want to finish.
5433     * @param resultCode Result code, if any, from this Activity.
5434     * @param resultData Result data (Intent), if any, from this Activity.
5435     * @param finishTask Whether to finish the task associated with this Activity.
5436     *
5437     * @return Returns true if the activity successfully finished, or false if it is still running.
5438     */
5439    @Override
5440    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5441            int finishTask) {
5442        // Refuse possible leaked file descriptors
5443        if (resultData != null && resultData.hasFileDescriptors() == true) {
5444            throw new IllegalArgumentException("File descriptors passed in Intent");
5445        }
5446
5447        synchronized(this) {
5448            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5449            if (r == null) {
5450                return true;
5451            }
5452            // Keep track of the root activity of the task before we finish it
5453            TaskRecord tr = r.getTask();
5454            ActivityRecord rootR = tr.getRootActivity();
5455            if (rootR == null) {
5456                Slog.w(TAG, "Finishing task with all activities already finished");
5457            }
5458            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5459            // finish.
5460            if (mLockTaskController.activityBlockedFromFinish(r)) {
5461                return false;
5462            }
5463
5464            if (mController != null) {
5465                // Find the first activity that is not finishing.
5466                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5467                if (next != null) {
5468                    // ask watcher if this is allowed
5469                    boolean resumeOK = true;
5470                    try {
5471                        resumeOK = mController.activityResuming(next.packageName);
5472                    } catch (RemoteException e) {
5473                        mController = null;
5474                        Watchdog.getInstance().setActivityController(null);
5475                    }
5476
5477                    if (!resumeOK) {
5478                        Slog.i(TAG, "Not finishing activity because controller resumed");
5479                        return false;
5480                    }
5481                }
5482            }
5483            final long origId = Binder.clearCallingIdentity();
5484            try {
5485                boolean res;
5486                final boolean finishWithRootActivity =
5487                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5488                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5489                        || (finishWithRootActivity && r == rootR)) {
5490                    // If requested, remove the task that is associated to this activity only if it
5491                    // was the root activity in the task. The result code and data is ignored
5492                    // because we don't support returning them across task boundaries. Also, to
5493                    // keep backwards compatibility we remove the task from recents when finishing
5494                    // task with root activity.
5495                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5496                            finishWithRootActivity, "finish-activity");
5497                    if (!res) {
5498                        Slog.i(TAG, "Removing task failed to finish activity");
5499                    }
5500                } else {
5501                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5502                            resultData, "app-request", true);
5503                    if (!res) {
5504                        Slog.i(TAG, "Failed to finish by app-request");
5505                    }
5506                }
5507                return res;
5508            } finally {
5509                Binder.restoreCallingIdentity(origId);
5510            }
5511        }
5512    }
5513
5514    @Override
5515    public final void finishHeavyWeightApp() {
5516        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5517                != PackageManager.PERMISSION_GRANTED) {
5518            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5519                    + Binder.getCallingPid()
5520                    + ", uid=" + Binder.getCallingUid()
5521                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5522            Slog.w(TAG, msg);
5523            throw new SecurityException(msg);
5524        }
5525
5526        synchronized(this) {
5527            final ProcessRecord proc = mHeavyWeightProcess;
5528            if (proc == null) {
5529                return;
5530            }
5531
5532            ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5533            for (int i = 0; i < activities.size(); i++) {
5534                ActivityRecord r = activities.get(i);
5535                if (!r.finishing && r.isInStackLocked()) {
5536                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5537                            null, "finish-heavy", true);
5538                }
5539            }
5540
5541            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5542                    proc.userId, 0));
5543            mHeavyWeightProcess = null;
5544        }
5545    }
5546
5547    @Override
5548    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5549            String message) {
5550        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5551                != PackageManager.PERMISSION_GRANTED) {
5552            String msg = "Permission Denial: crashApplication() from pid="
5553                    + Binder.getCallingPid()
5554                    + ", uid=" + Binder.getCallingUid()
5555                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5556            Slog.w(TAG, msg);
5557            throw new SecurityException(msg);
5558        }
5559
5560        synchronized(this) {
5561            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5562        }
5563    }
5564
5565    @Override
5566    public final void finishSubActivity(IBinder token, String resultWho,
5567            int requestCode) {
5568        synchronized(this) {
5569            final long origId = Binder.clearCallingIdentity();
5570            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5571            if (r != null) {
5572                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5573            }
5574            Binder.restoreCallingIdentity(origId);
5575        }
5576    }
5577
5578    @Override
5579    public boolean finishActivityAffinity(IBinder token) {
5580        synchronized(this) {
5581            final long origId = Binder.clearCallingIdentity();
5582            try {
5583                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5584                if (r == null) {
5585                    return false;
5586                }
5587
5588                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5589                // can finish.
5590                final TaskRecord task = r.getTask();
5591                if (mLockTaskController.activityBlockedFromFinish(r)) {
5592                    return false;
5593                }
5594                return task.getStack().finishActivityAffinityLocked(r);
5595            } finally {
5596                Binder.restoreCallingIdentity(origId);
5597            }
5598        }
5599    }
5600
5601    @Override
5602    public void finishVoiceTask(IVoiceInteractionSession session) {
5603        synchronized (this) {
5604            final long origId = Binder.clearCallingIdentity();
5605            try {
5606                // TODO: VI Consider treating local voice interactions and voice tasks
5607                // differently here
5608                mStackSupervisor.finishVoiceTask(session);
5609            } finally {
5610                Binder.restoreCallingIdentity(origId);
5611            }
5612        }
5613
5614    }
5615
5616    @Override
5617    public boolean releaseActivityInstance(IBinder token) {
5618        synchronized(this) {
5619            final long origId = Binder.clearCallingIdentity();
5620            try {
5621                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5622                if (r == null) {
5623                    return false;
5624                }
5625                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5626            } finally {
5627                Binder.restoreCallingIdentity(origId);
5628            }
5629        }
5630    }
5631
5632    @Override
5633    public void releaseSomeActivities(IApplicationThread appInt) {
5634        synchronized(this) {
5635            final long origId = Binder.clearCallingIdentity();
5636            try {
5637                ProcessRecord app = getRecordForAppLocked(appInt);
5638                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5639            } finally {
5640                Binder.restoreCallingIdentity(origId);
5641            }
5642        }
5643    }
5644
5645    @Override
5646    public boolean willActivityBeVisible(IBinder token) {
5647        synchronized(this) {
5648            ActivityStack stack = ActivityRecord.getStackLocked(token);
5649            if (stack != null) {
5650                return stack.willActivityBeVisibleLocked(token);
5651            }
5652            return false;
5653        }
5654    }
5655
5656    @Override
5657    public void overridePendingTransition(IBinder token, String packageName,
5658            int enterAnim, int exitAnim) {
5659        synchronized(this) {
5660            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5661            if (self == null) {
5662                return;
5663            }
5664
5665            final long origId = Binder.clearCallingIdentity();
5666
5667            if (self.state == ActivityState.RESUMED
5668                    || self.state == ActivityState.PAUSING) {
5669                mWindowManager.overridePendingAppTransition(packageName,
5670                        enterAnim, exitAnim, null);
5671            }
5672
5673            Binder.restoreCallingIdentity(origId);
5674        }
5675    }
5676
5677    /**
5678     * Main function for removing an existing process from the activity manager
5679     * as a result of that process going away.  Clears out all connections
5680     * to the process.
5681     */
5682    @GuardedBy("this")
5683    private final void handleAppDiedLocked(ProcessRecord app,
5684            boolean restarting, boolean allowRestart) {
5685        int pid = app.pid;
5686        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5687                false /*replacingPid*/);
5688        if (!kept && !restarting) {
5689            removeLruProcessLocked(app);
5690            if (pid > 0) {
5691                ProcessList.remove(pid);
5692            }
5693        }
5694
5695        if (mProfileProc == app) {
5696            clearProfilerLocked();
5697        }
5698
5699        // Remove this application's activities from active lists.
5700        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5701
5702        app.clearRecentTasks();
5703
5704        app.activities.clear();
5705
5706        if (app.instr != null) {
5707            Slog.w(TAG, "Crash of app " + app.processName
5708                  + " running instrumentation " + app.instr.mClass);
5709            Bundle info = new Bundle();
5710            info.putString("shortMsg", "Process crashed.");
5711            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5712        }
5713
5714        mWindowManager.deferSurfaceLayout();
5715        try {
5716            if (!restarting && hasVisibleActivities
5717                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5718                // If there was nothing to resume, and we are not already restarting this process, but
5719                // there is a visible activity that is hosted by the process...  then make sure all
5720                // visible activities are running, taking care of restarting this process.
5721                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5722            }
5723        } finally {
5724            mWindowManager.continueSurfaceLayout();
5725        }
5726    }
5727
5728    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5729        final IBinder threadBinder = thread.asBinder();
5730        // Find the application record.
5731        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5732            final ProcessRecord rec = mLruProcesses.get(i);
5733            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5734                return i;
5735            }
5736        }
5737        return -1;
5738    }
5739
5740    ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5741        if (thread == null) {
5742            return null;
5743        }
5744
5745        int appIndex = getLRURecordIndexForAppLocked(thread);
5746        if (appIndex >= 0) {
5747            return mLruProcesses.get(appIndex);
5748        }
5749
5750        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5751        // double-check that.
5752        final IBinder threadBinder = thread.asBinder();
5753        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5754        for (int i = pmap.size()-1; i >= 0; i--) {
5755            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5756            for (int j = procs.size()-1; j >= 0; j--) {
5757                final ProcessRecord proc = procs.valueAt(j);
5758                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5759                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5760                            + proc);
5761                    return proc;
5762                }
5763            }
5764        }
5765
5766        return null;
5767    }
5768
5769    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5770        // If there are no longer any background processes running,
5771        // and the app that died was not running instrumentation,
5772        // then tell everyone we are now low on memory.
5773        boolean haveBg = false;
5774        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5775            ProcessRecord rec = mLruProcesses.get(i);
5776            if (rec.thread != null
5777                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5778                haveBg = true;
5779                break;
5780            }
5781        }
5782
5783        if (!haveBg) {
5784            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5785            if (doReport) {
5786                long now = SystemClock.uptimeMillis();
5787                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5788                    doReport = false;
5789                } else {
5790                    mLastMemUsageReportTime = now;
5791                }
5792            }
5793            final ArrayList<ProcessMemInfo> memInfos
5794                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5795            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5796            long now = SystemClock.uptimeMillis();
5797            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5798                ProcessRecord rec = mLruProcesses.get(i);
5799                if (rec == dyingProc || rec.thread == null) {
5800                    continue;
5801                }
5802                if (doReport) {
5803                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5804                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5805                }
5806                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5807                    // The low memory report is overriding any current
5808                    // state for a GC request.  Make sure to do
5809                    // heavy/important/visible/foreground processes first.
5810                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5811                        rec.lastRequestedGc = 0;
5812                    } else {
5813                        rec.lastRequestedGc = rec.lastLowMemory;
5814                    }
5815                    rec.reportLowMemory = true;
5816                    rec.lastLowMemory = now;
5817                    mProcessesToGc.remove(rec);
5818                    addProcessToGcListLocked(rec);
5819                }
5820            }
5821            if (doReport) {
5822                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5823                mHandler.sendMessage(msg);
5824            }
5825            scheduleAppGcsLocked();
5826        }
5827    }
5828
5829    @GuardedBy("this")
5830    final void appDiedLocked(ProcessRecord app) {
5831       appDiedLocked(app, app.pid, app.thread, false);
5832    }
5833
5834    @GuardedBy("this")
5835    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5836            boolean fromBinderDied) {
5837        // First check if this ProcessRecord is actually active for the pid.
5838        synchronized (mPidsSelfLocked) {
5839            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5840            if (curProc != app) {
5841                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5842                return;
5843            }
5844        }
5845
5846        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5847        synchronized (stats) {
5848            stats.noteProcessDiedLocked(app.info.uid, pid);
5849        }
5850
5851        if (!app.killed) {
5852            if (!fromBinderDied) {
5853                killProcessQuiet(pid);
5854            }
5855            killProcessGroup(app.uid, pid);
5856            app.killed = true;
5857        }
5858
5859        // Clean up already done if the process has been re-started.
5860        if (app.pid == pid && app.thread != null &&
5861                app.thread.asBinder() == thread.asBinder()) {
5862            boolean doLowMem = app.instr == null;
5863            boolean doOomAdj = doLowMem;
5864            if (!app.killedByAm) {
5865                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5866                        + ProcessList.makeOomAdjString(app.setAdj)
5867                        + ProcessList.makeProcStateString(app.setProcState));
5868                mAllowLowerMemLevel = true;
5869            } else {
5870                // Note that we always want to do oom adj to update our state with the
5871                // new number of procs.
5872                mAllowLowerMemLevel = false;
5873                doLowMem = false;
5874            }
5875            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5876                    app.setAdj, app.setProcState);
5877            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5878                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5879            handleAppDiedLocked(app, false, true);
5880
5881            if (doOomAdj) {
5882                updateOomAdjLocked();
5883            }
5884            if (doLowMem) {
5885                doLowMemReportIfNeededLocked(app);
5886            }
5887        } else if (app.pid != pid) {
5888            // A new process has already been started.
5889            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5890                    + ") has died and restarted (pid " + app.pid + ").");
5891            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5892        } else if (DEBUG_PROCESSES) {
5893            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5894                    + thread.asBinder());
5895        }
5896    }
5897
5898    /**
5899     * If a stack trace dump file is configured, dump process stack traces.
5900     * @param clearTraces causes the dump file to be erased prior to the new
5901     *    traces being written, if true; when false, the new traces will be
5902     *    appended to any existing file content.
5903     * @param firstPids of dalvik VM processes to dump stack traces for first
5904     * @param lastPids of dalvik VM processes to dump stack traces for last
5905     * @param nativePids optional list of native pids to dump stack crawls
5906     */
5907    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5908            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5909            ArrayList<Integer> nativePids) {
5910        ArrayList<Integer> extraPids = null;
5911
5912        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5913        // of the top users at the time of the request.
5914        if (processCpuTracker != null) {
5915            processCpuTracker.init();
5916            try {
5917                Thread.sleep(200);
5918            } catch (InterruptedException ignored) {
5919            }
5920
5921            processCpuTracker.update();
5922
5923            // We'll take the stack crawls of just the top apps using CPU.
5924            final int N = processCpuTracker.countWorkingStats();
5925            extraPids = new ArrayList<>();
5926            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5927                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5928                if (lastPids.indexOfKey(stats.pid) >= 0) {
5929                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5930
5931                    extraPids.add(stats.pid);
5932                } else if (DEBUG_ANR) {
5933                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5934                            + stats.pid);
5935                }
5936            }
5937        }
5938
5939        boolean useTombstonedForJavaTraces = false;
5940        File tracesFile;
5941
5942        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5943        if (tracesDirProp.isEmpty()) {
5944            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5945            // dumping scheme. All traces are written to a global trace file (usually
5946            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5947            // the file if requested.
5948            //
5949            // This mode of operation will be removed in the near future.
5950
5951
5952            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5953            if (globalTracesPath.isEmpty()) {
5954                Slog.w(TAG, "dumpStackTraces: no trace path configured");
5955                return null;
5956            }
5957
5958            tracesFile = new File(globalTracesPath);
5959            try {
5960                if (clearTraces && tracesFile.exists()) {
5961                    tracesFile.delete();
5962                }
5963
5964                tracesFile.createNewFile();
5965                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5966            } catch (IOException e) {
5967                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5968                return null;
5969            }
5970        } else {
5971            File tracesDir = new File(tracesDirProp);
5972            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5973            // Each set of ANR traces is written to a separate file and dumpstate will process
5974            // all such files and add them to a captured bug report if they're recent enough.
5975            maybePruneOldTraces(tracesDir);
5976
5977            // NOTE: We should consider creating the file in native code atomically once we've
5978            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5979            // can be removed.
5980            tracesFile = createAnrDumpFile(tracesDir);
5981            if (tracesFile == null) {
5982                return null;
5983            }
5984
5985            useTombstonedForJavaTraces = true;
5986        }
5987
5988        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5989                useTombstonedForJavaTraces);
5990        return tracesFile;
5991    }
5992
5993    @GuardedBy("ActivityManagerService.class")
5994    private static SimpleDateFormat sAnrFileDateFormat;
5995
5996    private static synchronized File createAnrDumpFile(File tracesDir) {
5997        if (sAnrFileDateFormat == null) {
5998            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5999        }
6000
6001        final String formattedDate = sAnrFileDateFormat.format(new Date());
6002        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
6003
6004        try {
6005            if (anrFile.createNewFile()) {
6006                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
6007                return anrFile;
6008            } else {
6009                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
6010            }
6011        } catch (IOException ioe) {
6012            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
6013        }
6014
6015        return null;
6016    }
6017
6018    /**
6019     * Prune all trace files that are more than a day old.
6020     *
6021     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
6022     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
6023     * since it's the system_server that creates trace files for most ANRs.
6024     */
6025    private static void maybePruneOldTraces(File tracesDir) {
6026        final long now = System.currentTimeMillis();
6027        final File[] traceFiles = tracesDir.listFiles();
6028
6029        if (traceFiles != null) {
6030            for (File file : traceFiles) {
6031                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
6032                    if (!file.delete()) {
6033                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
6034                    }
6035                }
6036            }
6037        }
6038    }
6039
6040    /**
6041     * Legacy code, do not use. Existing users will be deleted.
6042     *
6043     * @deprecated
6044     */
6045    @Deprecated
6046    public static class DumpStackFileObserver extends FileObserver {
6047        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
6048        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
6049
6050        private final String mTracesPath;
6051        private boolean mClosed;
6052
6053        public DumpStackFileObserver(String tracesPath) {
6054            super(tracesPath, FileObserver.CLOSE_WRITE);
6055            mTracesPath = tracesPath;
6056        }
6057
6058        @Override
6059        public synchronized void onEvent(int event, String path) {
6060            mClosed = true;
6061            notify();
6062        }
6063
6064        public long dumpWithTimeout(int pid, long timeout) {
6065            sendSignal(pid, SIGNAL_QUIT);
6066            final long start = SystemClock.elapsedRealtime();
6067
6068            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
6069            synchronized (this) {
6070                try {
6071                    wait(waitTime); // Wait for traces file to be closed.
6072                } catch (InterruptedException e) {
6073                    Slog.wtf(TAG, e);
6074                }
6075            }
6076
6077            // This avoids a corner case of passing a negative time to the native
6078            // trace in case we've already hit the overall timeout.
6079            final long timeWaited = SystemClock.elapsedRealtime() - start;
6080            if (timeWaited >= timeout) {
6081                return timeWaited;
6082            }
6083
6084            if (!mClosed) {
6085                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
6086                       ". Attempting native stack collection.");
6087
6088                final long nativeDumpTimeoutMs = Math.min(
6089                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
6090
6091                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
6092                        (int) (nativeDumpTimeoutMs / 1000));
6093            }
6094
6095            final long end = SystemClock.elapsedRealtime();
6096            mClosed = false;
6097
6098            return (end - start);
6099        }
6100    }
6101
6102    /**
6103     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
6104     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
6105     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
6106     * attempting to obtain native traces in the case of a failure. Returns the total time spent
6107     * capturing traces.
6108     */
6109    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
6110        final long timeStart = SystemClock.elapsedRealtime();
6111        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
6112            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
6113                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
6114        }
6115
6116        return SystemClock.elapsedRealtime() - timeStart;
6117    }
6118
6119    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6120            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6121            boolean useTombstonedForJavaTraces) {
6122
6123        // We don't need any sort of inotify based monitoring when we're dumping traces via
6124        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
6125        // control of all writes to the file in question.
6126        final DumpStackFileObserver observer;
6127        if (useTombstonedForJavaTraces) {
6128            observer = null;
6129        } else {
6130            // Use a FileObserver to detect when traces finish writing.
6131            // The order of traces is considered important to maintain for legibility.
6132            observer = new DumpStackFileObserver(tracesFile);
6133        }
6134
6135        // We must complete all stack dumps within 20 seconds.
6136        long remainingTime = 20 * 1000;
6137        try {
6138            if (observer != null) {
6139                observer.startWatching();
6140            }
6141
6142            // First collect all of the stacks of the most important pids.
6143            if (firstPids != null) {
6144                int num = firstPids.size();
6145                for (int i = 0; i < num; i++) {
6146                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
6147                            + firstPids.get(i));
6148                    final long timeTaken;
6149                    if (useTombstonedForJavaTraces) {
6150                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
6151                    } else {
6152                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6153                    }
6154
6155                    remainingTime -= timeTaken;
6156                    if (remainingTime <= 0) {
6157                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6158                            "); deadline exceeded.");
6159                        return;
6160                    }
6161
6162                    if (DEBUG_ANR) {
6163                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
6164                    }
6165                }
6166            }
6167
6168            // Next collect the stacks of the native pids
6169            if (nativePids != null) {
6170                for (int pid : nativePids) {
6171                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
6172                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
6173
6174                    final long start = SystemClock.elapsedRealtime();
6175                    Debug.dumpNativeBacktraceToFileTimeout(
6176                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6177                    final long timeTaken = SystemClock.elapsedRealtime() - start;
6178
6179                    remainingTime -= timeTaken;
6180                    if (remainingTime <= 0) {
6181                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6182                            "); deadline exceeded.");
6183                        return;
6184                    }
6185
6186                    if (DEBUG_ANR) {
6187                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
6188                    }
6189                }
6190            }
6191
6192            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
6193            if (extraPids != null) {
6194                for (int pid : extraPids) {
6195                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6196
6197                    final long timeTaken;
6198                    if (useTombstonedForJavaTraces) {
6199                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6200                    } else {
6201                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6202                    }
6203
6204                    remainingTime -= timeTaken;
6205                    if (remainingTime <= 0) {
6206                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6207                                "); deadline exceeded.");
6208                        return;
6209                    }
6210
6211                    if (DEBUG_ANR) {
6212                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6213                    }
6214                }
6215            }
6216        } finally {
6217            if (observer != null) {
6218                observer.stopWatching();
6219            }
6220        }
6221    }
6222
6223    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6224        if (true || Build.IS_USER) {
6225            return;
6226        }
6227        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6228        if (tracesPath == null || tracesPath.length() == 0) {
6229            return;
6230        }
6231
6232        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6233        StrictMode.allowThreadDiskWrites();
6234        try {
6235            final File tracesFile = new File(tracesPath);
6236            final File tracesDir = tracesFile.getParentFile();
6237            final File tracesTmp = new File(tracesDir, "__tmp__");
6238            try {
6239                if (tracesFile.exists()) {
6240                    tracesTmp.delete();
6241                    tracesFile.renameTo(tracesTmp);
6242                }
6243                StringBuilder sb = new StringBuilder();
6244                Time tobj = new Time();
6245                tobj.set(System.currentTimeMillis());
6246                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6247                sb.append(": ");
6248                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6249                sb.append(" since ");
6250                sb.append(msg);
6251                FileOutputStream fos = new FileOutputStream(tracesFile);
6252                fos.write(sb.toString().getBytes());
6253                if (app == null) {
6254                    fos.write("\n*** No application process!".getBytes());
6255                }
6256                fos.close();
6257                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6258            } catch (IOException e) {
6259                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6260                return;
6261            }
6262
6263            if (app != null && app.pid > 0) {
6264                ArrayList<Integer> firstPids = new ArrayList<Integer>();
6265                firstPids.add(app.pid);
6266                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6267            }
6268
6269            File lastTracesFile = null;
6270            File curTracesFile = null;
6271            for (int i=9; i>=0; i--) {
6272                String name = String.format(Locale.US, "slow%02d.txt", i);
6273                curTracesFile = new File(tracesDir, name);
6274                if (curTracesFile.exists()) {
6275                    if (lastTracesFile != null) {
6276                        curTracesFile.renameTo(lastTracesFile);
6277                    } else {
6278                        curTracesFile.delete();
6279                    }
6280                }
6281                lastTracesFile = curTracesFile;
6282            }
6283            tracesFile.renameTo(curTracesFile);
6284            if (tracesTmp.exists()) {
6285                tracesTmp.renameTo(tracesFile);
6286            }
6287        } finally {
6288            StrictMode.setThreadPolicy(oldPolicy);
6289        }
6290    }
6291
6292    @GuardedBy("this")
6293    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6294        if (!mLaunchWarningShown) {
6295            mLaunchWarningShown = true;
6296            mUiHandler.post(new Runnable() {
6297                @Override
6298                public void run() {
6299                    synchronized (ActivityManagerService.this) {
6300                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6301                        d.show();
6302                        mUiHandler.postDelayed(new Runnable() {
6303                            @Override
6304                            public void run() {
6305                                synchronized (ActivityManagerService.this) {
6306                                    d.dismiss();
6307                                    mLaunchWarningShown = false;
6308                                }
6309                            }
6310                        }, 4000);
6311                    }
6312                }
6313            });
6314        }
6315    }
6316
6317    @Override
6318    public boolean clearApplicationUserData(final String packageName, boolean keepState,
6319            final IPackageDataObserver observer, int userId) {
6320        enforceNotIsolatedCaller("clearApplicationUserData");
6321        int uid = Binder.getCallingUid();
6322        int pid = Binder.getCallingPid();
6323        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6324                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6325
6326        final ApplicationInfo appInfo;
6327        final boolean isInstantApp;
6328
6329        long callingId = Binder.clearCallingIdentity();
6330        try {
6331            IPackageManager pm = AppGlobals.getPackageManager();
6332            synchronized(this) {
6333                // Instant packages are not protected
6334                if (getPackageManagerInternalLocked().isPackageDataProtected(
6335                        resolvedUserId, packageName)) {
6336                    throw new SecurityException(
6337                            "Cannot clear data for a protected package: " + packageName);
6338                }
6339
6340                ApplicationInfo applicationInfo = null;
6341                try {
6342                    applicationInfo = pm.getApplicationInfo(packageName,
6343                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6344                } catch (RemoteException e) {
6345                    /* ignore */
6346                }
6347                appInfo = applicationInfo;
6348
6349                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6350
6351                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6352                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6353                    throw new SecurityException("PID " + pid + " does not have permission "
6354                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6355                            + " of package " + packageName);
6356                }
6357
6358                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6359                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
6360                final boolean isUninstalledAppWithoutInstantMetadata =
6361                        (appInfo == null && !hasInstantMetadata);
6362                isInstantApp = (appInfo != null && appInfo.isInstantApp())
6363                        || hasInstantMetadata;
6364                final boolean canAccessInstantApps = checkComponentPermission(
6365                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6366                        == PackageManager.PERMISSION_GRANTED;
6367
6368                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6369                        && !canAccessInstantApps)) {
6370                    Slog.w(TAG, "Invalid packageName: " + packageName);
6371                    if (observer != null) {
6372                        try {
6373                            observer.onRemoveCompleted(packageName, false);
6374                        } catch (RemoteException e) {
6375                            Slog.i(TAG, "Observer no longer exists.");
6376                        }
6377                    }
6378                    return false;
6379                }
6380
6381                if (appInfo != null) {
6382                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6383                    mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6384                }
6385            }
6386
6387            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6388                @Override
6389                public void onRemoveCompleted(String packageName, boolean succeeded)
6390                        throws RemoteException {
6391                    if (appInfo != null) {
6392                        synchronized (ActivityManagerService.this) {
6393                            finishForceStopPackageLocked(packageName, appInfo.uid);
6394                        }
6395                    }
6396                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6397                            Uri.fromParts("package", packageName, null));
6398                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6399                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6400                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6401                    if (isInstantApp) {
6402                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6403                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6404                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6405                                resolvedUserId);
6406                    } else {
6407                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6408                                null, null, null, null, false, false, resolvedUserId);
6409                    }
6410
6411                    if (observer != null) {
6412                        observer.onRemoveCompleted(packageName, succeeded);
6413                    }
6414                }
6415            };
6416
6417            try {
6418                // Clear application user data
6419                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6420
6421                if (appInfo != null) {
6422                    // Restore already established notification state and permission grants,
6423                    // so it told us to keep those intact -- it's about to emplace app data
6424                    // that is appropriate for those bits of system state.
6425                    if (!keepState) {
6426                        synchronized (this) {
6427                            // Remove all permissions granted from/to this package
6428                            removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
6429                                    false);
6430                        }
6431
6432                        // Reset notification state
6433                        INotificationManager inm = NotificationManager.getService();
6434                        inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6435                    }
6436
6437                    // Clear its scheduled jobs
6438                    JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6439                    js.cancelJobsForUid(appInfo.uid, "clear data");
6440
6441                    // Clear its pending alarms
6442                    AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6443                    ami.removeAlarmsForUid(appInfo.uid);
6444                }
6445            } catch (RemoteException e) {
6446            }
6447        } finally {
6448            Binder.restoreCallingIdentity(callingId);
6449        }
6450        return true;
6451    }
6452
6453    @Override
6454    public void killBackgroundProcesses(final String packageName, int userId) {
6455        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6456                != PackageManager.PERMISSION_GRANTED &&
6457                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6458                        != PackageManager.PERMISSION_GRANTED) {
6459            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6460                    + Binder.getCallingPid()
6461                    + ", uid=" + Binder.getCallingUid()
6462                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6463            Slog.w(TAG, msg);
6464            throw new SecurityException(msg);
6465        }
6466
6467        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6468                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6469        long callingId = Binder.clearCallingIdentity();
6470        try {
6471            IPackageManager pm = AppGlobals.getPackageManager();
6472            synchronized(this) {
6473                int appId = -1;
6474                try {
6475                    appId = UserHandle.getAppId(
6476                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6477                } catch (RemoteException e) {
6478                }
6479                if (appId == -1) {
6480                    Slog.w(TAG, "Invalid packageName: " + packageName);
6481                    return;
6482                }
6483                killPackageProcessesLocked(packageName, appId, userId,
6484                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6485            }
6486        } finally {
6487            Binder.restoreCallingIdentity(callingId);
6488        }
6489    }
6490
6491    @Override
6492    public void killAllBackgroundProcesses() {
6493        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6494                != PackageManager.PERMISSION_GRANTED) {
6495            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6496                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6497                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6498            Slog.w(TAG, msg);
6499            throw new SecurityException(msg);
6500        }
6501
6502        final long callingId = Binder.clearCallingIdentity();
6503        try {
6504            synchronized (this) {
6505                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6506                final int NP = mProcessNames.getMap().size();
6507                for (int ip = 0; ip < NP; ip++) {
6508                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6509                    final int NA = apps.size();
6510                    for (int ia = 0; ia < NA; ia++) {
6511                        final ProcessRecord app = apps.valueAt(ia);
6512                        if (app.persistent) {
6513                            // We don't kill persistent processes.
6514                            continue;
6515                        }
6516                        if (app.removed) {
6517                            procs.add(app);
6518                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6519                            app.removed = true;
6520                            procs.add(app);
6521                        }
6522                    }
6523                }
6524
6525                final int N = procs.size();
6526                for (int i = 0; i < N; i++) {
6527                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6528                }
6529
6530                mAllowLowerMemLevel = true;
6531
6532                updateOomAdjLocked();
6533                doLowMemReportIfNeededLocked(null);
6534            }
6535        } finally {
6536            Binder.restoreCallingIdentity(callingId);
6537        }
6538    }
6539
6540    /**
6541     * Kills all background processes, except those matching any of the
6542     * specified properties.
6543     *
6544     * @param minTargetSdk the target SDK version at or above which to preserve
6545     *                     processes, or {@code -1} to ignore the target SDK
6546     * @param maxProcState the process state at or below which to preserve
6547     *                     processes, or {@code -1} to ignore the process state
6548     */
6549    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6550        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6551                != PackageManager.PERMISSION_GRANTED) {
6552            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6553                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6554                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6555            Slog.w(TAG, msg);
6556            throw new SecurityException(msg);
6557        }
6558
6559        final long callingId = Binder.clearCallingIdentity();
6560        try {
6561            synchronized (this) {
6562                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6563                final int NP = mProcessNames.getMap().size();
6564                for (int ip = 0; ip < NP; ip++) {
6565                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6566                    final int NA = apps.size();
6567                    for (int ia = 0; ia < NA; ia++) {
6568                        final ProcessRecord app = apps.valueAt(ia);
6569                        if (app.removed) {
6570                            procs.add(app);
6571                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6572                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6573                            app.removed = true;
6574                            procs.add(app);
6575                        }
6576                    }
6577                }
6578
6579                final int N = procs.size();
6580                for (int i = 0; i < N; i++) {
6581                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6582                }
6583            }
6584        } finally {
6585            Binder.restoreCallingIdentity(callingId);
6586        }
6587    }
6588
6589    @Override
6590    public void forceStopPackage(final String packageName, int userId) {
6591        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6592                != PackageManager.PERMISSION_GRANTED) {
6593            String msg = "Permission Denial: forceStopPackage() from pid="
6594                    + Binder.getCallingPid()
6595                    + ", uid=" + Binder.getCallingUid()
6596                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6597            Slog.w(TAG, msg);
6598            throw new SecurityException(msg);
6599        }
6600        final int callingPid = Binder.getCallingPid();
6601        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6602                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6603        long callingId = Binder.clearCallingIdentity();
6604        try {
6605            IPackageManager pm = AppGlobals.getPackageManager();
6606            synchronized(this) {
6607                int[] users = userId == UserHandle.USER_ALL
6608                        ? mUserController.getUsers() : new int[] { userId };
6609                for (int user : users) {
6610                    int pkgUid = -1;
6611                    try {
6612                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6613                                user);
6614                    } catch (RemoteException e) {
6615                    }
6616                    if (pkgUid == -1) {
6617                        Slog.w(TAG, "Invalid packageName: " + packageName);
6618                        continue;
6619                    }
6620                    try {
6621                        pm.setPackageStoppedState(packageName, true, user);
6622                    } catch (RemoteException e) {
6623                    } catch (IllegalArgumentException e) {
6624                        Slog.w(TAG, "Failed trying to unstop package "
6625                                + packageName + ": " + e);
6626                    }
6627                    if (mUserController.isUserRunning(user, 0)) {
6628                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6629                        finishForceStopPackageLocked(packageName, pkgUid);
6630                    }
6631                }
6632            }
6633        } finally {
6634            Binder.restoreCallingIdentity(callingId);
6635        }
6636    }
6637
6638    @Override
6639    public void addPackageDependency(String packageName) {
6640        synchronized (this) {
6641            int callingPid = Binder.getCallingPid();
6642            if (callingPid == myPid()) {
6643                //  Yeah, um, no.
6644                return;
6645            }
6646            ProcessRecord proc;
6647            synchronized (mPidsSelfLocked) {
6648                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6649            }
6650            if (proc != null) {
6651                if (proc.pkgDeps == null) {
6652                    proc.pkgDeps = new ArraySet<String>(1);
6653                }
6654                proc.pkgDeps.add(packageName);
6655            }
6656        }
6657    }
6658
6659    /*
6660     * The pkg name and app id have to be specified.
6661     */
6662    @Override
6663    public void killApplication(String pkg, int appId, int userId, String reason) {
6664        if (pkg == null) {
6665            return;
6666        }
6667        // Make sure the uid is valid.
6668        if (appId < 0) {
6669            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6670            return;
6671        }
6672        int callerUid = Binder.getCallingUid();
6673        // Only the system server can kill an application
6674        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6675            // Post an aysnc message to kill the application
6676            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6677            msg.arg1 = appId;
6678            msg.arg2 = userId;
6679            Bundle bundle = new Bundle();
6680            bundle.putString("pkg", pkg);
6681            bundle.putString("reason", reason);
6682            msg.obj = bundle;
6683            mHandler.sendMessage(msg);
6684        } else {
6685            throw new SecurityException(callerUid + " cannot kill pkg: " +
6686                    pkg);
6687        }
6688    }
6689
6690    @Override
6691    public void closeSystemDialogs(String reason) {
6692        enforceNotIsolatedCaller("closeSystemDialogs");
6693
6694        final int pid = Binder.getCallingPid();
6695        final int uid = Binder.getCallingUid();
6696        final long origId = Binder.clearCallingIdentity();
6697        try {
6698            synchronized (this) {
6699                // Only allow this from foreground processes, so that background
6700                // applications can't abuse it to prevent system UI from being shown.
6701                if (uid >= FIRST_APPLICATION_UID) {
6702                    ProcessRecord proc;
6703                    synchronized (mPidsSelfLocked) {
6704                        proc = mPidsSelfLocked.get(pid);
6705                    }
6706                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6707                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6708                                + " from background process " + proc);
6709                        return;
6710                    }
6711                }
6712                closeSystemDialogsLocked(reason);
6713            }
6714        } finally {
6715            Binder.restoreCallingIdentity(origId);
6716        }
6717    }
6718
6719    @GuardedBy("this")
6720    void closeSystemDialogsLocked(String reason) {
6721        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6722        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6723                | Intent.FLAG_RECEIVER_FOREGROUND);
6724        if (reason != null) {
6725            intent.putExtra("reason", reason);
6726        }
6727        mWindowManager.closeSystemDialogs(reason);
6728
6729        mStackSupervisor.closeSystemDialogsLocked();
6730
6731        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6732                OP_NONE, null, false, false,
6733                -1, SYSTEM_UID, UserHandle.USER_ALL);
6734    }
6735
6736    @Override
6737    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6738        enforceNotIsolatedCaller("getProcessMemoryInfo");
6739        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6740        for (int i=pids.length-1; i>=0; i--) {
6741            ProcessRecord proc;
6742            int oomAdj;
6743            synchronized (this) {
6744                synchronized (mPidsSelfLocked) {
6745                    proc = mPidsSelfLocked.get(pids[i]);
6746                    oomAdj = proc != null ? proc.setAdj : 0;
6747                }
6748            }
6749            infos[i] = new Debug.MemoryInfo();
6750            long startTime = SystemClock.currentThreadTimeMillis();
6751            Debug.getMemoryInfo(pids[i], infos[i]);
6752            long endTime = SystemClock.currentThreadTimeMillis();
6753            if (proc != null) {
6754                synchronized (this) {
6755                    if (proc.thread != null && proc.setAdj == oomAdj) {
6756                        // Record this for posterity if the process has been stable.
6757                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6758                                infos[i].getTotalUss(), infos[i].getTotalRss(), false,
6759                                ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
6760                                proc.pkgList);
6761                    }
6762                }
6763            }
6764        }
6765        return infos;
6766    }
6767
6768    @Override
6769    public long[] getProcessPss(int[] pids) {
6770        enforceNotIsolatedCaller("getProcessPss");
6771        long[] pss = new long[pids.length];
6772        for (int i=pids.length-1; i>=0; i--) {
6773            ProcessRecord proc;
6774            int oomAdj;
6775            synchronized (this) {
6776                synchronized (mPidsSelfLocked) {
6777                    proc = mPidsSelfLocked.get(pids[i]);
6778                    oomAdj = proc != null ? proc.setAdj : 0;
6779                }
6780            }
6781            long[] tmpUss = new long[3];
6782            long startTime = SystemClock.currentThreadTimeMillis();
6783            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6784            long endTime = SystemClock.currentThreadTimeMillis();
6785            if (proc != null) {
6786                synchronized (this) {
6787                    if (proc.thread != null && proc.setAdj == oomAdj) {
6788                        // Record this for posterity if the process has been stable.
6789                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
6790                                ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
6791                    }
6792                }
6793            }
6794        }
6795        return pss;
6796    }
6797
6798    @Override
6799    public void killApplicationProcess(String processName, int uid) {
6800        if (processName == null) {
6801            return;
6802        }
6803
6804        int callerUid = Binder.getCallingUid();
6805        // Only the system server can kill an application
6806        if (callerUid == SYSTEM_UID) {
6807            synchronized (this) {
6808                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6809                if (app != null && app.thread != null) {
6810                    try {
6811                        app.thread.scheduleSuicide();
6812                    } catch (RemoteException e) {
6813                        // If the other end already died, then our work here is done.
6814                    }
6815                } else {
6816                    Slog.w(TAG, "Process/uid not found attempting kill of "
6817                            + processName + " / " + uid);
6818                }
6819            }
6820        } else {
6821            throw new SecurityException(callerUid + " cannot kill app process: " +
6822                    processName);
6823        }
6824    }
6825
6826    @GuardedBy("this")
6827    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6828        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6829                false, true, false, false, UserHandle.getUserId(uid), reason);
6830    }
6831
6832    @GuardedBy("this")
6833    private void finishForceStopPackageLocked(final String packageName, int uid) {
6834        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6835                Uri.fromParts("package", packageName, null));
6836        if (!mProcessesReady) {
6837            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6838                    | Intent.FLAG_RECEIVER_FOREGROUND);
6839        }
6840        intent.putExtra(Intent.EXTRA_UID, uid);
6841        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6842        broadcastIntentLocked(null, null, intent,
6843                null, null, 0, null, null, null, OP_NONE,
6844                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6845    }
6846
6847
6848    @GuardedBy("this")
6849    private final boolean killPackageProcessesLocked(String packageName, int appId,
6850            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6851            boolean doit, boolean evenPersistent, String reason) {
6852        ArrayList<ProcessRecord> procs = new ArrayList<>();
6853
6854        // Remove all processes this package may have touched: all with the
6855        // same UID (except for the system or root user), and all whose name
6856        // matches the package name.
6857        final int NP = mProcessNames.getMap().size();
6858        for (int ip=0; ip<NP; ip++) {
6859            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6860            final int NA = apps.size();
6861            for (int ia=0; ia<NA; ia++) {
6862                ProcessRecord app = apps.valueAt(ia);
6863                if (app.persistent && !evenPersistent) {
6864                    // we don't kill persistent processes
6865                    continue;
6866                }
6867                if (app.removed) {
6868                    if (doit) {
6869                        procs.add(app);
6870                    }
6871                    continue;
6872                }
6873
6874                // Skip process if it doesn't meet our oom adj requirement.
6875                if (app.setAdj < minOomAdj) {
6876                    continue;
6877                }
6878
6879                // If no package is specified, we call all processes under the
6880                // give user id.
6881                if (packageName == null) {
6882                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6883                        continue;
6884                    }
6885                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6886                        continue;
6887                    }
6888                // Package has been specified, we want to hit all processes
6889                // that match it.  We need to qualify this by the processes
6890                // that are running under the specified app and user ID.
6891                } else {
6892                    final boolean isDep = app.pkgDeps != null
6893                            && app.pkgDeps.contains(packageName);
6894                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6895                        continue;
6896                    }
6897                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6898                        continue;
6899                    }
6900                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6901                        continue;
6902                    }
6903                }
6904
6905                // Process has passed all conditions, kill it!
6906                if (!doit) {
6907                    return true;
6908                }
6909                app.removed = true;
6910                procs.add(app);
6911            }
6912        }
6913
6914        int N = procs.size();
6915        for (int i=0; i<N; i++) {
6916            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6917        }
6918        updateOomAdjLocked();
6919        return N > 0;
6920    }
6921
6922    private void cleanupDisabledPackageComponentsLocked(
6923            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6924
6925        Set<String> disabledClasses = null;
6926        boolean packageDisabled = false;
6927        IPackageManager pm = AppGlobals.getPackageManager();
6928
6929        if (changedClasses == null) {
6930            // Nothing changed...
6931            return;
6932        }
6933
6934        // Determine enable/disable state of the package and its components.
6935        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6936        for (int i = changedClasses.length - 1; i >= 0; i--) {
6937            final String changedClass = changedClasses[i];
6938
6939            if (changedClass.equals(packageName)) {
6940                try {
6941                    // Entire package setting changed
6942                    enabled = pm.getApplicationEnabledSetting(packageName,
6943                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6944                } catch (Exception e) {
6945                    // No such package/component; probably racing with uninstall.  In any
6946                    // event it means we have nothing further to do here.
6947                    return;
6948                }
6949                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6950                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6951                if (packageDisabled) {
6952                    // Entire package is disabled.
6953                    // No need to continue to check component states.
6954                    disabledClasses = null;
6955                    break;
6956                }
6957            } else {
6958                try {
6959                    enabled = pm.getComponentEnabledSetting(
6960                            new ComponentName(packageName, changedClass),
6961                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6962                } catch (Exception e) {
6963                    // As above, probably racing with uninstall.
6964                    return;
6965                }
6966                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6967                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6968                    if (disabledClasses == null) {
6969                        disabledClasses = new ArraySet<>(changedClasses.length);
6970                    }
6971                    disabledClasses.add(changedClass);
6972                }
6973            }
6974        }
6975
6976        if (!packageDisabled && disabledClasses == null) {
6977            // Nothing to do here...
6978            return;
6979        }
6980
6981        // Clean-up disabled activities.
6982        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6983                packageName, disabledClasses, true, false, userId) && mBooted) {
6984            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6985            mStackSupervisor.scheduleIdleLocked();
6986        }
6987
6988        // Clean-up disabled tasks
6989        mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6990
6991        // Clean-up disabled services.
6992        mServices.bringDownDisabledPackageServicesLocked(
6993                packageName, disabledClasses, userId, false, killProcess, true);
6994
6995        // Clean-up disabled providers.
6996        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6997        mProviderMap.collectPackageProvidersLocked(
6998                packageName, disabledClasses, true, false, userId, providers);
6999        for (int i = providers.size() - 1; i >= 0; i--) {
7000            removeDyingProviderLocked(null, providers.get(i), true);
7001        }
7002
7003        // Clean-up disabled broadcast receivers.
7004        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7005            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7006                    packageName, disabledClasses, userId, true);
7007        }
7008
7009    }
7010
7011    final boolean clearBroadcastQueueForUserLocked(int userId) {
7012        boolean didSomething = false;
7013        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7014            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7015                    null, null, userId, true);
7016        }
7017        return didSomething;
7018    }
7019
7020    @GuardedBy("this")
7021    final boolean forceStopPackageLocked(String packageName, int appId,
7022            boolean callerWillRestart, boolean purgeCache, boolean doit,
7023            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
7024        int i;
7025
7026        if (userId == UserHandle.USER_ALL && packageName == null) {
7027            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
7028        }
7029
7030        if (appId < 0 && packageName != null) {
7031            try {
7032                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
7033                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
7034            } catch (RemoteException e) {
7035            }
7036        }
7037
7038        if (doit) {
7039            if (packageName != null) {
7040                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
7041                        + " user=" + userId + ": " + reason);
7042            } else {
7043                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
7044            }
7045
7046            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
7047        }
7048
7049        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
7050                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
7051                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
7052
7053        didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
7054
7055        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7056                packageName, null, doit, evenPersistent, userId)) {
7057            if (!doit) {
7058                return true;
7059            }
7060            didSomething = true;
7061        }
7062
7063        if (mServices.bringDownDisabledPackageServicesLocked(
7064                packageName, null, userId, evenPersistent, true, doit)) {
7065            if (!doit) {
7066                return true;
7067            }
7068            didSomething = true;
7069        }
7070
7071        if (packageName == null) {
7072            // Remove all sticky broadcasts from this user.
7073            mStickyBroadcasts.remove(userId);
7074        }
7075
7076        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7077        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
7078                userId, providers)) {
7079            if (!doit) {
7080                return true;
7081            }
7082            didSomething = true;
7083        }
7084        for (i = providers.size() - 1; i >= 0; i--) {
7085            removeDyingProviderLocked(null, providers.get(i), true);
7086        }
7087
7088        // Remove transient permissions granted from/to this package/user
7089        removeUriPermissionsForPackageLocked(packageName, userId, false, false);
7090
7091        if (doit) {
7092            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
7093                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7094                        packageName, null, userId, doit);
7095            }
7096        }
7097
7098        if (packageName == null || uninstalling) {
7099            // Remove pending intents.  For now we only do this when force
7100            // stopping users, because we have some problems when doing this
7101            // for packages -- app widgets are not currently cleaned up for
7102            // such packages, so they can be left with bad pending intents.
7103            if (mIntentSenderRecords.size() > 0) {
7104                Iterator<WeakReference<PendingIntentRecord>> it
7105                        = mIntentSenderRecords.values().iterator();
7106                while (it.hasNext()) {
7107                    WeakReference<PendingIntentRecord> wpir = it.next();
7108                    if (wpir == null) {
7109                        it.remove();
7110                        continue;
7111                    }
7112                    PendingIntentRecord pir = wpir.get();
7113                    if (pir == null) {
7114                        it.remove();
7115                        continue;
7116                    }
7117                    if (packageName == null) {
7118                        // Stopping user, remove all objects for the user.
7119                        if (pir.key.userId != userId) {
7120                            // Not the same user, skip it.
7121                            continue;
7122                        }
7123                    } else {
7124                        if (UserHandle.getAppId(pir.uid) != appId) {
7125                            // Different app id, skip it.
7126                            continue;
7127                        }
7128                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7129                            // Different user, skip it.
7130                            continue;
7131                        }
7132                        if (!pir.key.packageName.equals(packageName)) {
7133                            // Different package, skip it.
7134                            continue;
7135                        }
7136                    }
7137                    if (!doit) {
7138                        return true;
7139                    }
7140                    didSomething = true;
7141                    it.remove();
7142                    makeIntentSenderCanceledLocked(pir);
7143                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7144                        pir.key.activity.pendingResults.remove(pir.ref);
7145                    }
7146                }
7147            }
7148        }
7149
7150        if (doit) {
7151            if (purgeCache && packageName != null) {
7152                AttributeCache ac = AttributeCache.instance();
7153                if (ac != null) {
7154                    ac.removePackage(packageName);
7155                }
7156            }
7157            if (mBooted) {
7158                mStackSupervisor.resumeFocusedStackTopActivityLocked();
7159                mStackSupervisor.scheduleIdleLocked();
7160            }
7161        }
7162
7163        return didSomething;
7164    }
7165
7166    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7167        return removeProcessNameLocked(name, uid, null);
7168    }
7169
7170    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
7171            final ProcessRecord expecting) {
7172        ProcessRecord old = mProcessNames.get(name, uid);
7173        // Only actually remove when the currently recorded value matches the
7174        // record that we expected; if it doesn't match then we raced with a
7175        // newly created process and we don't want to destroy the new one.
7176        if ((expecting == null) || (old == expecting)) {
7177            mProcessNames.remove(name, uid);
7178        }
7179        if (old != null && old.uidRecord != null) {
7180            old.uidRecord.numProcs--;
7181            if (old.uidRecord.numProcs == 0) {
7182                // No more processes using this uid, tell clients it is gone.
7183                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7184                        "No more processes in " + old.uidRecord);
7185                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
7186                EventLogTags.writeAmUidStopped(uid);
7187                mActiveUids.remove(uid);
7188                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
7189            }
7190            old.uidRecord = null;
7191        }
7192        mIsolatedProcesses.remove(uid);
7193        return old;
7194    }
7195
7196    private final void addProcessNameLocked(ProcessRecord proc) {
7197        // We shouldn't already have a process under this name, but just in case we
7198        // need to clean up whatever may be there now.
7199        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
7200        if (old == proc && proc.persistent) {
7201            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
7202            Slog.w(TAG, "Re-adding persistent process " + proc);
7203        } else if (old != null) {
7204            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7205        }
7206        UidRecord uidRec = mActiveUids.get(proc.uid);
7207        if (uidRec == null) {
7208            uidRec = new UidRecord(proc.uid);
7209            // This is the first appearance of the uid, report it now!
7210            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7211                    "Creating new process uid: " + uidRec);
7212            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7213                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7214                uidRec.setWhitelist = uidRec.curWhitelist = true;
7215            }
7216            uidRec.updateHasInternetPermission();
7217            mActiveUids.put(proc.uid, uidRec);
7218            EventLogTags.writeAmUidRunning(uidRec.uid);
7219            noteUidProcessState(uidRec.uid, uidRec.curProcState);
7220        }
7221        proc.uidRecord = uidRec;
7222
7223        // Reset render thread tid if it was already set, so new process can set it again.
7224        proc.renderThreadTid = 0;
7225        uidRec.numProcs++;
7226        mProcessNames.put(proc.processName, proc.uid, proc);
7227        if (proc.isolated) {
7228            mIsolatedProcesses.put(proc.uid, proc);
7229        }
7230    }
7231
7232    @GuardedBy("this")
7233    boolean removeProcessLocked(ProcessRecord app,
7234            boolean callerWillRestart, boolean allowRestart, String reason) {
7235        final String name = app.processName;
7236        final int uid = app.uid;
7237        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7238            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7239
7240        ProcessRecord old = mProcessNames.get(name, uid);
7241        if (old != app) {
7242            // This process is no longer active, so nothing to do.
7243            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7244            return false;
7245        }
7246        removeProcessNameLocked(name, uid);
7247        if (mHeavyWeightProcess == app) {
7248            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7249                    mHeavyWeightProcess.userId, 0));
7250            mHeavyWeightProcess = null;
7251        }
7252        boolean needRestart = false;
7253        if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7254            int pid = app.pid;
7255            if (pid > 0) {
7256                synchronized (mPidsSelfLocked) {
7257                    mPidsSelfLocked.remove(pid);
7258                    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7259                }
7260                mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7261                if (app.isolated) {
7262                    mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7263                    getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7264                }
7265            }
7266            boolean willRestart = false;
7267            if (app.persistent && !app.isolated) {
7268                if (!callerWillRestart) {
7269                    willRestart = true;
7270                } else {
7271                    needRestart = true;
7272                }
7273            }
7274            app.kill(reason, true);
7275            handleAppDiedLocked(app, willRestart, allowRestart);
7276            if (willRestart) {
7277                removeLruProcessLocked(app);
7278                addAppLocked(app.info, null, false, null /* ABI override */);
7279            }
7280        } else {
7281            mRemovedProcesses.add(app);
7282        }
7283
7284        return needRestart;
7285    }
7286
7287    @GuardedBy("this")
7288    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7289        cleanupAppInLaunchingProvidersLocked(app, true);
7290        removeProcessLocked(app, false, true, "timeout publishing content providers");
7291    }
7292
7293    private final void processStartTimedOutLocked(ProcessRecord app) {
7294        final int pid = app.pid;
7295        boolean gone = false;
7296        synchronized (mPidsSelfLocked) {
7297            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7298            if (knownApp != null && knownApp.thread == null) {
7299                mPidsSelfLocked.remove(pid);
7300                gone = true;
7301            }
7302        }
7303
7304        if (gone) {
7305            Slog.w(TAG, "Process " + app + " failed to attach");
7306            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7307                    pid, app.uid, app.processName);
7308            removeProcessNameLocked(app.processName, app.uid);
7309            if (mHeavyWeightProcess == app) {
7310                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7311                        mHeavyWeightProcess.userId, 0));
7312                mHeavyWeightProcess = null;
7313            }
7314            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7315            // Take care of any launching providers waiting for this process.
7316            cleanupAppInLaunchingProvidersLocked(app, true);
7317            // Take care of any services that are waiting for the process.
7318            mServices.processStartTimedOutLocked(app);
7319            app.kill("start timeout", true);
7320            if (app.isolated) {
7321                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7322            }
7323            removeLruProcessLocked(app);
7324            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7325                Slog.w(TAG, "Unattached app died before backup, skipping");
7326                mHandler.post(new Runnable() {
7327                @Override
7328                    public void run(){
7329                        try {
7330                            IBackupManager bm = IBackupManager.Stub.asInterface(
7331                                    ServiceManager.getService(Context.BACKUP_SERVICE));
7332                            bm.agentDisconnected(app.info.packageName);
7333                        } catch (RemoteException e) {
7334                            // Can't happen; the backup manager is local
7335                        }
7336                    }
7337                });
7338            }
7339            if (isPendingBroadcastProcessLocked(pid)) {
7340                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7341                skipPendingBroadcastLocked(pid);
7342            }
7343        } else {
7344            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7345        }
7346    }
7347
7348    @GuardedBy("this")
7349    private final boolean attachApplicationLocked(IApplicationThread thread,
7350            int pid, int callingUid, long startSeq) {
7351
7352        // Find the application record that is being attached...  either via
7353        // the pid if we are running in multiple processes, or just pull the
7354        // next app record if we are emulating process with anonymous threads.
7355        ProcessRecord app;
7356        long startTime = SystemClock.uptimeMillis();
7357        if (pid != MY_PID && pid >= 0) {
7358            synchronized (mPidsSelfLocked) {
7359                app = mPidsSelfLocked.get(pid);
7360            }
7361        } else {
7362            app = null;
7363        }
7364
7365        // It's possible that process called attachApplication before we got a chance to
7366        // update the internal state.
7367        if (app == null && startSeq > 0) {
7368            final ProcessRecord pending = mPendingStarts.get(startSeq);
7369            if (pending != null && pending.startUid == callingUid
7370                    && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7371                            startSeq, true)) {
7372                app = pending;
7373            }
7374        }
7375
7376        if (app == null) {
7377            Slog.w(TAG, "No pending application record for pid " + pid
7378                    + " (IApplicationThread " + thread + "); dropping process");
7379            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7380            if (pid > 0 && pid != MY_PID) {
7381                killProcessQuiet(pid);
7382                //TODO: killProcessGroup(app.info.uid, pid);
7383            } else {
7384                try {
7385                    thread.scheduleExit();
7386                } catch (Exception e) {
7387                    // Ignore exceptions.
7388                }
7389            }
7390            return false;
7391        }
7392
7393        // If this application record is still attached to a previous
7394        // process, clean it up now.
7395        if (app.thread != null) {
7396            handleAppDiedLocked(app, true, true);
7397        }
7398
7399        // Tell the process all about itself.
7400
7401        if (DEBUG_ALL) Slog.v(
7402                TAG, "Binding process pid " + pid + " to record " + app);
7403
7404        final String processName = app.processName;
7405        try {
7406            AppDeathRecipient adr = new AppDeathRecipient(
7407                    app, pid, thread);
7408            thread.asBinder().linkToDeath(adr, 0);
7409            app.deathRecipient = adr;
7410        } catch (RemoteException e) {
7411            app.resetPackageList(mProcessStats);
7412            startProcessLocked(app, "link fail", processName);
7413            return false;
7414        }
7415
7416        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7417
7418        app.makeActive(thread, mProcessStats);
7419        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7420        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7421        app.forcingToImportant = null;
7422        updateProcessForegroundLocked(app, false, false);
7423        app.hasShownUi = false;
7424        app.debugging = false;
7425        app.cached = false;
7426        app.killedByAm = false;
7427        app.killed = false;
7428
7429
7430        // We carefully use the same state that PackageManager uses for
7431        // filtering, since we use this flag to decide if we need to install
7432        // providers when user is unlocked later
7433        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7434
7435        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7436
7437        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7438        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7439
7440        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7441            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7442            msg.obj = app;
7443            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7444        }
7445
7446        checkTime(startTime, "attachApplicationLocked: before bindApplication");
7447
7448        if (!normalMode) {
7449            Slog.i(TAG, "Launching preboot mode app: " + app);
7450        }
7451
7452        if (DEBUG_ALL) Slog.v(
7453            TAG, "New app record " + app
7454            + " thread=" + thread.asBinder() + " pid=" + pid);
7455        try {
7456            int testMode = ApplicationThreadConstants.DEBUG_OFF;
7457            if (mDebugApp != null && mDebugApp.equals(processName)) {
7458                testMode = mWaitForDebugger
7459                    ? ApplicationThreadConstants.DEBUG_WAIT
7460                    : ApplicationThreadConstants.DEBUG_ON;
7461                app.debugging = true;
7462                if (mDebugTransient) {
7463                    mDebugApp = mOrigDebugApp;
7464                    mWaitForDebugger = mOrigWaitForDebugger;
7465                }
7466            }
7467
7468            boolean enableTrackAllocation = false;
7469            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7470                enableTrackAllocation = true;
7471                mTrackAllocationApp = null;
7472            }
7473
7474            // If the app is being launched for restore or full backup, set it up specially
7475            boolean isRestrictedBackupMode = false;
7476            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7477                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7478                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7479                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7480                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7481            }
7482
7483            if (app.instr != null) {
7484                notifyPackageUse(app.instr.mClass.getPackageName(),
7485                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7486            }
7487            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7488                    + processName + " with config " + getGlobalConfiguration());
7489            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7490            app.compat = compatibilityInfoForPackageLocked(appInfo);
7491
7492            ProfilerInfo profilerInfo = null;
7493            String preBindAgent = null;
7494            if (mProfileApp != null && mProfileApp.equals(processName)) {
7495                mProfileProc = app;
7496                if (mProfilerInfo != null) {
7497                    // Send a profiler info object to the app if either a file is given, or
7498                    // an agent should be loaded at bind-time.
7499                    boolean needsInfo = mProfilerInfo.profileFile != null
7500                            || mProfilerInfo.attachAgentDuringBind;
7501                    profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7502                    if (mProfilerInfo.agent != null) {
7503                        preBindAgent = mProfilerInfo.agent;
7504                    }
7505                }
7506            } else if (app.instr != null && app.instr.mProfileFile != null) {
7507                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7508                        null, false);
7509            }
7510            if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7511                // We need to do a debuggable check here. See setAgentApp for why the check is
7512                // postponed to here.
7513                if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7514                    String agent = mAppAgentMap.get(processName);
7515                    // Do not overwrite already requested agent.
7516                    if (profilerInfo == null) {
7517                        profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7518                                mAppAgentMap.get(processName), true);
7519                    } else if (profilerInfo.agent == null) {
7520                        profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7521                    }
7522                }
7523            }
7524
7525            if (profilerInfo != null && profilerInfo.profileFd != null) {
7526                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7527            }
7528
7529            // We deprecated Build.SERIAL and it is not accessible to
7530            // apps that target the v2 security sandbox and to apps that
7531            // target APIs higher than O MR1. Since access to the serial
7532            // is now behind a permission we push down the value.
7533            final String buildSerial = (appInfo.targetSandboxVersion < 2
7534                    && appInfo.targetSdkVersion <= Build.VERSION_CODES.O_MR1)
7535                            ? sTheRealBuildSerial : Build.UNKNOWN;
7536
7537            // Check if this is a secondary process that should be incorporated into some
7538            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7539            // stuff above because profiling can currently happen only in the primary
7540            // instrumentation process.)
7541            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7542                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7543                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7544                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7545                        if (aInstr.mTargetProcesses.length == 0) {
7546                            // This is the wildcard mode, where every process brought up for
7547                            // the target instrumentation should be included.
7548                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7549                                app.instr = aInstr;
7550                                aInstr.mRunningProcesses.add(app);
7551                            }
7552                        } else {
7553                            for (String proc : aInstr.mTargetProcesses) {
7554                                if (proc.equals(app.processName)) {
7555                                    app.instr = aInstr;
7556                                    aInstr.mRunningProcesses.add(app);
7557                                    break;
7558                                }
7559                            }
7560                        }
7561                    }
7562                }
7563            }
7564
7565            // If we were asked to attach an agent on startup, do so now, before we're binding
7566            // application code.
7567            if (preBindAgent != null) {
7568                thread.attachAgent(preBindAgent);
7569            }
7570
7571
7572            // Figure out whether the app needs to run in autofill compat mode.
7573            boolean isAutofillCompatEnabled = false;
7574            if (UserHandle.getAppId(app.info.uid) >= Process.FIRST_APPLICATION_UID) {
7575                final AutofillManagerInternal afm = LocalServices.getService(
7576                        AutofillManagerInternal.class);
7577                if (afm != null) {
7578                    isAutofillCompatEnabled = afm.isCompatibilityModeRequested(
7579                            app.info.packageName, app.info.versionCode, app.userId);
7580                }
7581            }
7582
7583            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7584            mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7585            if (app.isolatedEntryPoint != null) {
7586                // This is an isolated process which should just call an entry point instead of
7587                // being bound to an application.
7588                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7589            } else if (app.instr != null) {
7590                thread.bindApplication(processName, appInfo, providers,
7591                        app.instr.mClass,
7592                        profilerInfo, app.instr.mArguments,
7593                        app.instr.mWatcher,
7594                        app.instr.mUiAutomationConnection, testMode,
7595                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7596                        isRestrictedBackupMode || !normalMode, app.persistent,
7597                        new Configuration(getGlobalConfiguration()), app.compat,
7598                        getCommonServicesLocked(app.isolated),
7599                        mCoreSettingsObserver.getCoreSettingsLocked(),
7600                        buildSerial, isAutofillCompatEnabled);
7601            } else {
7602                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7603                        null, null, null, testMode,
7604                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7605                        isRestrictedBackupMode || !normalMode, app.persistent,
7606                        new Configuration(getGlobalConfiguration()), app.compat,
7607                        getCommonServicesLocked(app.isolated),
7608                        mCoreSettingsObserver.getCoreSettingsLocked(),
7609                        buildSerial, isAutofillCompatEnabled);
7610            }
7611
7612            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7613            updateLruProcessLocked(app, false, null);
7614            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7615            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7616        } catch (Exception e) {
7617            // todo: Yikes!  What should we do?  For now we will try to
7618            // start another process, but that could easily get us in
7619            // an infinite loop of restarting processes...
7620            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7621
7622            app.resetPackageList(mProcessStats);
7623            app.unlinkDeathRecipient();
7624            startProcessLocked(app, "bind fail", processName);
7625            return false;
7626        }
7627
7628        // Remove this record from the list of starting applications.
7629        mPersistentStartingProcesses.remove(app);
7630        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7631                "Attach application locked removing on hold: " + app);
7632        mProcessesOnHold.remove(app);
7633
7634        boolean badApp = false;
7635        boolean didSomething = false;
7636
7637        // See if the top visible activity is waiting to run in this process...
7638        if (normalMode) {
7639            try {
7640                if (mStackSupervisor.attachApplicationLocked(app)) {
7641                    didSomething = true;
7642                }
7643            } catch (Exception e) {
7644                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7645                badApp = true;
7646            }
7647        }
7648
7649        // Find any services that should be running in this process...
7650        if (!badApp) {
7651            try {
7652                didSomething |= mServices.attachApplicationLocked(app, processName);
7653                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7654            } catch (Exception e) {
7655                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7656                badApp = true;
7657            }
7658        }
7659
7660        // Check if a next-broadcast receiver is in this process...
7661        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7662            try {
7663                didSomething |= sendPendingBroadcastsLocked(app);
7664                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7665            } catch (Exception e) {
7666                // If the app died trying to launch the receiver we declare it 'bad'
7667                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7668                badApp = true;
7669            }
7670        }
7671
7672        // Check whether the next backup agent is in this process...
7673        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7674            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7675                    "New app is backup target, launching agent for " + app);
7676            notifyPackageUse(mBackupTarget.appInfo.packageName,
7677                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7678            try {
7679                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7680                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7681                        mBackupTarget.backupMode);
7682            } catch (Exception e) {
7683                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7684                badApp = true;
7685            }
7686        }
7687
7688        if (badApp) {
7689            app.kill("error during init", true);
7690            handleAppDiedLocked(app, false, true);
7691            return false;
7692        }
7693
7694        if (!didSomething) {
7695            updateOomAdjLocked();
7696            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7697        }
7698
7699        return true;
7700    }
7701
7702    @Override
7703    public final void attachApplication(IApplicationThread thread, long startSeq) {
7704        synchronized (this) {
7705            int callingPid = Binder.getCallingPid();
7706            final int callingUid = Binder.getCallingUid();
7707            final long origId = Binder.clearCallingIdentity();
7708            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7709            Binder.restoreCallingIdentity(origId);
7710        }
7711    }
7712
7713    @Override
7714    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7715        final long origId = Binder.clearCallingIdentity();
7716        synchronized (this) {
7717            ActivityStack stack = ActivityRecord.getStackLocked(token);
7718            if (stack != null) {
7719                ActivityRecord r =
7720                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7721                                false /* processPausingActivities */, config);
7722                if (stopProfiling) {
7723                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7724                        clearProfilerLocked();
7725                    }
7726                }
7727            }
7728        }
7729        Binder.restoreCallingIdentity(origId);
7730    }
7731
7732    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7733        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7734                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7735    }
7736
7737    void enableScreenAfterBoot() {
7738        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7739                SystemClock.uptimeMillis());
7740        mWindowManager.enableScreenAfterBoot();
7741
7742        synchronized (this) {
7743            updateEventDispatchingLocked();
7744        }
7745    }
7746
7747    @Override
7748    public void showBootMessage(final CharSequence msg, final boolean always) {
7749        if (Binder.getCallingUid() != myUid()) {
7750            throw new SecurityException();
7751        }
7752        mWindowManager.showBootMessage(msg, always);
7753    }
7754
7755    @Override
7756    public void keyguardGoingAway(int flags) {
7757        enforceNotIsolatedCaller("keyguardGoingAway");
7758        final long token = Binder.clearCallingIdentity();
7759        try {
7760            synchronized (this) {
7761                mKeyguardController.keyguardGoingAway(flags);
7762            }
7763        } finally {
7764            Binder.restoreCallingIdentity(token);
7765        }
7766    }
7767
7768    /**
7769     * @return whther the keyguard is currently locked.
7770     */
7771    boolean isKeyguardLocked() {
7772        return mKeyguardController.isKeyguardLocked();
7773    }
7774
7775    final void finishBooting() {
7776        synchronized (this) {
7777            if (!mBootAnimationComplete) {
7778                mCallFinishBooting = true;
7779                return;
7780            }
7781            mCallFinishBooting = false;
7782        }
7783
7784        ArraySet<String> completedIsas = new ArraySet<String>();
7785        for (String abi : Build.SUPPORTED_ABIS) {
7786            zygoteProcess.establishZygoteConnectionForAbi(abi);
7787            final String instructionSet = VMRuntime.getInstructionSet(abi);
7788            if (!completedIsas.contains(instructionSet)) {
7789                try {
7790                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7791                } catch (InstallerException e) {
7792                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7793                            e.getMessage() +")");
7794                }
7795                completedIsas.add(instructionSet);
7796            }
7797        }
7798
7799        IntentFilter pkgFilter = new IntentFilter();
7800        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7801        pkgFilter.addDataScheme("package");
7802        mContext.registerReceiver(new BroadcastReceiver() {
7803            @Override
7804            public void onReceive(Context context, Intent intent) {
7805                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7806                if (pkgs != null) {
7807                    for (String pkg : pkgs) {
7808                        synchronized (ActivityManagerService.this) {
7809                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7810                                    0, "query restart")) {
7811                                setResultCode(Activity.RESULT_OK);
7812                                return;
7813                            }
7814                        }
7815                    }
7816                }
7817            }
7818        }, pkgFilter);
7819
7820        IntentFilter dumpheapFilter = new IntentFilter();
7821        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7822        mContext.registerReceiver(new BroadcastReceiver() {
7823            @Override
7824            public void onReceive(Context context, Intent intent) {
7825                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7826                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7827                } else {
7828                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7829                }
7830            }
7831        }, dumpheapFilter);
7832
7833        // Let system services know.
7834        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7835
7836        synchronized (this) {
7837            // Ensure that any processes we had put on hold are now started
7838            // up.
7839            final int NP = mProcessesOnHold.size();
7840            if (NP > 0) {
7841                ArrayList<ProcessRecord> procs =
7842                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7843                for (int ip=0; ip<NP; ip++) {
7844                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7845                            + procs.get(ip));
7846                    startProcessLocked(procs.get(ip), "on-hold", null);
7847                }
7848            }
7849            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7850                return;
7851            }
7852            // Start looking for apps that are abusing wake locks.
7853            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7854            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7855            // Tell anyone interested that we are done booting!
7856            SystemProperties.set("sys.boot_completed", "1");
7857
7858            // And trigger dev.bootcomplete if we are not showing encryption progress
7859            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7860                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7861                SystemProperties.set("dev.bootcomplete", "1");
7862            }
7863            mUserController.sendBootCompleted(
7864                    new IIntentReceiver.Stub() {
7865                        @Override
7866                        public void performReceive(Intent intent, int resultCode,
7867                                String data, Bundle extras, boolean ordered,
7868                                boolean sticky, int sendingUser) {
7869                            synchronized (ActivityManagerService.this) {
7870                                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
7871                            }
7872                        }
7873                    });
7874            mUserController.scheduleStartProfiles();
7875        }
7876    }
7877
7878    @Override
7879    public void bootAnimationComplete() {
7880        final boolean callFinishBooting;
7881        synchronized (this) {
7882            callFinishBooting = mCallFinishBooting;
7883            mBootAnimationComplete = true;
7884        }
7885        if (callFinishBooting) {
7886            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7887            finishBooting();
7888            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7889        }
7890    }
7891
7892    final void ensureBootCompleted() {
7893        boolean booting;
7894        boolean enableScreen;
7895        synchronized (this) {
7896            booting = mBooting;
7897            mBooting = false;
7898            enableScreen = !mBooted;
7899            mBooted = true;
7900        }
7901
7902        if (booting) {
7903            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7904            finishBooting();
7905            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7906        }
7907
7908        if (enableScreen) {
7909            enableScreenAfterBoot();
7910        }
7911    }
7912
7913    @Override
7914    public final void activityResumed(IBinder token) {
7915        final long origId = Binder.clearCallingIdentity();
7916        synchronized(this) {
7917            ActivityRecord.activityResumedLocked(token);
7918            mWindowManager.notifyAppResumedFinished(token);
7919        }
7920        Binder.restoreCallingIdentity(origId);
7921    }
7922
7923    @Override
7924    public final void activityPaused(IBinder token) {
7925        final long origId = Binder.clearCallingIdentity();
7926        synchronized(this) {
7927            ActivityStack stack = ActivityRecord.getStackLocked(token);
7928            if (stack != null) {
7929                stack.activityPausedLocked(token, false);
7930            }
7931        }
7932        Binder.restoreCallingIdentity(origId);
7933    }
7934
7935    @Override
7936    public final void activityStopped(IBinder token, Bundle icicle,
7937            PersistableBundle persistentState, CharSequence description) {
7938        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7939
7940        // Refuse possible leaked file descriptors
7941        if (icicle != null && icicle.hasFileDescriptors()) {
7942            throw new IllegalArgumentException("File descriptors passed in Bundle");
7943        }
7944
7945        final long origId = Binder.clearCallingIdentity();
7946
7947        synchronized (this) {
7948            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7949            if (r != null) {
7950                r.activityStoppedLocked(icicle, persistentState, description);
7951            }
7952        }
7953
7954        trimApplications();
7955
7956        Binder.restoreCallingIdentity(origId);
7957    }
7958
7959    @Override
7960    public final void activityDestroyed(IBinder token) {
7961        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7962        synchronized (this) {
7963            ActivityStack stack = ActivityRecord.getStackLocked(token);
7964            if (stack != null) {
7965                stack.activityDestroyedLocked(token, "activityDestroyed");
7966            }
7967        }
7968    }
7969
7970    @Override
7971    public final void activityRelaunched(IBinder token) {
7972        final long origId = Binder.clearCallingIdentity();
7973        synchronized (this) {
7974            mStackSupervisor.activityRelaunchedLocked(token);
7975        }
7976        Binder.restoreCallingIdentity(origId);
7977    }
7978
7979    @Override
7980    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7981            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7982        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7983                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7984        synchronized (this) {
7985            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7986            if (record == null) {
7987                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7988                        + "found for: " + token);
7989            }
7990            record.setSizeConfigurations(horizontalSizeConfiguration,
7991                    verticalSizeConfigurations, smallestSizeConfigurations);
7992        }
7993    }
7994
7995    @Override
7996    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7997        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7998    }
7999
8000    @Override
8001    public final void notifyEnterAnimationComplete(IBinder token) {
8002        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
8003    }
8004
8005    @Override
8006    public String getCallingPackage(IBinder token) {
8007        synchronized (this) {
8008            ActivityRecord r = getCallingRecordLocked(token);
8009            return r != null ? r.info.packageName : null;
8010        }
8011    }
8012
8013    @Override
8014    public ComponentName getCallingActivity(IBinder token) {
8015        synchronized (this) {
8016            ActivityRecord r = getCallingRecordLocked(token);
8017            return r != null ? r.intent.getComponent() : null;
8018        }
8019    }
8020
8021    private ActivityRecord getCallingRecordLocked(IBinder token) {
8022        ActivityRecord r = ActivityRecord.isInStackLocked(token);
8023        if (r == null) {
8024            return null;
8025        }
8026        return r.resultTo;
8027    }
8028
8029    @Override
8030    public ComponentName getActivityClassForToken(IBinder token) {
8031        synchronized(this) {
8032            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8033            if (r == null) {
8034                return null;
8035            }
8036            return r.intent.getComponent();
8037        }
8038    }
8039
8040    @Override
8041    public String getPackageForToken(IBinder token) {
8042        synchronized(this) {
8043            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8044            if (r == null) {
8045                return null;
8046            }
8047            return r.packageName;
8048        }
8049    }
8050
8051    @Override
8052    public boolean isRootVoiceInteraction(IBinder token) {
8053        synchronized(this) {
8054            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8055            if (r == null) {
8056                return false;
8057            }
8058            return r.rootVoiceInteraction;
8059        }
8060    }
8061
8062    @Override
8063    public IIntentSender getIntentSender(int type,
8064            String packageName, IBinder token, String resultWho,
8065            int requestCode, Intent[] intents, String[] resolvedTypes,
8066            int flags, Bundle bOptions, int userId) {
8067        enforceNotIsolatedCaller("getIntentSender");
8068        // Refuse possible leaked file descriptors
8069        if (intents != null) {
8070            if (intents.length < 1) {
8071                throw new IllegalArgumentException("Intents array length must be >= 1");
8072            }
8073            for (int i=0; i<intents.length; i++) {
8074                Intent intent = intents[i];
8075                if (intent != null) {
8076                    if (intent.hasFileDescriptors()) {
8077                        throw new IllegalArgumentException("File descriptors passed in Intent");
8078                    }
8079                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
8080                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
8081                        throw new IllegalArgumentException(
8082                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
8083                    }
8084                    intents[i] = new Intent(intent);
8085                }
8086            }
8087            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
8088                throw new IllegalArgumentException(
8089                        "Intent array length does not match resolvedTypes length");
8090            }
8091        }
8092        if (bOptions != null) {
8093            if (bOptions.hasFileDescriptors()) {
8094                throw new IllegalArgumentException("File descriptors passed in options");
8095            }
8096        }
8097
8098        synchronized(this) {
8099            int callingUid = Binder.getCallingUid();
8100            int origUserId = userId;
8101            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8102                    type == ActivityManager.INTENT_SENDER_BROADCAST,
8103                    ALLOW_NON_FULL, "getIntentSender", null);
8104            if (origUserId == UserHandle.USER_CURRENT) {
8105                // We don't want to evaluate this until the pending intent is
8106                // actually executed.  However, we do want to always do the
8107                // security checking for it above.
8108                userId = UserHandle.USER_CURRENT;
8109            }
8110            try {
8111                if (callingUid != 0 && callingUid != SYSTEM_UID) {
8112                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
8113                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
8114                    if (!UserHandle.isSameApp(callingUid, uid)) {
8115                        String msg = "Permission Denial: getIntentSender() from pid="
8116                            + Binder.getCallingPid()
8117                            + ", uid=" + Binder.getCallingUid()
8118                            + ", (need uid=" + uid + ")"
8119                            + " is not allowed to send as package " + packageName;
8120                        Slog.w(TAG, msg);
8121                        throw new SecurityException(msg);
8122                    }
8123                }
8124
8125                return getIntentSenderLocked(type, packageName, callingUid, userId,
8126                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
8127
8128            } catch (RemoteException e) {
8129                throw new SecurityException(e);
8130            }
8131        }
8132    }
8133
8134    IIntentSender getIntentSenderLocked(int type, String packageName,
8135            int callingUid, int userId, IBinder token, String resultWho,
8136            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
8137            Bundle bOptions) {
8138        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
8139        ActivityRecord activity = null;
8140        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8141            activity = ActivityRecord.isInStackLocked(token);
8142            if (activity == null) {
8143                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
8144                return null;
8145            }
8146            if (activity.finishing) {
8147                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
8148                return null;
8149            }
8150        }
8151
8152        // We're going to be splicing together extras before sending, so we're
8153        // okay poking into any contained extras.
8154        if (intents != null) {
8155            for (int i = 0; i < intents.length; i++) {
8156                intents[i].setDefusable(true);
8157            }
8158        }
8159        Bundle.setDefusable(bOptions, true);
8160
8161        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
8162        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
8163        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
8164        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
8165                |PendingIntent.FLAG_UPDATE_CURRENT);
8166
8167        PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
8168                resultWho, requestCode, intents, resolvedTypes, flags,
8169                SafeActivityOptions.fromBundle(bOptions), userId);
8170        WeakReference<PendingIntentRecord> ref;
8171        ref = mIntentSenderRecords.get(key);
8172        PendingIntentRecord rec = ref != null ? ref.get() : null;
8173        if (rec != null) {
8174            if (!cancelCurrent) {
8175                if (updateCurrent) {
8176                    if (rec.key.requestIntent != null) {
8177                        rec.key.requestIntent.replaceExtras(intents != null ?
8178                                intents[intents.length - 1] : null);
8179                    }
8180                    if (intents != null) {
8181                        intents[intents.length-1] = rec.key.requestIntent;
8182                        rec.key.allIntents = intents;
8183                        rec.key.allResolvedTypes = resolvedTypes;
8184                    } else {
8185                        rec.key.allIntents = null;
8186                        rec.key.allResolvedTypes = null;
8187                    }
8188                }
8189                return rec;
8190            }
8191            makeIntentSenderCanceledLocked(rec);
8192            mIntentSenderRecords.remove(key);
8193        }
8194        if (noCreate) {
8195            return rec;
8196        }
8197        rec = new PendingIntentRecord(this, key, callingUid);
8198        mIntentSenderRecords.put(key, rec.ref);
8199        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8200            if (activity.pendingResults == null) {
8201                activity.pendingResults
8202                        = new HashSet<WeakReference<PendingIntentRecord>>();
8203            }
8204            activity.pendingResults.add(rec.ref);
8205        }
8206        return rec;
8207    }
8208
8209    @Override
8210    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
8211            Intent intent, String resolvedType,
8212            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
8213        if (target instanceof PendingIntentRecord) {
8214            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
8215                    whitelistToken, finishedReceiver, requiredPermission, options);
8216        } else {
8217            if (intent == null) {
8218                // Weird case: someone has given us their own custom IIntentSender, and now
8219                // they have someone else trying to send to it but of course this isn't
8220                // really a PendingIntent, so there is no base Intent, and the caller isn't
8221                // supplying an Intent... but we never want to dispatch a null Intent to
8222                // a receiver, so um...  let's make something up.
8223                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
8224                intent = new Intent(Intent.ACTION_MAIN);
8225            }
8226            try {
8227                target.send(code, intent, resolvedType, whitelistToken, null,
8228                        requiredPermission, options);
8229            } catch (RemoteException e) {
8230            }
8231            // Platform code can rely on getting a result back when the send is done, but if
8232            // this intent sender is from outside of the system we can't rely on it doing that.
8233            // So instead we don't give it the result receiver, and instead just directly
8234            // report the finish immediately.
8235            if (finishedReceiver != null) {
8236                try {
8237                    finishedReceiver.performReceive(intent, 0,
8238                            null, null, false, false, UserHandle.getCallingUserId());
8239                } catch (RemoteException e) {
8240                }
8241            }
8242            return 0;
8243        }
8244    }
8245
8246    @Override
8247    public void cancelIntentSender(IIntentSender sender) {
8248        if (!(sender instanceof PendingIntentRecord)) {
8249            return;
8250        }
8251        synchronized(this) {
8252            PendingIntentRecord rec = (PendingIntentRecord)sender;
8253            try {
8254                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8255                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8256                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8257                    String msg = "Permission Denial: cancelIntentSender() from pid="
8258                        + Binder.getCallingPid()
8259                        + ", uid=" + Binder.getCallingUid()
8260                        + " is not allowed to cancel package "
8261                        + rec.key.packageName;
8262                    Slog.w(TAG, msg);
8263                    throw new SecurityException(msg);
8264                }
8265            } catch (RemoteException e) {
8266                throw new SecurityException(e);
8267            }
8268            cancelIntentSenderLocked(rec, true);
8269        }
8270    }
8271
8272    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8273        makeIntentSenderCanceledLocked(rec);
8274        mIntentSenderRecords.remove(rec.key);
8275        if (cleanActivity && rec.key.activity != null) {
8276            rec.key.activity.pendingResults.remove(rec.ref);
8277        }
8278    }
8279
8280    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8281        rec.canceled = true;
8282        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8283        if (callbacks != null) {
8284            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8285        }
8286    }
8287
8288    @Override
8289    public String getPackageForIntentSender(IIntentSender pendingResult) {
8290        if (!(pendingResult instanceof PendingIntentRecord)) {
8291            return null;
8292        }
8293        try {
8294            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8295            return res.key.packageName;
8296        } catch (ClassCastException e) {
8297        }
8298        return null;
8299    }
8300
8301    @Override
8302    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8303        if (!(sender instanceof PendingIntentRecord)) {
8304            return;
8305        }
8306        synchronized(this) {
8307            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
8308        }
8309    }
8310
8311    @Override
8312    public void unregisterIntentSenderCancelListener(IIntentSender sender,
8313            IResultReceiver receiver) {
8314        if (!(sender instanceof PendingIntentRecord)) {
8315            return;
8316        }
8317        synchronized(this) {
8318            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8319        }
8320    }
8321
8322    @Override
8323    public int getUidForIntentSender(IIntentSender sender) {
8324        if (sender instanceof PendingIntentRecord) {
8325            try {
8326                PendingIntentRecord res = (PendingIntentRecord)sender;
8327                return res.uid;
8328            } catch (ClassCastException e) {
8329            }
8330        }
8331        return -1;
8332    }
8333
8334    @Override
8335    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8336        if (!(pendingResult instanceof PendingIntentRecord)) {
8337            return false;
8338        }
8339        try {
8340            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8341            if (res.key.allIntents == null) {
8342                return false;
8343            }
8344            for (int i=0; i<res.key.allIntents.length; i++) {
8345                Intent intent = res.key.allIntents[i];
8346                if (intent.getPackage() != null && intent.getComponent() != null) {
8347                    return false;
8348                }
8349            }
8350            return true;
8351        } catch (ClassCastException e) {
8352        }
8353        return false;
8354    }
8355
8356    @Override
8357    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8358        if (!(pendingResult instanceof PendingIntentRecord)) {
8359            return false;
8360        }
8361        try {
8362            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8363            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8364                return true;
8365            }
8366            return false;
8367        } catch (ClassCastException e) {
8368        }
8369        return false;
8370    }
8371
8372    @Override
8373    public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8374        if (pendingResult instanceof PendingIntentRecord) {
8375            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8376            return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8377        }
8378        return false;
8379    }
8380
8381    @Override
8382    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8383        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8384                "getIntentForIntentSender()");
8385        if (!(pendingResult instanceof PendingIntentRecord)) {
8386            return null;
8387        }
8388        try {
8389            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8390            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8391        } catch (ClassCastException e) {
8392        }
8393        return null;
8394    }
8395
8396    @Override
8397    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8398        if (!(pendingResult instanceof PendingIntentRecord)) {
8399            return null;
8400        }
8401        try {
8402            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8403            synchronized (this) {
8404                return getTagForIntentSenderLocked(res, prefix);
8405            }
8406        } catch (ClassCastException e) {
8407        }
8408        return null;
8409    }
8410
8411    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8412        final Intent intent = res.key.requestIntent;
8413        if (intent != null) {
8414            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8415                    || res.lastTagPrefix.equals(prefix))) {
8416                return res.lastTag;
8417            }
8418            res.lastTagPrefix = prefix;
8419            final StringBuilder sb = new StringBuilder(128);
8420            if (prefix != null) {
8421                sb.append(prefix);
8422            }
8423            if (intent.getAction() != null) {
8424                sb.append(intent.getAction());
8425            } else if (intent.getComponent() != null) {
8426                intent.getComponent().appendShortString(sb);
8427            } else {
8428                sb.append("?");
8429            }
8430            return res.lastTag = sb.toString();
8431        }
8432        return null;
8433    }
8434
8435    @Override
8436    public void setProcessLimit(int max) {
8437        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8438                "setProcessLimit()");
8439        synchronized (this) {
8440            mConstants.setOverrideMaxCachedProcesses(max);
8441        }
8442        trimApplications();
8443    }
8444
8445    @Override
8446    public int getProcessLimit() {
8447        synchronized (this) {
8448            return mConstants.getOverrideMaxCachedProcesses();
8449        }
8450    }
8451
8452    void importanceTokenDied(ImportanceToken token) {
8453        synchronized (ActivityManagerService.this) {
8454            synchronized (mPidsSelfLocked) {
8455                ImportanceToken cur
8456                    = mImportantProcesses.get(token.pid);
8457                if (cur != token) {
8458                    return;
8459                }
8460                mImportantProcesses.remove(token.pid);
8461                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8462                if (pr == null) {
8463                    return;
8464                }
8465                pr.forcingToImportant = null;
8466                updateProcessForegroundLocked(pr, false, false);
8467            }
8468            updateOomAdjLocked();
8469        }
8470    }
8471
8472    @Override
8473    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8474        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8475                "setProcessImportant()");
8476        synchronized(this) {
8477            boolean changed = false;
8478
8479            synchronized (mPidsSelfLocked) {
8480                ProcessRecord pr = mPidsSelfLocked.get(pid);
8481                if (pr == null && isForeground) {
8482                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8483                    return;
8484                }
8485                ImportanceToken oldToken = mImportantProcesses.get(pid);
8486                if (oldToken != null) {
8487                    oldToken.token.unlinkToDeath(oldToken, 0);
8488                    mImportantProcesses.remove(pid);
8489                    if (pr != null) {
8490                        pr.forcingToImportant = null;
8491                    }
8492                    changed = true;
8493                }
8494                if (isForeground && token != null) {
8495                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8496                        @Override
8497                        public void binderDied() {
8498                            importanceTokenDied(this);
8499                        }
8500                    };
8501                    try {
8502                        token.linkToDeath(newToken, 0);
8503                        mImportantProcesses.put(pid, newToken);
8504                        pr.forcingToImportant = newToken;
8505                        changed = true;
8506                    } catch (RemoteException e) {
8507                        // If the process died while doing this, we will later
8508                        // do the cleanup with the process death link.
8509                    }
8510                }
8511            }
8512
8513            if (changed) {
8514                updateOomAdjLocked();
8515            }
8516        }
8517    }
8518
8519    @Override
8520    public boolean isAppForeground(int uid) throws RemoteException {
8521        synchronized (this) {
8522            UidRecord uidRec = mActiveUids.get(uid);
8523            if (uidRec == null || uidRec.idle) {
8524                return false;
8525            }
8526            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8527        }
8528    }
8529
8530    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8531    // be guarded by permission checking.
8532    int getUidState(int uid) {
8533        synchronized (this) {
8534            return getUidStateLocked(uid);
8535        }
8536    }
8537
8538    int getUidStateLocked(int uid) {
8539        UidRecord uidRec = mActiveUids.get(uid);
8540        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8541    }
8542
8543    @Override
8544    public boolean isInMultiWindowMode(IBinder token) {
8545        final long origId = Binder.clearCallingIdentity();
8546        try {
8547            synchronized(this) {
8548                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8549                if (r == null) {
8550                    return false;
8551                }
8552                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8553                return r.inMultiWindowMode();
8554            }
8555        } finally {
8556            Binder.restoreCallingIdentity(origId);
8557        }
8558    }
8559
8560    @Override
8561    public boolean isInPictureInPictureMode(IBinder token) {
8562        final long origId = Binder.clearCallingIdentity();
8563        try {
8564            synchronized(this) {
8565                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8566            }
8567        } finally {
8568            Binder.restoreCallingIdentity(origId);
8569        }
8570    }
8571
8572    private boolean isInPictureInPictureMode(ActivityRecord r) {
8573        if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8574                || r.getStack().isInStackLocked(r) == null) {
8575            return false;
8576        }
8577
8578        // If we are animating to fullscreen then we have already dispatched the PIP mode
8579        // changed, so we should reflect that check here as well.
8580        final PinnedActivityStack stack = r.getStack();
8581        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8582        return !windowController.isAnimatingBoundsToFullscreen();
8583    }
8584
8585    @Override
8586    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8587        final long origId = Binder.clearCallingIdentity();
8588        try {
8589            synchronized(this) {
8590                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8591                        "enterPictureInPictureMode", token, params);
8592
8593                // If the activity is already in picture in picture mode, then just return early
8594                if (isInPictureInPictureMode(r)) {
8595                    return true;
8596                }
8597
8598                // Activity supports picture-in-picture, now check that we can enter PiP at this
8599                // point, if it is
8600                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8601                        false /* beforeStopping */)) {
8602                    return false;
8603                }
8604
8605                final Runnable enterPipRunnable = () -> {
8606                    // Only update the saved args from the args that are set
8607                    r.pictureInPictureArgs.copyOnlySet(params);
8608                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8609                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8610                    // Adjust the source bounds by the insets for the transition down
8611                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8612                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8613                            "enterPictureInPictureMode");
8614                    final PinnedActivityStack stack = r.getStack();
8615                    stack.setPictureInPictureAspectRatio(aspectRatio);
8616                    stack.setPictureInPictureActions(actions);
8617
8618                    MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.supportsEnterPipOnTaskSwitch);
8619                    logPictureInPictureArgs(params);
8620                };
8621
8622                if (isKeyguardLocked()) {
8623                    // If the keyguard is showing or occluded, then try and dismiss it before
8624                    // entering picture-in-picture (this will prompt the user to authenticate if the
8625                    // device is currently locked).
8626                    try {
8627                        dismissKeyguard(token, new KeyguardDismissCallback() {
8628                            @Override
8629                            public void onDismissSucceeded() throws RemoteException {
8630                                mHandler.post(enterPipRunnable);
8631                            }
8632                        }, null /* message */);
8633                    } catch (RemoteException e) {
8634                        // Local call
8635                    }
8636                } else {
8637                    // Enter picture in picture immediately otherwise
8638                    enterPipRunnable.run();
8639                }
8640                return true;
8641            }
8642        } finally {
8643            Binder.restoreCallingIdentity(origId);
8644        }
8645    }
8646
8647    @Override
8648    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8649        final long origId = Binder.clearCallingIdentity();
8650        try {
8651            synchronized(this) {
8652                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8653                        "setPictureInPictureParams", token, params);
8654
8655                // Only update the saved args from the args that are set
8656                r.pictureInPictureArgs.copyOnlySet(params);
8657                if (r.inPinnedWindowingMode()) {
8658                    // If the activity is already in picture-in-picture, update the pinned stack now
8659                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8660                    // be used the next time the activity enters PiP
8661                    final PinnedActivityStack stack = r.getStack();
8662                    if (!stack.isAnimatingBoundsToFullscreen()) {
8663                        stack.setPictureInPictureAspectRatio(
8664                                r.pictureInPictureArgs.getAspectRatio());
8665                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8666                    }
8667                }
8668                logPictureInPictureArgs(params);
8669            }
8670        } finally {
8671            Binder.restoreCallingIdentity(origId);
8672        }
8673    }
8674
8675    @Override
8676    public int getMaxNumPictureInPictureActions(IBinder token) {
8677        // Currently, this is a static constant, but later, we may change this to be dependent on
8678        // the context of the activity
8679        return 3;
8680    }
8681
8682    private void logPictureInPictureArgs(PictureInPictureParams params) {
8683        if (params.hasSetActions()) {
8684            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8685                    params.getActions().size());
8686        }
8687        if (params.hasSetAspectRatio()) {
8688            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8689            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8690            MetricsLogger.action(lm);
8691        }
8692    }
8693
8694    /**
8695     * Checks the state of the system and the activity associated with the given {@param token} to
8696     * verify that picture-in-picture is supported for that activity.
8697     *
8698     * @return the activity record for the given {@param token} if all the checks pass.
8699     */
8700    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8701            IBinder token, PictureInPictureParams params) {
8702        if (!mSupportsPictureInPicture) {
8703            throw new IllegalStateException(caller
8704                    + ": Device doesn't support picture-in-picture mode.");
8705        }
8706
8707        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8708        if (r == null) {
8709            throw new IllegalStateException(caller
8710                    + ": Can't find activity for token=" + token);
8711        }
8712
8713        if (!r.supportsPictureInPicture()) {
8714            throw new IllegalStateException(caller
8715                    + ": Current activity does not support picture-in-picture.");
8716        }
8717
8718        if (params.hasSetAspectRatio()
8719                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8720                        params.getAspectRatio())) {
8721            final float minAspectRatio = mContext.getResources().getFloat(
8722                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8723            final float maxAspectRatio = mContext.getResources().getFloat(
8724                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8725            throw new IllegalArgumentException(String.format(caller
8726                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8727                            minAspectRatio, maxAspectRatio));
8728        }
8729
8730        // Truncate the number of actions if necessary
8731        params.truncateActions(getMaxNumPictureInPictureActions(token));
8732
8733        return r;
8734    }
8735
8736    // =========================================================
8737    // PROCESS INFO
8738    // =========================================================
8739
8740    static class ProcessInfoService extends IProcessInfoService.Stub {
8741        final ActivityManagerService mActivityManagerService;
8742        ProcessInfoService(ActivityManagerService activityManagerService) {
8743            mActivityManagerService = activityManagerService;
8744        }
8745
8746        @Override
8747        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8748            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8749                    /*in*/ pids, /*out*/ states, null);
8750        }
8751
8752        @Override
8753        public void getProcessStatesAndOomScoresFromPids(
8754                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8755            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8756                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8757        }
8758    }
8759
8760    /**
8761     * For each PID in the given input array, write the current process state
8762     * for that process into the states array, or -1 to indicate that no
8763     * process with the given PID exists. If scores array is provided, write
8764     * the oom score for the process into the scores array, with INVALID_ADJ
8765     * indicating the PID doesn't exist.
8766     */
8767    public void getProcessStatesAndOomScoresForPIDs(
8768            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8769        if (scores != null) {
8770            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8771                    "getProcessStatesAndOomScoresForPIDs()");
8772        }
8773
8774        if (pids == null) {
8775            throw new NullPointerException("pids");
8776        } else if (states == null) {
8777            throw new NullPointerException("states");
8778        } else if (pids.length != states.length) {
8779            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8780        } else if (scores != null && pids.length != scores.length) {
8781            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8782        }
8783
8784        synchronized (mPidsSelfLocked) {
8785            for (int i = 0; i < pids.length; i++) {
8786                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8787                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8788                        pr.curProcState;
8789                if (scores != null) {
8790                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8791                }
8792            }
8793        }
8794    }
8795
8796    // =========================================================
8797    // PERMISSIONS
8798    // =========================================================
8799
8800    static class PermissionController extends IPermissionController.Stub {
8801        ActivityManagerService mActivityManagerService;
8802        PermissionController(ActivityManagerService activityManagerService) {
8803            mActivityManagerService = activityManagerService;
8804        }
8805
8806        @Override
8807        public boolean checkPermission(String permission, int pid, int uid) {
8808            return mActivityManagerService.checkPermission(permission, pid,
8809                    uid) == PackageManager.PERMISSION_GRANTED;
8810        }
8811
8812        @Override
8813        public String[] getPackagesForUid(int uid) {
8814            return mActivityManagerService.mContext.getPackageManager()
8815                    .getPackagesForUid(uid);
8816        }
8817
8818        @Override
8819        public boolean isRuntimePermission(String permission) {
8820            try {
8821                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8822                        .getPermissionInfo(permission, 0);
8823                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8824                        == PermissionInfo.PROTECTION_DANGEROUS;
8825            } catch (NameNotFoundException nnfe) {
8826                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8827            }
8828            return false;
8829        }
8830
8831        @Override
8832        public int getPackageUid(String packageName, int flags) {
8833            try {
8834                return mActivityManagerService.mContext.getPackageManager()
8835                        .getPackageUid(packageName, flags);
8836            } catch (NameNotFoundException nnfe) {
8837                return -1;
8838            }
8839        }
8840    }
8841
8842    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8843        @Override
8844        public int checkComponentPermission(String permission, int pid, int uid,
8845                int owningUid, boolean exported) {
8846            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8847                    owningUid, exported);
8848        }
8849
8850        @Override
8851        public Object getAMSLock() {
8852            return ActivityManagerService.this;
8853        }
8854    }
8855
8856    int checkComponentPermission(String permission, int pid, int uid,
8857            int owningUid, boolean exported) {
8858        if (pid == MY_PID) {
8859            return PackageManager.PERMISSION_GRANTED;
8860        }
8861        return ActivityManager.checkComponentPermission(permission, uid,
8862                owningUid, exported);
8863    }
8864
8865    /**
8866     * As the only public entry point for permissions checking, this method
8867     * can enforce the semantic that requesting a check on a null global
8868     * permission is automatically denied.  (Internally a null permission
8869     * string is used when calling {@link #checkComponentPermission} in cases
8870     * when only uid-based security is needed.)
8871     *
8872     * This can be called with or without the global lock held.
8873     */
8874    @Override
8875    public int checkPermission(String permission, int pid, int uid) {
8876        if (permission == null) {
8877            return PackageManager.PERMISSION_DENIED;
8878        }
8879        return checkComponentPermission(permission, pid, uid, -1, true);
8880    }
8881
8882    @Override
8883    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8884        if (permission == null) {
8885            return PackageManager.PERMISSION_DENIED;
8886        }
8887
8888        // We might be performing an operation on behalf of an indirect binder
8889        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8890        // client identity accordingly before proceeding.
8891        Identity tlsIdentity = sCallerIdentity.get();
8892        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8893            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8894                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8895            uid = tlsIdentity.uid;
8896            pid = tlsIdentity.pid;
8897        }
8898
8899        return checkComponentPermission(permission, pid, uid, -1, true);
8900    }
8901
8902    /**
8903     * Binder IPC calls go through the public entry point.
8904     * This can be called with or without the global lock held.
8905     */
8906    int checkCallingPermission(String permission) {
8907        return checkPermission(permission,
8908                Binder.getCallingPid(),
8909                UserHandle.getAppId(Binder.getCallingUid()));
8910    }
8911
8912    /**
8913     * This can be called with or without the global lock held.
8914     */
8915    void enforceCallingPermission(String permission, String func) {
8916        if (checkCallingPermission(permission)
8917                == PackageManager.PERMISSION_GRANTED) {
8918            return;
8919        }
8920
8921        String msg = "Permission Denial: " + func + " from pid="
8922                + Binder.getCallingPid()
8923                + ", uid=" + Binder.getCallingUid()
8924                + " requires " + permission;
8925        Slog.w(TAG, msg);
8926        throw new SecurityException(msg);
8927    }
8928
8929    /**
8930     * This can be called with or without the global lock held.
8931     */
8932    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
8933        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
8934            enforceCallingPermission(permission, func);
8935        }
8936    }
8937
8938    /**
8939     * Determine if UID is holding permissions required to access {@link Uri} in
8940     * the given {@link ProviderInfo}. Final permission checking is always done
8941     * in {@link ContentProvider}.
8942     */
8943    private final boolean checkHoldingPermissionsLocked(
8944            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8945        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8946                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8947        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8948            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8949                    != PERMISSION_GRANTED) {
8950                return false;
8951            }
8952        }
8953        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8954    }
8955
8956    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8957            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8958        if (pi.applicationInfo.uid == uid) {
8959            return true;
8960        } else if (!pi.exported) {
8961            return false;
8962        }
8963
8964        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8965        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8966        try {
8967            // check if target holds top-level <provider> permissions
8968            if (!readMet && pi.readPermission != null && considerUidPermissions
8969                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8970                readMet = true;
8971            }
8972            if (!writeMet && pi.writePermission != null && considerUidPermissions
8973                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8974                writeMet = true;
8975            }
8976
8977            // track if unprotected read/write is allowed; any denied
8978            // <path-permission> below removes this ability
8979            boolean allowDefaultRead = pi.readPermission == null;
8980            boolean allowDefaultWrite = pi.writePermission == null;
8981
8982            // check if target holds any <path-permission> that match uri
8983            final PathPermission[] pps = pi.pathPermissions;
8984            if (pps != null) {
8985                final String path = grantUri.uri.getPath();
8986                int i = pps.length;
8987                while (i > 0 && (!readMet || !writeMet)) {
8988                    i--;
8989                    PathPermission pp = pps[i];
8990                    if (pp.match(path)) {
8991                        if (!readMet) {
8992                            final String pprperm = pp.getReadPermission();
8993                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8994                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8995                                    + ": match=" + pp.match(path)
8996                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8997                            if (pprperm != null) {
8998                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8999                                        == PERMISSION_GRANTED) {
9000                                    readMet = true;
9001                                } else {
9002                                    allowDefaultRead = false;
9003                                }
9004                            }
9005                        }
9006                        if (!writeMet) {
9007                            final String ppwperm = pp.getWritePermission();
9008                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9009                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
9010                                    + ": match=" + pp.match(path)
9011                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
9012                            if (ppwperm != null) {
9013                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
9014                                        == PERMISSION_GRANTED) {
9015                                    writeMet = true;
9016                                } else {
9017                                    allowDefaultWrite = false;
9018                                }
9019                            }
9020                        }
9021                    }
9022                }
9023            }
9024
9025            // grant unprotected <provider> read/write, if not blocked by
9026            // <path-permission> above
9027            if (allowDefaultRead) readMet = true;
9028            if (allowDefaultWrite) writeMet = true;
9029
9030        } catch (RemoteException e) {
9031            return false;
9032        }
9033
9034        return readMet && writeMet;
9035    }
9036
9037    public boolean isAppStartModeDisabled(int uid, String packageName) {
9038        synchronized (this) {
9039            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
9040                    == ActivityManager.APP_START_MODE_DISABLED;
9041        }
9042    }
9043
9044    // Unified app-op and target sdk check
9045    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9046        // Apps that target O+ are always subject to background check
9047        if (packageTargetSdk >= Build.VERSION_CODES.O) {
9048            if (DEBUG_BACKGROUND_CHECK) {
9049                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
9050            }
9051            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9052        }
9053        // ...and legacy apps get an AppOp check
9054        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
9055                uid, packageName);
9056        if (DEBUG_BACKGROUND_CHECK) {
9057            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
9058        }
9059        switch (appop) {
9060            case AppOpsManager.MODE_ALLOWED:
9061                // If force-background-check is enabled, restrict all apps that aren't whitelisted.
9062                if (mForceBackgroundCheck &&
9063                        !UserHandle.isCore(uid) &&
9064                        !isOnDeviceIdleWhitelistLocked(uid)) {
9065                    if (DEBUG_BACKGROUND_CHECK) {
9066                        Slog.i(TAG, "Force background check: " +
9067                                uid + "/" + packageName + " restricted");
9068                    }
9069                    return ActivityManager.APP_START_MODE_DELAYED;
9070                }
9071                return ActivityManager.APP_START_MODE_NORMAL;
9072            case AppOpsManager.MODE_IGNORED:
9073                return ActivityManager.APP_START_MODE_DELAYED;
9074            default:
9075                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9076        }
9077    }
9078
9079    // Service launch is available to apps with run-in-background exemptions but
9080    // some other background operations are not.  If we're doing a check
9081    // of service-launch policy, allow those callers to proceed unrestricted.
9082    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9083        // Persistent app?
9084        if (mPackageManagerInt.isPackagePersistent(packageName)) {
9085            if (DEBUG_BACKGROUND_CHECK) {
9086                Slog.i(TAG, "App " + uid + "/" + packageName
9087                        + " is persistent; not restricted in background");
9088            }
9089            return ActivityManager.APP_START_MODE_NORMAL;
9090        }
9091
9092        // Non-persistent but background whitelisted?
9093        if (uidOnBackgroundWhitelist(uid)) {
9094            if (DEBUG_BACKGROUND_CHECK) {
9095                Slog.i(TAG, "App " + uid + "/" + packageName
9096                        + " on background whitelist; not restricted in background");
9097            }
9098            return ActivityManager.APP_START_MODE_NORMAL;
9099        }
9100
9101        // Is this app on the battery whitelist?
9102        if (isOnDeviceIdleWhitelistLocked(uid)) {
9103            if (DEBUG_BACKGROUND_CHECK) {
9104                Slog.i(TAG, "App " + uid + "/" + packageName
9105                        + " on idle whitelist; not restricted in background");
9106            }
9107            return ActivityManager.APP_START_MODE_NORMAL;
9108        }
9109
9110        // None of the service-policy criteria apply, so we apply the common criteria
9111        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
9112    }
9113
9114    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
9115            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
9116        UidRecord uidRec = mActiveUids.get(uid);
9117        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
9118                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
9119                + (uidRec != null ? uidRec.idle : false));
9120        if (uidRec == null || alwaysRestrict || uidRec.idle) {
9121            boolean ephemeral;
9122            if (uidRec == null) {
9123                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
9124                        UserHandle.getUserId(uid), packageName);
9125            } else {
9126                ephemeral = uidRec.ephemeral;
9127            }
9128
9129            if (ephemeral) {
9130                // We are hard-core about ephemeral apps not running in the background.
9131                return ActivityManager.APP_START_MODE_DISABLED;
9132            } else {
9133                if (disabledOnly) {
9134                    // The caller is only interested in whether app starts are completely
9135                    // disabled for the given package (that is, it is an instant app).  So
9136                    // we don't need to go further, which is all just seeing if we should
9137                    // apply a "delayed" mode for a regular app.
9138                    return ActivityManager.APP_START_MODE_NORMAL;
9139                }
9140                final int startMode = (alwaysRestrict)
9141                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
9142                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
9143                                packageTargetSdk);
9144                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
9145                        + " pkg=" + packageName + " startMode=" + startMode
9146                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
9147                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
9148                    // This is an old app that has been forced into a "compatible as possible"
9149                    // mode of background check.  To increase compatibility, we will allow other
9150                    // foreground apps to cause its services to start.
9151                    if (callingPid >= 0) {
9152                        ProcessRecord proc;
9153                        synchronized (mPidsSelfLocked) {
9154                            proc = mPidsSelfLocked.get(callingPid);
9155                        }
9156                        if (proc != null &&
9157                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
9158                            // Whoever is instigating this is in the foreground, so we will allow it
9159                            // to go through.
9160                            return ActivityManager.APP_START_MODE_NORMAL;
9161                        }
9162                    }
9163                }
9164                return startMode;
9165            }
9166        }
9167        return ActivityManager.APP_START_MODE_NORMAL;
9168    }
9169
9170    /**
9171     * @return whether a UID is in the system, user or temp doze whitelist.
9172     */
9173    boolean isOnDeviceIdleWhitelistLocked(int uid) {
9174        final int appId = UserHandle.getAppId(uid);
9175        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
9176                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9177                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9178    }
9179
9180    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9181        ProviderInfo pi = null;
9182        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9183        if (cpr != null) {
9184            pi = cpr.info;
9185        } else {
9186            try {
9187                pi = AppGlobals.getPackageManager().resolveContentProvider(
9188                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9189                        userHandle);
9190            } catch (RemoteException ex) {
9191            }
9192        }
9193        return pi;
9194    }
9195
9196    void grantEphemeralAccessLocked(int userId, Intent intent,
9197            int targetAppId, int ephemeralAppId) {
9198        getPackageManagerInternalLocked().
9199                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
9200    }
9201
9202    @GuardedBy("this")
9203    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
9204        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9205        if (targetUris != null) {
9206            return targetUris.get(grantUri);
9207        }
9208        return null;
9209    }
9210
9211    @GuardedBy("this")
9212    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
9213            String targetPkg, int targetUid, GrantUri grantUri) {
9214        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9215        if (targetUris == null) {
9216            targetUris = Maps.newArrayMap();
9217            mGrantedUriPermissions.put(targetUid, targetUris);
9218        }
9219
9220        UriPermission perm = targetUris.get(grantUri);
9221        if (perm == null) {
9222            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9223            targetUris.put(grantUri, perm);
9224        }
9225
9226        return perm;
9227    }
9228
9229    @GuardedBy("this")
9230    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
9231            final int modeFlags) {
9232        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
9233        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9234                : UriPermission.STRENGTH_OWNED;
9235
9236        // Root gets to do everything.
9237        if (uid == 0) {
9238            return true;
9239        }
9240
9241        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9242        if (perms == null) return false;
9243
9244        // First look for exact match
9245        final UriPermission exactPerm = perms.get(grantUri);
9246        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9247            return true;
9248        }
9249
9250        // No exact match, look for prefixes
9251        final int N = perms.size();
9252        for (int i = 0; i < N; i++) {
9253            final UriPermission perm = perms.valueAt(i);
9254            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9255                    && perm.getStrength(modeFlags) >= minStrength) {
9256                return true;
9257            }
9258        }
9259
9260        return false;
9261    }
9262
9263    /**
9264     * @param uri This uri must NOT contain an embedded userId.
9265     * @param userId The userId in which the uri is to be resolved.
9266     */
9267    @Override
9268    public int checkUriPermission(Uri uri, int pid, int uid,
9269            final int modeFlags, int userId, IBinder callerToken) {
9270        enforceNotIsolatedCaller("checkUriPermission");
9271
9272        // Another redirected-binder-call permissions check as in
9273        // {@link checkPermissionWithToken}.
9274        Identity tlsIdentity = sCallerIdentity.get();
9275        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9276            uid = tlsIdentity.uid;
9277            pid = tlsIdentity.pid;
9278        }
9279
9280        // Our own process gets to do everything.
9281        if (pid == MY_PID) {
9282            return PackageManager.PERMISSION_GRANTED;
9283        }
9284        synchronized (this) {
9285            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9286                    ? PackageManager.PERMISSION_GRANTED
9287                    : PackageManager.PERMISSION_DENIED;
9288        }
9289    }
9290
9291    /**
9292     * Check if the targetPkg can be granted permission to access uri by
9293     * the callingUid using the given modeFlags.  Throws a security exception
9294     * if callingUid is not allowed to do this.  Returns the uid of the target
9295     * if the URI permission grant should be performed; returns -1 if it is not
9296     * needed (for example targetPkg already has permission to access the URI).
9297     * If you already know the uid of the target, you can supply it in
9298     * lastTargetUid else set that to -1.
9299     */
9300    @GuardedBy("this")
9301    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9302            final int modeFlags, int lastTargetUid) {
9303        if (!Intent.isAccessUriMode(modeFlags)) {
9304            return -1;
9305        }
9306
9307        if (targetPkg != null) {
9308            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9309                    "Checking grant " + targetPkg + " permission to " + grantUri);
9310        }
9311
9312        final IPackageManager pm = AppGlobals.getPackageManager();
9313
9314        // If this is not a content: uri, we can't do anything with it.
9315        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9316            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9317                    "Can't grant URI permission for non-content URI: " + grantUri);
9318            return -1;
9319        }
9320
9321        // Bail early if system is trying to hand out permissions directly; it
9322        // must always grant permissions on behalf of someone explicit.
9323        final int callingAppId = UserHandle.getAppId(callingUid);
9324        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9325            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9326                // Exempted authority for
9327                // 1. cropping user photos and sharing a generated license html
9328                //    file in Settings app
9329                // 2. sharing a generated license html file in TvSettings app
9330            } else {
9331                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9332                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9333                return -1;
9334            }
9335        }
9336
9337        final String authority = grantUri.uri.getAuthority();
9338        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9339                MATCH_DEBUG_TRIAGED_MISSING);
9340        if (pi == null) {
9341            Slog.w(TAG, "No content provider found for permission check: " +
9342                    grantUri.uri.toSafeString());
9343            return -1;
9344        }
9345
9346        int targetUid = lastTargetUid;
9347        if (targetUid < 0 && targetPkg != null) {
9348            try {
9349                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9350                        UserHandle.getUserId(callingUid));
9351                if (targetUid < 0) {
9352                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9353                            "Can't grant URI permission no uid for: " + targetPkg);
9354                    return -1;
9355                }
9356            } catch (RemoteException ex) {
9357                return -1;
9358            }
9359        }
9360
9361        // If we're extending a persistable grant, then we always need to create
9362        // the grant data structure so that take/release APIs work
9363        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9364            return targetUid;
9365        }
9366
9367        if (targetUid >= 0) {
9368            // First...  does the target actually need this permission?
9369            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9370                // No need to grant the target this permission.
9371                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9372                        "Target " + targetPkg + " already has full permission to " + grantUri);
9373                return -1;
9374            }
9375        } else {
9376            // First...  there is no target package, so can anyone access it?
9377            boolean allowed = pi.exported;
9378            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9379                if (pi.readPermission != null) {
9380                    allowed = false;
9381                }
9382            }
9383            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9384                if (pi.writePermission != null) {
9385                    allowed = false;
9386                }
9387            }
9388            if (allowed) {
9389                return -1;
9390            }
9391        }
9392
9393        /* There is a special cross user grant if:
9394         * - The target is on another user.
9395         * - Apps on the current user can access the uri without any uid permissions.
9396         * In this case, we grant a uri permission, even if the ContentProvider does not normally
9397         * grant uri permissions.
9398         */
9399        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9400                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9401                modeFlags, false /*without considering the uid permissions*/);
9402
9403        // Second...  is the provider allowing granting of URI permissions?
9404        if (!specialCrossUserGrant) {
9405            if (!pi.grantUriPermissions) {
9406                throw new SecurityException("Provider " + pi.packageName
9407                        + "/" + pi.name
9408                        + " does not allow granting of Uri permissions (uri "
9409                        + grantUri + ")");
9410            }
9411            if (pi.uriPermissionPatterns != null) {
9412                final int N = pi.uriPermissionPatterns.length;
9413                boolean allowed = false;
9414                for (int i=0; i<N; i++) {
9415                    if (pi.uriPermissionPatterns[i] != null
9416                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9417                        allowed = true;
9418                        break;
9419                    }
9420                }
9421                if (!allowed) {
9422                    throw new SecurityException("Provider " + pi.packageName
9423                            + "/" + pi.name
9424                            + " does not allow granting of permission to path of Uri "
9425                            + grantUri);
9426                }
9427            }
9428        }
9429
9430        // Third...  does the caller itself have permission to access
9431        // this uri?
9432        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9433            // Require they hold a strong enough Uri permission
9434            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9435                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9436                    throw new SecurityException(
9437                            "UID " + callingUid + " does not have permission to " + grantUri
9438                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9439                                    + "or related APIs");
9440                } else {
9441                    throw new SecurityException(
9442                            "UID " + callingUid + " does not have permission to " + grantUri);
9443                }
9444            }
9445        }
9446        return targetUid;
9447    }
9448
9449    /**
9450     * @param uri This uri must NOT contain an embedded userId.
9451     * @param userId The userId in which the uri is to be resolved.
9452     */
9453    @Override
9454    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9455            final int modeFlags, int userId) {
9456        enforceNotIsolatedCaller("checkGrantUriPermission");
9457        synchronized(this) {
9458            return checkGrantUriPermissionLocked(callingUid, targetPkg,
9459                    new GrantUri(userId, uri, false), modeFlags, -1);
9460        }
9461    }
9462
9463    @GuardedBy("this")
9464    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9465            final int modeFlags, UriPermissionOwner owner) {
9466        if (!Intent.isAccessUriMode(modeFlags)) {
9467            return;
9468        }
9469
9470        // So here we are: the caller has the assumed permission
9471        // to the uri, and the target doesn't.  Let's now give this to
9472        // the target.
9473
9474        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9475                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9476
9477        final String authority = grantUri.uri.getAuthority();
9478        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9479                MATCH_DEBUG_TRIAGED_MISSING);
9480        if (pi == null) {
9481            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9482            return;
9483        }
9484
9485        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9486            grantUri.prefix = true;
9487        }
9488        final UriPermission perm = findOrCreateUriPermissionLocked(
9489                pi.packageName, targetPkg, targetUid, grantUri);
9490        perm.grantModes(modeFlags, owner);
9491    }
9492
9493    @GuardedBy("this")
9494    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9495            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9496        if (targetPkg == null) {
9497            throw new NullPointerException("targetPkg");
9498        }
9499        int targetUid;
9500        final IPackageManager pm = AppGlobals.getPackageManager();
9501        try {
9502            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9503        } catch (RemoteException ex) {
9504            return;
9505        }
9506
9507        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9508                targetUid);
9509        if (targetUid < 0) {
9510            return;
9511        }
9512
9513        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9514                owner);
9515    }
9516
9517    static class NeededUriGrants extends ArrayList<GrantUri> {
9518        final String targetPkg;
9519        final int targetUid;
9520        final int flags;
9521
9522        NeededUriGrants(String targetPkg, int targetUid, int flags) {
9523            this.targetPkg = targetPkg;
9524            this.targetUid = targetUid;
9525            this.flags = flags;
9526        }
9527
9528        void writeToProto(ProtoOutputStream proto, long fieldId) {
9529            long token = proto.start(fieldId);
9530            proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9531            proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9532            proto.write(NeededUriGrantsProto.FLAGS, flags);
9533
9534            final int N = this.size();
9535            for (int i=0; i<N; i++) {
9536                this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9537            }
9538            proto.end(token);
9539        }
9540    }
9541
9542    /**
9543     * Like checkGrantUriPermissionLocked, but takes an Intent.
9544     */
9545    @GuardedBy("this")
9546    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9547            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9548        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9549                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9550                + " clip=" + (intent != null ? intent.getClipData() : null)
9551                + " from " + intent + "; flags=0x"
9552                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9553
9554        if (targetPkg == null) {
9555            throw new NullPointerException("targetPkg");
9556        }
9557
9558        if (intent == null) {
9559            return null;
9560        }
9561        Uri data = intent.getData();
9562        ClipData clip = intent.getClipData();
9563        if (data == null && clip == null) {
9564            return null;
9565        }
9566        // Default userId for uris in the intent (if they don't specify it themselves)
9567        int contentUserHint = intent.getContentUserHint();
9568        if (contentUserHint == UserHandle.USER_CURRENT) {
9569            contentUserHint = UserHandle.getUserId(callingUid);
9570        }
9571        final IPackageManager pm = AppGlobals.getPackageManager();
9572        int targetUid;
9573        if (needed != null) {
9574            targetUid = needed.targetUid;
9575        } else {
9576            try {
9577                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9578                        targetUserId);
9579            } catch (RemoteException ex) {
9580                return null;
9581            }
9582            if (targetUid < 0) {
9583                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9584                        "Can't grant URI permission no uid for: " + targetPkg
9585                        + " on user " + targetUserId);
9586                return null;
9587            }
9588        }
9589        if (data != null) {
9590            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9591            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9592                    targetUid);
9593            if (targetUid > 0) {
9594                if (needed == null) {
9595                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9596                }
9597                needed.add(grantUri);
9598            }
9599        }
9600        if (clip != null) {
9601            for (int i=0; i<clip.getItemCount(); i++) {
9602                Uri uri = clip.getItemAt(i).getUri();
9603                if (uri != null) {
9604                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9605                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9606                            targetUid);
9607                    if (targetUid > 0) {
9608                        if (needed == null) {
9609                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9610                        }
9611                        needed.add(grantUri);
9612                    }
9613                } else {
9614                    Intent clipIntent = clip.getItemAt(i).getIntent();
9615                    if (clipIntent != null) {
9616                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9617                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9618                        if (newNeeded != null) {
9619                            needed = newNeeded;
9620                        }
9621                    }
9622                }
9623            }
9624        }
9625
9626        return needed;
9627    }
9628
9629    /**
9630     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9631     */
9632    @GuardedBy("this")
9633    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9634            UriPermissionOwner owner) {
9635        if (needed != null) {
9636            for (int i=0; i<needed.size(); i++) {
9637                GrantUri grantUri = needed.get(i);
9638                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9639                        grantUri, needed.flags, owner);
9640            }
9641        }
9642    }
9643
9644    @GuardedBy("this")
9645    void grantUriPermissionFromIntentLocked(int callingUid,
9646            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9647        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9648                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9649        if (needed == null) {
9650            return;
9651        }
9652
9653        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9654    }
9655
9656    /**
9657     * @param uri This uri must NOT contain an embedded userId.
9658     * @param userId The userId in which the uri is to be resolved.
9659     */
9660    @Override
9661    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9662            final int modeFlags, int userId) {
9663        enforceNotIsolatedCaller("grantUriPermission");
9664        GrantUri grantUri = new GrantUri(userId, uri, false);
9665        synchronized(this) {
9666            final ProcessRecord r = getRecordForAppLocked(caller);
9667            if (r == null) {
9668                throw new SecurityException("Unable to find app for caller "
9669                        + caller
9670                        + " when granting permission to uri " + grantUri);
9671            }
9672            if (targetPkg == null) {
9673                throw new IllegalArgumentException("null target");
9674            }
9675            if (grantUri == null) {
9676                throw new IllegalArgumentException("null uri");
9677            }
9678
9679            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9680                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9681                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9682                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9683
9684            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9685                    UserHandle.getUserId(r.uid));
9686        }
9687    }
9688
9689    @GuardedBy("this")
9690    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9691        if (perm.modeFlags == 0) {
9692            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9693                    perm.targetUid);
9694            if (perms != null) {
9695                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9696                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9697
9698                perms.remove(perm.uri);
9699                if (perms.isEmpty()) {
9700                    mGrantedUriPermissions.remove(perm.targetUid);
9701                }
9702            }
9703        }
9704    }
9705
9706    @GuardedBy("this")
9707    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9708            final int modeFlags) {
9709        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9710                "Revoking all granted permissions to " + grantUri);
9711
9712        final IPackageManager pm = AppGlobals.getPackageManager();
9713        final String authority = grantUri.uri.getAuthority();
9714        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9715                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9716        if (pi == null) {
9717            Slog.w(TAG, "No content provider found for permission revoke: "
9718                    + grantUri.toSafeString());
9719            return;
9720        }
9721
9722        // Does the caller have this permission on the URI?
9723        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9724            // If they don't have direct access to the URI, then revoke any
9725            // ownerless URI permissions that have been granted to them.
9726            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9727            if (perms != null) {
9728                boolean persistChanged = false;
9729                for (int i = perms.size()-1; i >= 0; i--) {
9730                    final UriPermission perm = perms.valueAt(i);
9731                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9732                        continue;
9733                    }
9734                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9735                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9736                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9737                                "Revoking non-owned " + perm.targetUid
9738                                + " permission to " + perm.uri);
9739                        persistChanged |= perm.revokeModes(
9740                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9741                        if (perm.modeFlags == 0) {
9742                            perms.removeAt(i);
9743                        }
9744                    }
9745                }
9746                if (perms.isEmpty()) {
9747                    mGrantedUriPermissions.remove(callingUid);
9748                }
9749                if (persistChanged) {
9750                    schedulePersistUriGrants();
9751                }
9752            }
9753            return;
9754        }
9755
9756        boolean persistChanged = false;
9757
9758        // Go through all of the permissions and remove any that match.
9759        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9760            final int targetUid = mGrantedUriPermissions.keyAt(i);
9761            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9762
9763            for (int j = perms.size()-1; j >= 0; j--) {
9764                final UriPermission perm = perms.valueAt(j);
9765                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9766                    continue;
9767                }
9768                if (perm.uri.sourceUserId == grantUri.sourceUserId
9769                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9770                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9771                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9772                    persistChanged |= perm.revokeModes(
9773                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9774                            targetPackage == null);
9775                    if (perm.modeFlags == 0) {
9776                        perms.removeAt(j);
9777                    }
9778                }
9779            }
9780
9781            if (perms.isEmpty()) {
9782                mGrantedUriPermissions.removeAt(i);
9783            }
9784        }
9785
9786        if (persistChanged) {
9787            schedulePersistUriGrants();
9788        }
9789    }
9790
9791    /**
9792     * @param uri This uri must NOT contain an embedded userId.
9793     * @param userId The userId in which the uri is to be resolved.
9794     */
9795    @Override
9796    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9797            final int modeFlags, int userId) {
9798        enforceNotIsolatedCaller("revokeUriPermission");
9799        synchronized(this) {
9800            final ProcessRecord r = getRecordForAppLocked(caller);
9801            if (r == null) {
9802                throw new SecurityException("Unable to find app for caller "
9803                        + caller
9804                        + " when revoking permission to uri " + uri);
9805            }
9806            if (uri == null) {
9807                Slog.w(TAG, "revokeUriPermission: null uri");
9808                return;
9809            }
9810
9811            if (!Intent.isAccessUriMode(modeFlags)) {
9812                return;
9813            }
9814
9815            final String authority = uri.getAuthority();
9816            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9817                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9818            if (pi == null) {
9819                Slog.w(TAG, "No content provider found for permission revoke: "
9820                        + uri.toSafeString());
9821                return;
9822            }
9823
9824            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9825                    modeFlags);
9826        }
9827    }
9828
9829    /**
9830     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9831     * given package.
9832     *
9833     * @param packageName Package name to match, or {@code null} to apply to all
9834     *            packages.
9835     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9836     *            to all users.
9837     * @param persistable If persistable grants should be removed.
9838     * @param targetOnly When {@code true}, only remove permissions where the app is the target,
9839     * not source.
9840     */
9841    @GuardedBy("this")
9842    private void removeUriPermissionsForPackageLocked(
9843            String packageName, int userHandle, boolean persistable, boolean targetOnly) {
9844        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9845            throw new IllegalArgumentException("Must narrow by either package or user");
9846        }
9847
9848        boolean persistChanged = false;
9849
9850        int N = mGrantedUriPermissions.size();
9851        for (int i = 0; i < N; i++) {
9852            final int targetUid = mGrantedUriPermissions.keyAt(i);
9853            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9854
9855            // Only inspect grants matching user
9856            if (userHandle == UserHandle.USER_ALL
9857                    || userHandle == UserHandle.getUserId(targetUid)) {
9858                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9859                    final UriPermission perm = it.next();
9860
9861                    // Only inspect grants matching package
9862                    if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
9863                            || perm.targetPkg.equals(packageName)) {
9864                        // Hacky solution as part of fixing a security bug; ignore
9865                        // grants associated with DownloadManager so we don't have
9866                        // to immediately launch it to regrant the permissions
9867                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9868                                && !persistable) continue;
9869
9870                        persistChanged |= perm.revokeModes(persistable
9871                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9872
9873                        // Only remove when no modes remain; any persisted grants
9874                        // will keep this alive.
9875                        if (perm.modeFlags == 0) {
9876                            it.remove();
9877                        }
9878                    }
9879                }
9880
9881                if (perms.isEmpty()) {
9882                    mGrantedUriPermissions.remove(targetUid);
9883                    N--;
9884                    i--;
9885                }
9886            }
9887        }
9888
9889        if (persistChanged) {
9890            schedulePersistUriGrants();
9891        }
9892    }
9893
9894    @Override
9895    public IBinder newUriPermissionOwner(String name) {
9896        enforceNotIsolatedCaller("newUriPermissionOwner");
9897        synchronized(this) {
9898            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9899            return owner.getExternalTokenLocked();
9900        }
9901    }
9902
9903    @Override
9904    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9905        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9906        synchronized(this) {
9907            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9908            if (r == null) {
9909                throw new IllegalArgumentException("Activity does not exist; token="
9910                        + activityToken);
9911            }
9912            return r.getUriPermissionsLocked().getExternalTokenLocked();
9913        }
9914    }
9915    /**
9916     * @param uri This uri must NOT contain an embedded userId.
9917     * @param sourceUserId The userId in which the uri is to be resolved.
9918     * @param targetUserId The userId of the app that receives the grant.
9919     */
9920    @Override
9921    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9922            final int modeFlags, int sourceUserId, int targetUserId) {
9923        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9924                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9925                "grantUriPermissionFromOwner", null);
9926        synchronized(this) {
9927            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9928            if (owner == null) {
9929                throw new IllegalArgumentException("Unknown owner: " + token);
9930            }
9931            if (fromUid != Binder.getCallingUid()) {
9932                if (Binder.getCallingUid() != myUid()) {
9933                    // Only system code can grant URI permissions on behalf
9934                    // of other users.
9935                    throw new SecurityException("nice try");
9936                }
9937            }
9938            if (targetPkg == null) {
9939                throw new IllegalArgumentException("null target");
9940            }
9941            if (uri == null) {
9942                throw new IllegalArgumentException("null uri");
9943            }
9944
9945            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9946                    modeFlags, owner, targetUserId);
9947        }
9948    }
9949
9950    /**
9951     * @param uri This uri must NOT contain an embedded userId.
9952     * @param userId The userId in which the uri is to be resolved.
9953     */
9954    @Override
9955    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9956        synchronized(this) {
9957            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9958            if (owner == null) {
9959                throw new IllegalArgumentException("Unknown owner: " + token);
9960            }
9961
9962            if (uri == null) {
9963                owner.removeUriPermissionsLocked(mode);
9964            } else {
9965                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9966                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9967            }
9968        }
9969    }
9970
9971    private void schedulePersistUriGrants() {
9972        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9973            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9974                    10 * DateUtils.SECOND_IN_MILLIS);
9975        }
9976    }
9977
9978    private void writeGrantedUriPermissions() {
9979        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9980
9981        final long startTime = SystemClock.uptimeMillis();
9982
9983        // Snapshot permissions so we can persist without lock
9984        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9985        synchronized (this) {
9986            final int size = mGrantedUriPermissions.size();
9987            for (int i = 0; i < size; i++) {
9988                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9989                for (UriPermission perm : perms.values()) {
9990                    if (perm.persistedModeFlags != 0) {
9991                        persist.add(perm.snapshot());
9992                    }
9993                }
9994            }
9995        }
9996
9997        FileOutputStream fos = null;
9998        try {
9999            fos = mGrantFile.startWrite(startTime);
10000
10001            XmlSerializer out = new FastXmlSerializer();
10002            out.setOutput(fos, StandardCharsets.UTF_8.name());
10003            out.startDocument(null, true);
10004            out.startTag(null, TAG_URI_GRANTS);
10005            for (UriPermission.Snapshot perm : persist) {
10006                out.startTag(null, TAG_URI_GRANT);
10007                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
10008                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
10009                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
10010                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
10011                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
10012                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
10013                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
10014                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
10015                out.endTag(null, TAG_URI_GRANT);
10016            }
10017            out.endTag(null, TAG_URI_GRANTS);
10018            out.endDocument();
10019
10020            mGrantFile.finishWrite(fos);
10021        } catch (IOException e) {
10022            if (fos != null) {
10023                mGrantFile.failWrite(fos);
10024            }
10025        }
10026    }
10027
10028    @GuardedBy("this")
10029    private void readGrantedUriPermissionsLocked() {
10030        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
10031
10032        final long now = System.currentTimeMillis();
10033
10034        FileInputStream fis = null;
10035        try {
10036            fis = mGrantFile.openRead();
10037            final XmlPullParser in = Xml.newPullParser();
10038            in.setInput(fis, StandardCharsets.UTF_8.name());
10039
10040            int type;
10041            while ((type = in.next()) != END_DOCUMENT) {
10042                final String tag = in.getName();
10043                if (type == START_TAG) {
10044                    if (TAG_URI_GRANT.equals(tag)) {
10045                        final int sourceUserId;
10046                        final int targetUserId;
10047                        final int userHandle = readIntAttribute(in,
10048                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
10049                        if (userHandle != UserHandle.USER_NULL) {
10050                            // For backwards compatibility.
10051                            sourceUserId = userHandle;
10052                            targetUserId = userHandle;
10053                        } else {
10054                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
10055                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
10056                        }
10057                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
10058                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
10059                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
10060                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
10061                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
10062                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
10063
10064                        // Sanity check that provider still belongs to source package
10065                        // Both direct boot aware and unaware packages are fine as we
10066                        // will do filtering at query time to avoid multiple parsing.
10067                        final ProviderInfo pi = getProviderInfoLocked(
10068                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
10069                                        | MATCH_DIRECT_BOOT_UNAWARE);
10070                        if (pi != null && sourcePkg.equals(pi.packageName)) {
10071                            int targetUid = -1;
10072                            try {
10073                                targetUid = AppGlobals.getPackageManager().getPackageUid(
10074                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
10075                            } catch (RemoteException e) {
10076                            }
10077                            if (targetUid != -1) {
10078                                final UriPermission perm = findOrCreateUriPermissionLocked(
10079                                        sourcePkg, targetPkg, targetUid,
10080                                        new GrantUri(sourceUserId, uri, prefix));
10081                                perm.initPersistedModes(modeFlags, createdTime);
10082                            }
10083                        } else {
10084                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
10085                                    + " but instead found " + pi);
10086                        }
10087                    }
10088                }
10089            }
10090        } catch (FileNotFoundException e) {
10091            // Missing grants is okay
10092        } catch (IOException e) {
10093            Slog.wtf(TAG, "Failed reading Uri grants", e);
10094        } catch (XmlPullParserException e) {
10095            Slog.wtf(TAG, "Failed reading Uri grants", e);
10096        } finally {
10097            IoUtils.closeQuietly(fis);
10098        }
10099    }
10100
10101    /**
10102     * @param uri This uri must NOT contain an embedded userId.
10103     * @param userId The userId in which the uri is to be resolved.
10104     */
10105    @Override
10106    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
10107        enforceNotIsolatedCaller("takePersistableUriPermission");
10108
10109        Preconditions.checkFlagsArgument(modeFlags,
10110                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10111
10112        synchronized (this) {
10113            final int callingUid = Binder.getCallingUid();
10114            boolean persistChanged = false;
10115            GrantUri grantUri = new GrantUri(userId, uri, false);
10116
10117            UriPermission exactPerm = findUriPermissionLocked(callingUid, grantUri);
10118            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
10119                    new GrantUri(userId, uri, true));
10120
10121            final boolean exactValid = (exactPerm != null)
10122                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
10123            final boolean prefixValid = (prefixPerm != null)
10124                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
10125
10126            if (!(exactValid || prefixValid)) {
10127                throw new SecurityException("No persistable permission grants found for UID "
10128                        + callingUid + " and Uri " + grantUri.toSafeString());
10129            }
10130
10131            if (exactValid) {
10132                persistChanged |= exactPerm.takePersistableModes(modeFlags);
10133            }
10134            if (prefixValid) {
10135                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
10136            }
10137
10138            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
10139
10140            if (persistChanged) {
10141                schedulePersistUriGrants();
10142            }
10143        }
10144    }
10145
10146    /**
10147     * @param uri This uri must NOT contain an embedded userId.
10148     * @param userId The userId in which the uri is to be resolved.
10149     */
10150    @Override
10151    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
10152        enforceNotIsolatedCaller("releasePersistableUriPermission");
10153
10154        Preconditions.checkFlagsArgument(modeFlags,
10155                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10156
10157        synchronized (this) {
10158            final int callingUid = Binder.getCallingUid();
10159            boolean persistChanged = false;
10160
10161            UriPermission exactPerm = findUriPermissionLocked(callingUid,
10162                    new GrantUri(userId, uri, false));
10163            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
10164                    new GrantUri(userId, uri, true));
10165            if (exactPerm == null && prefixPerm == null) {
10166                throw new SecurityException("No permission grants found for UID " + callingUid
10167                        + " and Uri " + uri.toSafeString());
10168            }
10169
10170            if (exactPerm != null) {
10171                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10172                removeUriPermissionIfNeededLocked(exactPerm);
10173            }
10174            if (prefixPerm != null) {
10175                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10176                removeUriPermissionIfNeededLocked(prefixPerm);
10177            }
10178
10179            if (persistChanged) {
10180                schedulePersistUriGrants();
10181            }
10182        }
10183    }
10184
10185    /**
10186     * Prune any older {@link UriPermission} for the given UID until outstanding
10187     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10188     *
10189     * @return if any mutations occured that require persisting.
10190     */
10191    @GuardedBy("this")
10192    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
10193        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
10194        if (perms == null) return false;
10195        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
10196
10197        final ArrayList<UriPermission> persisted = Lists.newArrayList();
10198        for (UriPermission perm : perms.values()) {
10199            if (perm.persistedModeFlags != 0) {
10200                persisted.add(perm);
10201            }
10202        }
10203
10204        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10205        if (trimCount <= 0) return false;
10206
10207        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10208        for (int i = 0; i < trimCount; i++) {
10209            final UriPermission perm = persisted.get(i);
10210
10211            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10212                    "Trimming grant created at " + perm.persistedCreateTime);
10213
10214            perm.releasePersistableModes(~0);
10215            removeUriPermissionIfNeededLocked(perm);
10216        }
10217
10218        return true;
10219    }
10220
10221    @Override
10222    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10223            String packageName, boolean incoming) {
10224        enforceNotIsolatedCaller("getPersistedUriPermissions");
10225        Preconditions.checkNotNull(packageName, "packageName");
10226
10227        final int callingUid = Binder.getCallingUid();
10228        final int callingUserId = UserHandle.getUserId(callingUid);
10229        final IPackageManager pm = AppGlobals.getPackageManager();
10230        try {
10231            final int packageUid = pm.getPackageUid(packageName,
10232                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
10233            if (packageUid != callingUid) {
10234                throw new SecurityException(
10235                        "Package " + packageName + " does not belong to calling UID " + callingUid);
10236            }
10237        } catch (RemoteException e) {
10238            throw new SecurityException("Failed to verify package name ownership");
10239        }
10240
10241        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10242        synchronized (this) {
10243            if (incoming) {
10244                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10245                        callingUid);
10246                if (perms == null) {
10247                    Slog.w(TAG, "No permission grants found for " + packageName);
10248                } else {
10249                    for (int j = 0; j < perms.size(); j++) {
10250                        final UriPermission perm = perms.valueAt(j);
10251                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10252                            result.add(perm.buildPersistedPublicApiObject());
10253                        }
10254                    }
10255                }
10256            } else {
10257                final int size = mGrantedUriPermissions.size();
10258                for (int i = 0; i < size; i++) {
10259                    final ArrayMap<GrantUri, UriPermission> perms =
10260                            mGrantedUriPermissions.valueAt(i);
10261                    for (int j = 0; j < perms.size(); j++) {
10262                        final UriPermission perm = perms.valueAt(j);
10263                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10264                            result.add(perm.buildPersistedPublicApiObject());
10265                        }
10266                    }
10267                }
10268            }
10269        }
10270        return new ParceledListSlice<android.content.UriPermission>(result);
10271    }
10272
10273    @Override
10274    public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
10275            @Nullable String packageName, int userId) {
10276        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10277                "getGrantedUriPermissions");
10278
10279        final List<GrantedUriPermission> result = new ArrayList<>();
10280        synchronized (this) {
10281            final int size = mGrantedUriPermissions.size();
10282            for (int i = 0; i < size; i++) {
10283                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10284                for (int j = 0; j < perms.size(); j++) {
10285                    final UriPermission perm = perms.valueAt(j);
10286                    if ((packageName == null || packageName.equals(perm.targetPkg))
10287                            && perm.targetUserId == userId
10288                            && perm.persistedModeFlags != 0) {
10289                        result.add(perm.buildGrantedUriPermission());
10290                    }
10291                }
10292            }
10293        }
10294        return new ParceledListSlice<>(result);
10295    }
10296
10297    @Override
10298    public void clearGrantedUriPermissions(String packageName, int userId) {
10299        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10300                "clearGrantedUriPermissions");
10301        synchronized(this) {
10302            removeUriPermissionsForPackageLocked(packageName, userId, true, true);
10303        }
10304    }
10305
10306    @Override
10307    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10308        synchronized (this) {
10309            ProcessRecord app =
10310                who != null ? getRecordForAppLocked(who) : null;
10311            if (app == null) return;
10312
10313            Message msg = Message.obtain();
10314            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10315            msg.obj = app;
10316            msg.arg1 = waiting ? 1 : 0;
10317            mUiHandler.sendMessage(msg);
10318        }
10319    }
10320
10321    @Override
10322    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10323        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10324        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10325        outInfo.availMem = getFreeMemory();
10326        outInfo.totalMem = getTotalMemory();
10327        outInfo.threshold = homeAppMem;
10328        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10329        outInfo.hiddenAppThreshold = cachedAppMem;
10330        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10331                ProcessList.SERVICE_ADJ);
10332        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10333                ProcessList.VISIBLE_APP_ADJ);
10334        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10335                ProcessList.FOREGROUND_APP_ADJ);
10336    }
10337
10338    // =========================================================
10339    // TASK MANAGEMENT
10340    // =========================================================
10341
10342    @Override
10343    public List<IBinder> getAppTasks(String callingPackage) {
10344        int callingUid = Binder.getCallingUid();
10345        long ident = Binder.clearCallingIdentity();
10346        try {
10347            synchronized(this) {
10348                return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10349            }
10350        } finally {
10351            Binder.restoreCallingIdentity(ident);
10352        }
10353    }
10354
10355    @Override
10356    public List<RunningTaskInfo> getTasks(int maxNum) {
10357       return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10358    }
10359
10360    @Override
10361    public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10362            @WindowingMode int ignoreWindowingMode) {
10363        final int callingUid = Binder.getCallingUid();
10364        ArrayList<RunningTaskInfo> list = new ArrayList<>();
10365
10366        synchronized(this) {
10367            if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10368
10369            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10370                    callingUid);
10371            mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10372                    ignoreWindowingMode, callingUid, allowed);
10373        }
10374
10375        return list;
10376    }
10377
10378    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10379        if (mRecentTasks.isCallerRecents(callingUid)) {
10380            // Always allow the recents component to get tasks
10381            return true;
10382        }
10383
10384        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10385                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10386        if (!allowed) {
10387            if (checkPermission(android.Manifest.permission.GET_TASKS,
10388                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10389                // Temporary compatibility: some existing apps on the system image may
10390                // still be requesting the old permission and not switched to the new
10391                // one; if so, we'll still allow them full access.  This means we need
10392                // to see if they are holding the old permission and are a system app.
10393                try {
10394                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10395                        allowed = true;
10396                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10397                                + " is using old GET_TASKS but privileged; allowing");
10398                    }
10399                } catch (RemoteException e) {
10400                }
10401            }
10402        }
10403        if (!allowed) {
10404            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10405                    + " does not hold REAL_GET_TASKS; limiting output");
10406        }
10407        return allowed;
10408    }
10409
10410    @Override
10411    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10412            int userId) {
10413        final int callingUid = Binder.getCallingUid();
10414        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10415                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10416        final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10417                callingUid);
10418        final boolean detailed = checkCallingPermission(
10419                android.Manifest.permission.GET_DETAILED_TASKS)
10420                        == PackageManager.PERMISSION_GRANTED;
10421
10422        synchronized (this) {
10423            return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10424                    callingUid);
10425        }
10426    }
10427
10428    @Override
10429    public ActivityManager.TaskDescription getTaskDescription(int id) {
10430        synchronized (this) {
10431            enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10432            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10433                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10434            if (tr != null) {
10435                return tr.lastTaskDescription;
10436            }
10437        }
10438        return null;
10439    }
10440
10441    @Override
10442    public int addAppTask(IBinder activityToken, Intent intent,
10443            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10444        final int callingUid = Binder.getCallingUid();
10445        final long callingIdent = Binder.clearCallingIdentity();
10446
10447        try {
10448            synchronized (this) {
10449                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10450                if (r == null) {
10451                    throw new IllegalArgumentException("Activity does not exist; token="
10452                            + activityToken);
10453                }
10454                ComponentName comp = intent.getComponent();
10455                if (comp == null) {
10456                    throw new IllegalArgumentException("Intent " + intent
10457                            + " must specify explicit component");
10458                }
10459                if (thumbnail.getWidth() != mThumbnailWidth
10460                        || thumbnail.getHeight() != mThumbnailHeight) {
10461                    throw new IllegalArgumentException("Bad thumbnail size: got "
10462                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10463                            + mThumbnailWidth + "x" + mThumbnailHeight);
10464                }
10465                if (intent.getSelector() != null) {
10466                    intent.setSelector(null);
10467                }
10468                if (intent.getSourceBounds() != null) {
10469                    intent.setSourceBounds(null);
10470                }
10471                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10472                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10473                        // The caller has added this as an auto-remove task...  that makes no
10474                        // sense, so turn off auto-remove.
10475                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10476                    }
10477                }
10478                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10479                    mLastAddedTaskActivity = null;
10480                }
10481                ActivityInfo ainfo = mLastAddedTaskActivity;
10482                if (ainfo == null) {
10483                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10484                            comp, 0, UserHandle.getUserId(callingUid));
10485                    if (ainfo.applicationInfo.uid != callingUid) {
10486                        throw new SecurityException(
10487                                "Can't add task for another application: target uid="
10488                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10489                    }
10490                }
10491
10492                TaskRecord task = TaskRecord.create(this,
10493                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10494                        ainfo, intent, description);
10495                if (!mRecentTasks.addToBottom(task)) {
10496                    return INVALID_TASK_ID;
10497                }
10498                r.getStack().addTask(task, !ON_TOP, "addAppTask");
10499
10500                // TODO: Send the thumbnail to WM to store it.
10501
10502                return task.taskId;
10503            }
10504        } finally {
10505            Binder.restoreCallingIdentity(callingIdent);
10506        }
10507    }
10508
10509    @Override
10510    public Point getAppTaskThumbnailSize() {
10511        synchronized (this) {
10512            return new Point(mThumbnailWidth,  mThumbnailHeight);
10513        }
10514    }
10515
10516    @Override
10517    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10518        synchronized (this) {
10519            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10520            if (r != null) {
10521                r.setTaskDescription(td);
10522                final TaskRecord task = r.getTask();
10523                task.updateTaskDescription();
10524                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10525            }
10526        }
10527    }
10528
10529    @Override
10530    public void setTaskResizeable(int taskId, int resizeableMode) {
10531        synchronized (this) {
10532            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10533                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10534            if (task == null) {
10535                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10536                return;
10537            }
10538            task.setResizeMode(resizeableMode);
10539        }
10540    }
10541
10542    @Override
10543    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10544        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10545        long ident = Binder.clearCallingIdentity();
10546        try {
10547            synchronized (this) {
10548                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10549                if (task == null) {
10550                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10551                    return;
10552                }
10553                // Place the task in the right stack if it isn't there already based on
10554                // the requested bounds.
10555                // The stack transition logic is:
10556                // - a null bounds on a freeform task moves that task to fullscreen
10557                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10558                //   that task to freeform
10559                // - otherwise the task is not moved
10560                ActivityStack stack = task.getStack();
10561                if (!task.getWindowConfiguration().canResizeTask()) {
10562                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10563                }
10564                if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10565                    stack = stack.getDisplay().getOrCreateStack(
10566                            WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10567                } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10568                    stack = stack.getDisplay().getOrCreateStack(
10569                            WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10570                }
10571
10572                // Reparent the task to the right stack if necessary
10573                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10574                if (stack != task.getStack()) {
10575                    // Defer resume until the task is resized below
10576                    task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10577                            DEFER_RESUME, "resizeTask");
10578                    preserveWindow = false;
10579                }
10580
10581                // After reparenting (which only resizes the task to the stack bounds), resize the
10582                // task to the actual bounds provided
10583                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10584            }
10585        } finally {
10586            Binder.restoreCallingIdentity(ident);
10587        }
10588    }
10589
10590    @Override
10591    public Rect getTaskBounds(int taskId) {
10592        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10593        long ident = Binder.clearCallingIdentity();
10594        Rect rect = new Rect();
10595        try {
10596            synchronized (this) {
10597                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10598                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10599                if (task == null) {
10600                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10601                    return rect;
10602                }
10603                if (task.getStack() != null) {
10604                    // Return the bounds from window manager since it will be adjusted for various
10605                    // things like the presense of a docked stack for tasks that aren't resizeable.
10606                    task.getWindowContainerBounds(rect);
10607                } else {
10608                    // Task isn't in window manager yet since it isn't associated with a stack.
10609                    // Return the persist value from activity manager
10610                    if (!task.matchParentBounds()) {
10611                        rect.set(task.getBounds());
10612                    } else if (task.mLastNonFullscreenBounds != null) {
10613                        rect.set(task.mLastNonFullscreenBounds);
10614                    }
10615                }
10616            }
10617        } finally {
10618            Binder.restoreCallingIdentity(ident);
10619        }
10620        return rect;
10621    }
10622
10623    @Override
10624    public void cancelTaskWindowTransition(int taskId) {
10625        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10626                "cancelTaskWindowTransition()");
10627        final long ident = Binder.clearCallingIdentity();
10628        try {
10629            synchronized (this) {
10630                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10631                        MATCH_TASK_IN_STACKS_ONLY);
10632                if (task == null) {
10633                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10634                    return;
10635                }
10636                task.cancelWindowTransition();
10637            }
10638        } finally {
10639            Binder.restoreCallingIdentity(ident);
10640        }
10641    }
10642
10643    @Override
10644    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10645        enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10646        final long ident = Binder.clearCallingIdentity();
10647        try {
10648            final TaskRecord task;
10649            synchronized (this) {
10650                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10651                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10652                if (task == null) {
10653                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10654                    return null;
10655                }
10656            }
10657            // Don't call this while holding the lock as this operation might hit the disk.
10658            return task.getSnapshot(reducedResolution);
10659        } finally {
10660            Binder.restoreCallingIdentity(ident);
10661        }
10662    }
10663
10664    @Override
10665    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10666        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10667                userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
10668
10669        final File passedIconFile = new File(filePath);
10670        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10671                passedIconFile.getName());
10672        if (!legitIconFile.getPath().equals(filePath)
10673                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10674            throw new IllegalArgumentException("Bad file path: " + filePath
10675                    + " passed for userId " + userId);
10676        }
10677        return mRecentTasks.getTaskDescriptionIcon(filePath);
10678    }
10679
10680    @Override
10681    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10682            throws RemoteException {
10683        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
10684        final ActivityOptions activityOptions = safeOptions != null
10685                ? safeOptions.getOptions(mStackSupervisor)
10686                : null;
10687        if (activityOptions == null
10688                || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
10689                || activityOptions.getCustomInPlaceResId() == 0) {
10690            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10691                    "with valid animation");
10692        }
10693        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10694        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10695                activityOptions.getCustomInPlaceResId());
10696        mWindowManager.executeAppTransition();
10697    }
10698
10699    @Override
10700    public void removeStack(int stackId) {
10701        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
10702        synchronized (this) {
10703            final long ident = Binder.clearCallingIdentity();
10704            try {
10705                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10706                if (stack == null) {
10707                    Slog.w(TAG, "removeStack: No stack with id=" + stackId);
10708                    return;
10709                }
10710                if (!stack.isActivityTypeStandardOrUndefined()) {
10711                    throw new IllegalArgumentException(
10712                            "Removing non-standard stack is not allowed.");
10713                }
10714                mStackSupervisor.removeStack(stack);
10715            } finally {
10716                Binder.restoreCallingIdentity(ident);
10717            }
10718        }
10719    }
10720
10721    /**
10722     * Removes stacks in the input windowing modes from the system if they are of activity type
10723     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
10724     */
10725    @Override
10726    public void removeStacksInWindowingModes(int[] windowingModes) {
10727        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10728                "removeStacksInWindowingModes()");
10729        synchronized (this) {
10730            final long ident = Binder.clearCallingIdentity();
10731            try {
10732                mStackSupervisor.removeStacksInWindowingModes(windowingModes);
10733            } finally {
10734                Binder.restoreCallingIdentity(ident);
10735            }
10736        }
10737    }
10738
10739    @Override
10740    public void removeStacksWithActivityTypes(int[] activityTypes) {
10741        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10742                "removeStacksWithActivityTypes()");
10743        synchronized (this) {
10744            final long ident = Binder.clearCallingIdentity();
10745            try {
10746                mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
10747            } finally {
10748                Binder.restoreCallingIdentity(ident);
10749            }
10750        }
10751    }
10752
10753    @Override
10754    public void moveStackToDisplay(int stackId, int displayId) {
10755        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10756
10757        synchronized (this) {
10758            final long ident = Binder.clearCallingIdentity();
10759            try {
10760                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10761                        + " to displayId=" + displayId);
10762                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10763            } finally {
10764                Binder.restoreCallingIdentity(ident);
10765            }
10766        }
10767    }
10768
10769    @Override
10770    public boolean removeTask(int taskId) {
10771        enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
10772        synchronized (this) {
10773            final long ident = Binder.clearCallingIdentity();
10774            try {
10775                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
10776                        "remove-task");
10777            } finally {
10778                Binder.restoreCallingIdentity(ident);
10779            }
10780        }
10781    }
10782
10783    /**
10784     * TODO: Add mController hook
10785     */
10786    @Override
10787    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10788        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10789
10790        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10791        synchronized(this) {
10792            moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
10793                    false /* fromRecents */);
10794        }
10795    }
10796
10797    void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
10798            boolean fromRecents) {
10799
10800        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10801                Binder.getCallingUid(), -1, -1, "Task to front")) {
10802            SafeActivityOptions.abort(options);
10803            return;
10804        }
10805        final long origId = Binder.clearCallingIdentity();
10806        try {
10807            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10808            if (task == null) {
10809                Slog.d(TAG, "Could not find task for id: "+ taskId);
10810                return;
10811            }
10812            if (mLockTaskController.isLockTaskModeViolation(task)) {
10813                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10814                return;
10815            }
10816            ActivityOptions realOptions = options != null
10817                    ? options.getOptions(mStackSupervisor)
10818                    : null;
10819            mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
10820                    false /* forceNonResizable */);
10821
10822            final ActivityRecord topActivity = task.getTopActivity();
10823            if (topActivity != null) {
10824
10825                // We are reshowing a task, use a starting window to hide the initial draw delay
10826                // so the transition can start earlier.
10827                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10828                        true /* taskSwitch */, fromRecents);
10829            }
10830        } finally {
10831            Binder.restoreCallingIdentity(origId);
10832        }
10833        SafeActivityOptions.abort(options);
10834    }
10835
10836    /**
10837     * Attempts to move a task backwards in z-order (the order of activities within the task is
10838     * unchanged).
10839     *
10840     * There are several possible results of this call:
10841     * - if the task is locked, then we will show the lock toast
10842     * - if there is a task behind the provided task, then that task is made visible and resumed as
10843     *   this task is moved to the back
10844     * - otherwise, if there are no other tasks in the stack:
10845     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10846     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10847     *       (depending on whether it is visible)
10848     *     - otherwise, we simply return home and hide this task
10849     *
10850     * @param token A reference to the activity we wish to move
10851     * @param nonRoot If false then this only works if the activity is the root
10852     *                of a task; if true it will work for any activity in a task.
10853     * @return Returns true if the move completed, false if not.
10854     */
10855    @Override
10856    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10857        enforceNotIsolatedCaller("moveActivityTaskToBack");
10858        synchronized(this) {
10859            final long origId = Binder.clearCallingIdentity();
10860            try {
10861                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10862                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10863                if (task != null) {
10864                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10865                }
10866            } finally {
10867                Binder.restoreCallingIdentity(origId);
10868            }
10869        }
10870        return false;
10871    }
10872
10873    @Override
10874    public void moveTaskBackwards(int task) {
10875        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10876                "moveTaskBackwards()");
10877
10878        synchronized(this) {
10879            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10880                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10881                return;
10882            }
10883            final long origId = Binder.clearCallingIdentity();
10884            moveTaskBackwardsLocked(task);
10885            Binder.restoreCallingIdentity(origId);
10886        }
10887    }
10888
10889    private final void moveTaskBackwardsLocked(int task) {
10890        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10891    }
10892
10893    @Override
10894    public int createStackOnDisplay(int displayId) throws RemoteException {
10895        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10896        synchronized (this) {
10897            final ActivityDisplay display =
10898                    mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
10899            if (display == null) {
10900                return INVALID_STACK_ID;
10901            }
10902            // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
10903            final ActivityStack stack = display.createStack(
10904                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
10905                    ON_TOP);
10906            return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
10907        }
10908    }
10909
10910    @Override
10911    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10912        synchronized (this) {
10913            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10914            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10915                return stack.mDisplayId;
10916            }
10917            return DEFAULT_DISPLAY;
10918        }
10919    }
10920
10921    @Override
10922    public void exitFreeformMode(IBinder token) throws RemoteException {
10923        synchronized (this) {
10924            long ident = Binder.clearCallingIdentity();
10925            try {
10926                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10927                if (r == null) {
10928                    throw new IllegalArgumentException(
10929                            "exitFreeformMode: No activity record matching token=" + token);
10930                }
10931
10932                final ActivityStack stack = r.getStack();
10933                if (stack == null || !stack.inFreeformWindowingMode()) {
10934                    throw new IllegalStateException(
10935                            "exitFreeformMode: You can only go fullscreen from freeform.");
10936                }
10937
10938                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
10939            } finally {
10940                Binder.restoreCallingIdentity(ident);
10941            }
10942        }
10943    }
10944
10945    @Override
10946    public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
10947        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
10948            setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
10949                    toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
10950            return;
10951        }
10952        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
10953        synchronized (this) {
10954            final long ident = Binder.clearCallingIdentity();
10955            try {
10956                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10957                if (task == null) {
10958                    Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
10959                    return;
10960                }
10961
10962                if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
10963                        + " to windowingMode=" + windowingMode + " toTop=" + toTop);
10964
10965                if (!task.isActivityTypeStandardOrUndefined()) {
10966                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
10967                            + " non-standard task " + taskId + " to windowing mode="
10968                            + windowingMode);
10969                }
10970
10971                final ActivityStack stack = task.getStack();
10972                if (toTop) {
10973                    stack.moveToFront("setTaskWindowingMode", task);
10974                }
10975                stack.setWindowingMode(windowingMode);
10976            } finally {
10977                Binder.restoreCallingIdentity(ident);
10978            }
10979        }
10980    }
10981
10982    /**
10983     * Moves the specified task to the primary-split-screen stack.
10984     *
10985     * @param taskId Id of task to move.
10986     * @param createMode The mode the primary split screen stack should be created in if it doesn't
10987     *                   exist already. See
10988     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
10989     *                   and
10990     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
10991     * @param toTop If the task and stack should be moved to the top.
10992     * @param animate Whether we should play an animation for the moving the task.
10993     * @param initialBounds If the primary stack gets created, it will use these bounds for the
10994     *                      stack. Pass {@code null} to use default bounds.
10995     * @param showRecents If the recents activity should be shown on the other side of the task
10996     *                    going into split-screen mode.
10997     */
10998    @Override
10999    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
11000            boolean animate, Rect initialBounds, boolean showRecents) {
11001        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11002                "setTaskWindowingModeSplitScreenPrimary()");
11003        synchronized (this) {
11004            long ident = Binder.clearCallingIdentity();
11005            try {
11006                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11007                if (task == null) {
11008                    Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
11009                    return false;
11010                }
11011                if (DEBUG_STACK) Slog.d(TAG_STACK,
11012                        "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
11013                        + " to createMode=" + createMode + " toTop=" + toTop);
11014                if (!task.isActivityTypeStandardOrUndefined()) {
11015                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11016                            + " non-standard task " + taskId + " to split-screen windowing mode");
11017                }
11018
11019                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
11020                final int windowingMode = task.getWindowingMode();
11021                final ActivityStack stack = task.getStack();
11022                if (toTop) {
11023                    stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
11024                }
11025                stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
11026                        false /* enteringSplitScreenMode */);
11027                return windowingMode != task.getWindowingMode();
11028            } finally {
11029                Binder.restoreCallingIdentity(ident);
11030            }
11031        }
11032    }
11033
11034    @Override
11035    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
11036        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
11037        synchronized (this) {
11038            long ident = Binder.clearCallingIdentity();
11039            try {
11040                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11041                if (task == null) {
11042                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
11043                    return;
11044                }
11045
11046                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
11047                        + " to stackId=" + stackId + " toTop=" + toTop);
11048
11049                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11050                if (stack == null) {
11051                    throw new IllegalStateException(
11052                            "moveTaskToStack: No stack for stackId=" + stackId);
11053                }
11054                if (!stack.isActivityTypeStandardOrUndefined()) {
11055                    throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
11056                            + taskId + " to stack " + stackId);
11057                }
11058                if (stack.inSplitScreenPrimaryWindowingMode()) {
11059                    mWindowManager.setDockedStackCreateState(
11060                            SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
11061                }
11062                task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
11063                        "moveTaskToStack");
11064            } finally {
11065                Binder.restoreCallingIdentity(ident);
11066            }
11067        }
11068    }
11069
11070    /**
11071     * Dismisses split-screen multi-window mode.
11072     * @param toTop If true the current primary split-screen stack will be placed or left on top.
11073     */
11074    @Override
11075    public void dismissSplitScreenMode(boolean toTop) {
11076        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
11077        final long ident = Binder.clearCallingIdentity();
11078        try {
11079            synchronized (this) {
11080                final ActivityStack stack =
11081                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
11082                if (stack == null) {
11083                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
11084                    return;
11085                }
11086
11087                if (toTop) {
11088                    // Caller wants the current split-screen primary stack to be the top stack after
11089                    // it goes fullscreen, so move it to the front.
11090                    stack.moveToFront("dismissSplitScreenMode");
11091                } else if (mStackSupervisor.isFocusedStack(stack)) {
11092                    // In this case the current split-screen primary stack shouldn't be the top
11093                    // stack after it goes fullscreen, but it current has focus, so we move the
11094                    // focus to the top-most split-screen secondary stack next to it.
11095                    final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
11096                            WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
11097                    if (otherStack != null) {
11098                        otherStack.moveToFront("dismissSplitScreenMode_other");
11099                    }
11100                }
11101
11102                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11103            }
11104        } finally {
11105            Binder.restoreCallingIdentity(ident);
11106        }
11107    }
11108
11109    /**
11110     * Dismisses Pip
11111     * @param animate True if the dismissal should be animated.
11112     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
11113     *                          default animation duration should be used.
11114     */
11115    @Override
11116    public void dismissPip(boolean animate, int animationDuration) {
11117        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
11118        final long ident = Binder.clearCallingIdentity();
11119        try {
11120            synchronized (this) {
11121                final PinnedActivityStack stack =
11122                        mStackSupervisor.getDefaultDisplay().getPinnedStack();
11123                if (stack == null) {
11124                    Slog.w(TAG, "dismissPip: pinned stack not found.");
11125                    return;
11126                }
11127                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11128                    throw new IllegalArgumentException("Stack: " + stack
11129                            + " doesn't support animated resize.");
11130                }
11131                if (animate) {
11132                    stack.animateResizePinnedStack(null /* sourceHintBounds */,
11133                            null /* destBounds */, animationDuration, false /* fromFullscreen */);
11134                } else {
11135                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
11136                }
11137            }
11138        } finally {
11139            Binder.restoreCallingIdentity(ident);
11140        }
11141    }
11142
11143    /**
11144     * Moves the top activity in the input stackId to the pinned stack.
11145     *
11146     * @param stackId Id of stack to move the top activity to pinned stack.
11147     * @param bounds Bounds to use for pinned stack.
11148     *
11149     * @return True if the top activity of the input stack was successfully moved to the pinned
11150     *          stack.
11151     */
11152    @Override
11153    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
11154        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11155                "moveTopActivityToPinnedStack()");
11156        synchronized (this) {
11157            if (!mSupportsPictureInPicture) {
11158                throw new IllegalStateException("moveTopActivityToPinnedStack:"
11159                        + "Device doesn't support picture-in-picture mode");
11160            }
11161
11162            long ident = Binder.clearCallingIdentity();
11163            try {
11164                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
11165            } finally {
11166                Binder.restoreCallingIdentity(ident);
11167            }
11168        }
11169    }
11170
11171    @Override
11172    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
11173            boolean preserveWindows, boolean animate, int animationDuration) {
11174        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
11175        long ident = Binder.clearCallingIdentity();
11176        try {
11177            synchronized (this) {
11178                if (animate) {
11179                    final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
11180                    if (stack == null) {
11181                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11182                        return;
11183                    }
11184                    if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11185                        throw new IllegalArgumentException("Stack: " + stackId
11186                                + " doesn't support animated resize.");
11187                    }
11188                    stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11189                            animationDuration, false /* fromFullscreen */);
11190                } else {
11191                    final ActivityStack stack = mStackSupervisor.getStack(stackId);
11192                    if (stack == null) {
11193                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11194                        return;
11195                    }
11196                    mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11197                            null /* tempTaskInsetBounds */, preserveWindows,
11198                            allowResizeInDockedMode, !DEFER_RESUME);
11199                }
11200            }
11201        } finally {
11202            Binder.restoreCallingIdentity(ident);
11203        }
11204    }
11205
11206    @Override
11207    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
11208            Rect tempDockedTaskInsetBounds,
11209            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
11210        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
11211        long ident = Binder.clearCallingIdentity();
11212        try {
11213            synchronized (this) {
11214                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11215                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11216                        PRESERVE_WINDOWS);
11217            }
11218        } finally {
11219            Binder.restoreCallingIdentity(ident);
11220        }
11221    }
11222
11223    @Override
11224    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11225        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11226        final long ident = Binder.clearCallingIdentity();
11227        try {
11228            synchronized (this) {
11229                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11230            }
11231        } finally {
11232            Binder.restoreCallingIdentity(ident);
11233        }
11234    }
11235
11236    /**
11237     * Try to place task to provided position. The final position might be different depending on
11238     * current user and stacks state. The task will be moved to target stack if it's currently in
11239     * different stack.
11240     */
11241    @Override
11242    public void positionTaskInStack(int taskId, int stackId, int position) {
11243        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11244        synchronized (this) {
11245            long ident = Binder.clearCallingIdentity();
11246            try {
11247                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
11248                        + taskId + " in stackId=" + stackId + " at position=" + position);
11249                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11250                if (task == null) {
11251                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
11252                            + taskId);
11253                }
11254
11255                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11256
11257                if (stack == null) {
11258                    throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11259                            + stackId);
11260                }
11261                if (!stack.isActivityTypeStandardOrUndefined()) {
11262                    throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11263                            + " the position of task " + taskId + " in/to non-standard stack");
11264                }
11265
11266                // TODO: Have the callers of this API call a separate reparent method if that is
11267                // what they intended to do vs. having this method also do reparenting.
11268                if (task.getStack() == stack) {
11269                    // Change position in current stack.
11270                    stack.positionChildAt(task, position);
11271                } else {
11272                    // Reparent to new stack.
11273                    task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11274                            !DEFER_RESUME, "positionTaskInStack");
11275                }
11276            } finally {
11277                Binder.restoreCallingIdentity(ident);
11278            }
11279        }
11280    }
11281
11282    @Override
11283    public List<StackInfo> getAllStackInfos() {
11284        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11285        long ident = Binder.clearCallingIdentity();
11286        try {
11287            synchronized (this) {
11288                return mStackSupervisor.getAllStackInfosLocked();
11289            }
11290        } finally {
11291            Binder.restoreCallingIdentity(ident);
11292        }
11293    }
11294
11295    @Override
11296    public StackInfo getStackInfo(int windowingMode, int activityType) {
11297        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11298        long ident = Binder.clearCallingIdentity();
11299        try {
11300            synchronized (this) {
11301                return mStackSupervisor.getStackInfo(windowingMode, activityType);
11302            }
11303        } finally {
11304            Binder.restoreCallingIdentity(ident);
11305        }
11306    }
11307
11308    @Override
11309    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11310        synchronized(this) {
11311            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11312        }
11313    }
11314
11315    @Override
11316    public void updateDeviceOwner(String packageName) {
11317        final int callingUid = Binder.getCallingUid();
11318        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11319            throw new SecurityException("updateDeviceOwner called from non-system process");
11320        }
11321        synchronized (this) {
11322            mDeviceOwnerName = packageName;
11323        }
11324    }
11325
11326    @Override
11327    public void updateLockTaskPackages(int userId, String[] packages) {
11328        final int callingUid = Binder.getCallingUid();
11329        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11330            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11331                    "updateLockTaskPackages()");
11332        }
11333        synchronized (this) {
11334            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11335                    Arrays.toString(packages));
11336            mLockTaskController.updateLockTaskPackages(userId, packages);
11337        }
11338    }
11339
11340    @Override
11341    public void updateLockTaskFeatures(int userId, int flags) {
11342        final int callingUid = Binder.getCallingUid();
11343        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11344            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11345                    "updateLockTaskFeatures()");
11346        }
11347        synchronized (this) {
11348            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11349                    Integer.toHexString(flags));
11350            mLockTaskController.updateLockTaskFeatures(userId, flags);
11351        }
11352    }
11353
11354    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11355        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11356        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11357            return;
11358        }
11359
11360        final ActivityStack stack = mStackSupervisor.getFocusedStack();
11361        if (stack == null || task != stack.topTask()) {
11362            throw new IllegalArgumentException("Invalid task, not in foreground");
11363        }
11364
11365        // When a task is locked, dismiss the pinned stack if it exists
11366        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11367
11368        // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11369        // system or a specific app.
11370        // * System-initiated requests will only start the pinned mode (screen pinning)
11371        // * App-initiated requests
11372        //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
11373        //   - will start the pinned mode, otherwise
11374        final int callingUid = Binder.getCallingUid();
11375        long ident = Binder.clearCallingIdentity();
11376        try {
11377            mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11378        } finally {
11379            Binder.restoreCallingIdentity(ident);
11380        }
11381    }
11382
11383    @Override
11384    public void startLockTaskModeByToken(IBinder token) {
11385        synchronized (this) {
11386            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11387            if (r == null) {
11388                return;
11389            }
11390            startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11391        }
11392    }
11393
11394    @Override
11395    public void startSystemLockTaskMode(int taskId) throws RemoteException {
11396        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11397        // This makes inner call to look as if it was initiated by system.
11398        long ident = Binder.clearCallingIdentity();
11399        try {
11400            synchronized (this) {
11401                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11402
11403                // When starting lock task mode the stack must be in front and focused
11404                task.getStack().moveToFront("startSystemLockTaskMode");
11405                startLockTaskModeLocked(task, true /* isSystemCaller */);
11406            }
11407        } finally {
11408            Binder.restoreCallingIdentity(ident);
11409        }
11410    }
11411
11412    @Override
11413    public void stopLockTaskModeByToken(IBinder token) {
11414        synchronized (this) {
11415            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11416            if (r == null) {
11417                return;
11418            }
11419            stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11420        }
11421    }
11422
11423    /**
11424     * This API should be called by SystemUI only when user perform certain action to dismiss
11425     * lock task mode. We should only dismiss pinned lock task mode in this case.
11426     */
11427    @Override
11428    public void stopSystemLockTaskMode() throws RemoteException {
11429        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11430        stopLockTaskModeInternal(null, true /* isSystemCaller */);
11431    }
11432
11433    private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11434        final int callingUid = Binder.getCallingUid();
11435        long ident = Binder.clearCallingIdentity();
11436        try {
11437            synchronized (this) {
11438                mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11439            }
11440            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11441            // task and jumping straight into a call in the case of emergency call back.
11442            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11443            if (tm != null) {
11444                tm.showInCallScreen(false);
11445            }
11446        } finally {
11447            Binder.restoreCallingIdentity(ident);
11448        }
11449    }
11450
11451    @Override
11452    public boolean isInLockTaskMode() {
11453        return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11454    }
11455
11456    @Override
11457    public int getLockTaskModeState() {
11458        synchronized (this) {
11459            return mLockTaskController.getLockTaskModeState();
11460        }
11461    }
11462
11463    @Override
11464    public void showLockTaskEscapeMessage(IBinder token) {
11465        synchronized (this) {
11466            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11467            if (r == null) {
11468                return;
11469            }
11470            mLockTaskController.showLockTaskToast();
11471        }
11472    }
11473
11474    @Override
11475    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11476            throws RemoteException {
11477        synchronized (this) {
11478            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11479            if (r == null) {
11480                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11481                        + token);
11482                return;
11483            }
11484            final long origId = Binder.clearCallingIdentity();
11485            try {
11486                r.setDisablePreviewScreenshots(disable);
11487            } finally {
11488                Binder.restoreCallingIdentity(origId);
11489            }
11490        }
11491    }
11492
11493    // =========================================================
11494    // CONTENT PROVIDERS
11495    // =========================================================
11496
11497    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11498        List<ProviderInfo> providers = null;
11499        try {
11500            providers = AppGlobals.getPackageManager()
11501                    .queryContentProviders(app.processName, app.uid,
11502                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11503                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11504                    .getList();
11505        } catch (RemoteException ex) {
11506        }
11507        if (DEBUG_MU) Slog.v(TAG_MU,
11508                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11509        int userId = app.userId;
11510        if (providers != null) {
11511            int N = providers.size();
11512            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11513            for (int i=0; i<N; i++) {
11514                // TODO: keep logic in sync with installEncryptionUnawareProviders
11515                ProviderInfo cpi =
11516                    (ProviderInfo)providers.get(i);
11517                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11518                        cpi.name, cpi.flags);
11519                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11520                    // This is a singleton provider, but a user besides the
11521                    // default user is asking to initialize a process it runs
11522                    // in...  well, no, it doesn't actually run in this process,
11523                    // it runs in the process of the default user.  Get rid of it.
11524                    providers.remove(i);
11525                    N--;
11526                    i--;
11527                    continue;
11528                }
11529
11530                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11531                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11532                if (cpr == null) {
11533                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11534                    mProviderMap.putProviderByClass(comp, cpr);
11535                }
11536                if (DEBUG_MU) Slog.v(TAG_MU,
11537                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11538                app.pubProviders.put(cpi.name, cpr);
11539                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11540                    // Don't add this if it is a platform component that is marked
11541                    // to run in multiple processes, because this is actually
11542                    // part of the framework so doesn't make sense to track as a
11543                    // separate apk in the process.
11544                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11545                            mProcessStats);
11546                }
11547                notifyPackageUse(cpi.applicationInfo.packageName,
11548                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11549            }
11550        }
11551        return providers;
11552    }
11553
11554    /**
11555     * Check if the calling UID has a possible chance at accessing the provider
11556     * at the given authority and user.
11557     */
11558    public String checkContentProviderAccess(String authority, int userId) {
11559        if (userId == UserHandle.USER_ALL) {
11560            mContext.enforceCallingOrSelfPermission(
11561                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11562            userId = UserHandle.getCallingUserId();
11563        }
11564
11565        ProviderInfo cpi = null;
11566        try {
11567            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11568                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11569                            | PackageManager.MATCH_DISABLED_COMPONENTS
11570                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11571                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11572                    userId);
11573        } catch (RemoteException ignored) {
11574        }
11575        if (cpi == null) {
11576            return "Failed to find provider " + authority + " for user " + userId
11577                    + "; expected to find a valid ContentProvider for this authority";
11578        }
11579
11580        ProcessRecord r = null;
11581        synchronized (mPidsSelfLocked) {
11582            r = mPidsSelfLocked.get(Binder.getCallingPid());
11583        }
11584        if (r == null) {
11585            return "Failed to find PID " + Binder.getCallingPid();
11586        }
11587
11588        synchronized (this) {
11589            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11590        }
11591    }
11592
11593    /**
11594     * Check if {@link ProcessRecord} has a possible chance at accessing the
11595     * given {@link ProviderInfo}. Final permission checking is always done
11596     * in {@link ContentProvider}.
11597     */
11598    private final String checkContentProviderPermissionLocked(
11599            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11600        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11601        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11602        boolean checkedGrants = false;
11603        if (checkUser) {
11604            // Looking for cross-user grants before enforcing the typical cross-users permissions
11605            int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11606            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11607                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11608                    return null;
11609                }
11610                checkedGrants = true;
11611            }
11612            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11613                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11614            if (userId != tmpTargetUserId) {
11615                // When we actually went to determine the final targer user ID, this ended
11616                // up different than our initial check for the authority.  This is because
11617                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11618                // SELF.  So we need to re-check the grants again.
11619                checkedGrants = false;
11620            }
11621        }
11622        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11623                cpi.applicationInfo.uid, cpi.exported)
11624                == PackageManager.PERMISSION_GRANTED) {
11625            return null;
11626        }
11627        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11628                cpi.applicationInfo.uid, cpi.exported)
11629                == PackageManager.PERMISSION_GRANTED) {
11630            return null;
11631        }
11632
11633        PathPermission[] pps = cpi.pathPermissions;
11634        if (pps != null) {
11635            int i = pps.length;
11636            while (i > 0) {
11637                i--;
11638                PathPermission pp = pps[i];
11639                String pprperm = pp.getReadPermission();
11640                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11641                        cpi.applicationInfo.uid, cpi.exported)
11642                        == PackageManager.PERMISSION_GRANTED) {
11643                    return null;
11644                }
11645                String ppwperm = pp.getWritePermission();
11646                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11647                        cpi.applicationInfo.uid, cpi.exported)
11648                        == PackageManager.PERMISSION_GRANTED) {
11649                    return null;
11650                }
11651            }
11652        }
11653        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11654            return null;
11655        }
11656
11657        final String suffix;
11658        if (!cpi.exported) {
11659            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11660        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11661            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11662        } else {
11663            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11664        }
11665        final String msg = "Permission Denial: opening provider " + cpi.name
11666                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11667                + ", uid=" + callingUid + ")" + suffix;
11668        Slog.w(TAG, msg);
11669        return msg;
11670    }
11671
11672    /**
11673     * Returns if the ContentProvider has granted a uri to callingUid
11674     */
11675    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11676        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11677        if (perms != null) {
11678            for (int i=perms.size()-1; i>=0; i--) {
11679                GrantUri grantUri = perms.keyAt(i);
11680                if (grantUri.sourceUserId == userId || !checkUser) {
11681                    if (matchesProvider(grantUri.uri, cpi)) {
11682                        return true;
11683                    }
11684                }
11685            }
11686        }
11687        return false;
11688    }
11689
11690    /**
11691     * Returns true if the uri authority is one of the authorities specified in the provider.
11692     */
11693    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11694        String uriAuth = uri.getAuthority();
11695        String cpiAuth = cpi.authority;
11696        if (cpiAuth.indexOf(';') == -1) {
11697            return cpiAuth.equals(uriAuth);
11698        }
11699        String[] cpiAuths = cpiAuth.split(";");
11700        int length = cpiAuths.length;
11701        for (int i = 0; i < length; i++) {
11702            if (cpiAuths[i].equals(uriAuth)) return true;
11703        }
11704        return false;
11705    }
11706
11707    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11708            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11709        if (r != null) {
11710            for (int i=0; i<r.conProviders.size(); i++) {
11711                ContentProviderConnection conn = r.conProviders.get(i);
11712                if (conn.provider == cpr) {
11713                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11714                            "Adding provider requested by "
11715                            + r.processName + " from process "
11716                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11717                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11718                    if (stable) {
11719                        conn.stableCount++;
11720                        conn.numStableIncs++;
11721                    } else {
11722                        conn.unstableCount++;
11723                        conn.numUnstableIncs++;
11724                    }
11725                    return conn;
11726                }
11727            }
11728            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11729            if (stable) {
11730                conn.stableCount = 1;
11731                conn.numStableIncs = 1;
11732            } else {
11733                conn.unstableCount = 1;
11734                conn.numUnstableIncs = 1;
11735            }
11736            cpr.connections.add(conn);
11737            r.conProviders.add(conn);
11738            startAssociationLocked(r.uid, r.processName, r.curProcState,
11739                    cpr.uid, cpr.name, cpr.info.processName);
11740            return conn;
11741        }
11742        cpr.addExternalProcessHandleLocked(externalProcessToken);
11743        return null;
11744    }
11745
11746    boolean decProviderCountLocked(ContentProviderConnection conn,
11747            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11748        if (conn != null) {
11749            cpr = conn.provider;
11750            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11751                    "Removing provider requested by "
11752                    + conn.client.processName + " from process "
11753                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11754                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11755            if (stable) {
11756                conn.stableCount--;
11757            } else {
11758                conn.unstableCount--;
11759            }
11760            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11761                cpr.connections.remove(conn);
11762                conn.client.conProviders.remove(conn);
11763                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11764                    // The client is more important than last activity -- note the time this
11765                    // is happening, so we keep the old provider process around a bit as last
11766                    // activity to avoid thrashing it.
11767                    if (cpr.proc != null) {
11768                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11769                    }
11770                }
11771                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11772                return true;
11773            }
11774            return false;
11775        }
11776        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11777        return false;
11778    }
11779
11780    private void checkTime(long startTime, String where) {
11781        long now = SystemClock.uptimeMillis();
11782        if ((now-startTime) > 50) {
11783            // If we are taking more than 50ms, log about it.
11784            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11785        }
11786    }
11787
11788    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11789            PROC_SPACE_TERM,
11790            PROC_SPACE_TERM|PROC_PARENS,
11791            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11792    };
11793
11794    private final long[] mProcessStateStatsLongs = new long[1];
11795
11796    private boolean isProcessAliveLocked(ProcessRecord proc) {
11797        if (proc.pid <= 0) {
11798            if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
11799            return false;
11800        }
11801        if (proc.procStatFile == null) {
11802            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11803        }
11804        mProcessStateStatsLongs[0] = 0;
11805        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11806                mProcessStateStatsLongs, null)) {
11807            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11808            return false;
11809        }
11810        final long state = mProcessStateStatsLongs[0];
11811        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11812                + (char)state);
11813        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11814    }
11815
11816    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11817            String name, IBinder token, boolean stable, int userId) {
11818        ContentProviderRecord cpr;
11819        ContentProviderConnection conn = null;
11820        ProviderInfo cpi = null;
11821
11822        synchronized(this) {
11823            long startTime = SystemClock.uptimeMillis();
11824
11825            ProcessRecord r = null;
11826            if (caller != null) {
11827                r = getRecordForAppLocked(caller);
11828                if (r == null) {
11829                    throw new SecurityException(
11830                            "Unable to find app for caller " + caller
11831                          + " (pid=" + Binder.getCallingPid()
11832                          + ") when getting content provider " + name);
11833                }
11834            }
11835
11836            boolean checkCrossUser = true;
11837
11838            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11839
11840            // First check if this content provider has been published...
11841            cpr = mProviderMap.getProviderByName(name, userId);
11842            // If that didn't work, check if it exists for user 0 and then
11843            // verify that it's a singleton provider before using it.
11844            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11845                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11846                if (cpr != null) {
11847                    cpi = cpr.info;
11848                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11849                            cpi.name, cpi.flags)
11850                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11851                        userId = UserHandle.USER_SYSTEM;
11852                        checkCrossUser = false;
11853                    } else {
11854                        cpr = null;
11855                        cpi = null;
11856                    }
11857                }
11858            }
11859
11860            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11861            if (providerRunning) {
11862                cpi = cpr.info;
11863                String msg;
11864                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11865                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11866                        != null) {
11867                    throw new SecurityException(msg);
11868                }
11869                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11870
11871                if (r != null && cpr.canRunHere(r)) {
11872                    // This provider has been published or is in the process
11873                    // of being published...  but it is also allowed to run
11874                    // in the caller's process, so don't make a connection
11875                    // and just let the caller instantiate its own instance.
11876                    ContentProviderHolder holder = cpr.newHolder(null);
11877                    // don't give caller the provider object, it needs
11878                    // to make its own.
11879                    holder.provider = null;
11880                    return holder;
11881                }
11882                // Don't expose providers between normal apps and instant apps
11883                try {
11884                    if (AppGlobals.getPackageManager()
11885                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11886                        return null;
11887                    }
11888                } catch (RemoteException e) {
11889                }
11890
11891                final long origId = Binder.clearCallingIdentity();
11892
11893                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11894
11895                // In this case the provider instance already exists, so we can
11896                // return it right away.
11897                conn = incProviderCountLocked(r, cpr, token, stable);
11898                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11899                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11900                        // If this is a perceptible app accessing the provider,
11901                        // make sure to count it as being accessed and thus
11902                        // back up on the LRU list.  This is good because
11903                        // content providers are often expensive to start.
11904                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11905                        updateLruProcessLocked(cpr.proc, false, null);
11906                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11907                    }
11908                }
11909
11910                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11911                final int verifiedAdj = cpr.proc.verifiedAdj;
11912                boolean success = updateOomAdjLocked(cpr.proc, true);
11913                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11914                // if the process has been successfully adjusted.  So to reduce races with
11915                // it, we will check whether the process still exists.  Note that this doesn't
11916                // completely get rid of races with LMK killing the process, but should make
11917                // them much smaller.
11918                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11919                    success = false;
11920                }
11921                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11922                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11923                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11924                // NOTE: there is still a race here where a signal could be
11925                // pending on the process even though we managed to update its
11926                // adj level.  Not sure what to do about this, but at least
11927                // the race is now smaller.
11928                if (!success) {
11929                    // Uh oh...  it looks like the provider's process
11930                    // has been killed on us.  We need to wait for a new
11931                    // process to be started, and make sure its death
11932                    // doesn't kill our process.
11933                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11934                            + " is crashing; detaching " + r);
11935                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11936                    checkTime(startTime, "getContentProviderImpl: before appDied");
11937                    appDiedLocked(cpr.proc);
11938                    checkTime(startTime, "getContentProviderImpl: after appDied");
11939                    if (!lastRef) {
11940                        // This wasn't the last ref our process had on
11941                        // the provider...  we have now been killed, bail.
11942                        return null;
11943                    }
11944                    providerRunning = false;
11945                    conn = null;
11946                } else {
11947                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11948                }
11949
11950                Binder.restoreCallingIdentity(origId);
11951            }
11952
11953            if (!providerRunning) {
11954                try {
11955                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11956                    cpi = AppGlobals.getPackageManager().
11957                        resolveContentProvider(name,
11958                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11959                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11960                } catch (RemoteException ex) {
11961                }
11962                if (cpi == null) {
11963                    return null;
11964                }
11965                // If the provider is a singleton AND
11966                // (it's a call within the same user || the provider is a
11967                // privileged app)
11968                // Then allow connecting to the singleton provider
11969                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11970                        cpi.name, cpi.flags)
11971                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11972                if (singleton) {
11973                    userId = UserHandle.USER_SYSTEM;
11974                }
11975                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11976                checkTime(startTime, "getContentProviderImpl: got app info for user");
11977
11978                String msg;
11979                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11980                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11981                        != null) {
11982                    throw new SecurityException(msg);
11983                }
11984                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11985
11986                if (!mProcessesReady
11987                        && !cpi.processName.equals("system")) {
11988                    // If this content provider does not run in the system
11989                    // process, and the system is not yet ready to run other
11990                    // processes, then fail fast instead of hanging.
11991                    throw new IllegalArgumentException(
11992                            "Attempt to launch content provider before system ready");
11993                }
11994
11995                // Make sure that the user who owns this provider is running.  If not,
11996                // we don't want to allow it to run.
11997                if (!mUserController.isUserRunning(userId, 0)) {
11998                    Slog.w(TAG, "Unable to launch app "
11999                            + cpi.applicationInfo.packageName + "/"
12000                            + cpi.applicationInfo.uid + " for provider "
12001                            + name + ": user " + userId + " is stopped");
12002                    return null;
12003                }
12004
12005                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
12006                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
12007                cpr = mProviderMap.getProviderByClass(comp, userId);
12008                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
12009                final boolean firstClass = cpr == null;
12010                if (firstClass) {
12011                    final long ident = Binder.clearCallingIdentity();
12012
12013                    // If permissions need a review before any of the app components can run,
12014                    // we return no provider and launch a review activity if the calling app
12015                    // is in the foreground.
12016                    if (mPermissionReviewRequired) {
12017                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
12018                            return null;
12019                        }
12020                    }
12021
12022                    try {
12023                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
12024                        ApplicationInfo ai =
12025                            AppGlobals.getPackageManager().
12026                                getApplicationInfo(
12027                                        cpi.applicationInfo.packageName,
12028                                        STOCK_PM_FLAGS, userId);
12029                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
12030                        if (ai == null) {
12031                            Slog.w(TAG, "No package info for content provider "
12032                                    + cpi.name);
12033                            return null;
12034                        }
12035                        ai = getAppInfoForUser(ai, userId);
12036                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
12037                    } catch (RemoteException ex) {
12038                        // pm is in same process, this will never happen.
12039                    } finally {
12040                        Binder.restoreCallingIdentity(ident);
12041                    }
12042                }
12043
12044                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
12045
12046                if (r != null && cpr.canRunHere(r)) {
12047                    // If this is a multiprocess provider, then just return its
12048                    // info and allow the caller to instantiate it.  Only do
12049                    // this if the provider is the same user as the caller's
12050                    // process, or can run as root (so can be in any process).
12051                    return cpr.newHolder(null);
12052                }
12053
12054                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
12055                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
12056                            + cpr.info.name + " callers=" + Debug.getCallers(6));
12057
12058                // This is single process, and our app is now connecting to it.
12059                // See if we are already in the process of launching this
12060                // provider.
12061                final int N = mLaunchingProviders.size();
12062                int i;
12063                for (i = 0; i < N; i++) {
12064                    if (mLaunchingProviders.get(i) == cpr) {
12065                        break;
12066                    }
12067                }
12068
12069                // If the provider is not already being launched, then get it
12070                // started.
12071                if (i >= N) {
12072                    final long origId = Binder.clearCallingIdentity();
12073
12074                    try {
12075                        // Content provider is now in use, its package can't be stopped.
12076                        try {
12077                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
12078                            AppGlobals.getPackageManager().setPackageStoppedState(
12079                                    cpr.appInfo.packageName, false, userId);
12080                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
12081                        } catch (RemoteException e) {
12082                        } catch (IllegalArgumentException e) {
12083                            Slog.w(TAG, "Failed trying to unstop package "
12084                                    + cpr.appInfo.packageName + ": " + e);
12085                        }
12086
12087                        // Use existing process if already started
12088                        checkTime(startTime, "getContentProviderImpl: looking for process record");
12089                        ProcessRecord proc = getProcessRecordLocked(
12090                                cpi.processName, cpr.appInfo.uid, false);
12091                        if (proc != null && proc.thread != null && !proc.killed) {
12092                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
12093                                    "Installing in existing process " + proc);
12094                            if (!proc.pubProviders.containsKey(cpi.name)) {
12095                                checkTime(startTime, "getContentProviderImpl: scheduling install");
12096                                proc.pubProviders.put(cpi.name, cpr);
12097                                try {
12098                                    proc.thread.scheduleInstallProvider(cpi);
12099                                } catch (RemoteException e) {
12100                                }
12101                            }
12102                        } else {
12103                            checkTime(startTime, "getContentProviderImpl: before start process");
12104                            proc = startProcessLocked(cpi.processName,
12105                                    cpr.appInfo, false, 0, "content provider",
12106                                    new ComponentName(cpi.applicationInfo.packageName,
12107                                            cpi.name), false, false, false);
12108                            checkTime(startTime, "getContentProviderImpl: after start process");
12109                            if (proc == null) {
12110                                Slog.w(TAG, "Unable to launch app "
12111                                        + cpi.applicationInfo.packageName + "/"
12112                                        + cpi.applicationInfo.uid + " for provider "
12113                                        + name + ": process is bad");
12114                                return null;
12115                            }
12116                        }
12117                        cpr.launchingApp = proc;
12118                        mLaunchingProviders.add(cpr);
12119                    } finally {
12120                        Binder.restoreCallingIdentity(origId);
12121                    }
12122                }
12123
12124                checkTime(startTime, "getContentProviderImpl: updating data structures");
12125
12126                // Make sure the provider is published (the same provider class
12127                // may be published under multiple names).
12128                if (firstClass) {
12129                    mProviderMap.putProviderByClass(comp, cpr);
12130                }
12131
12132                mProviderMap.putProviderByName(name, cpr);
12133                conn = incProviderCountLocked(r, cpr, token, stable);
12134                if (conn != null) {
12135                    conn.waiting = true;
12136                }
12137            }
12138            checkTime(startTime, "getContentProviderImpl: done!");
12139
12140            grantEphemeralAccessLocked(userId, null /*intent*/,
12141                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
12142        }
12143
12144        // Wait for the provider to be published...
12145        synchronized (cpr) {
12146            while (cpr.provider == null) {
12147                if (cpr.launchingApp == null) {
12148                    Slog.w(TAG, "Unable to launch app "
12149                            + cpi.applicationInfo.packageName + "/"
12150                            + cpi.applicationInfo.uid + " for provider "
12151                            + name + ": launching app became null");
12152                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
12153                            UserHandle.getUserId(cpi.applicationInfo.uid),
12154                            cpi.applicationInfo.packageName,
12155                            cpi.applicationInfo.uid, name);
12156                    return null;
12157                }
12158                try {
12159                    if (DEBUG_MU) Slog.v(TAG_MU,
12160                            "Waiting to start provider " + cpr
12161                            + " launchingApp=" + cpr.launchingApp);
12162                    if (conn != null) {
12163                        conn.waiting = true;
12164                    }
12165                    cpr.wait();
12166                } catch (InterruptedException ex) {
12167                } finally {
12168                    if (conn != null) {
12169                        conn.waiting = false;
12170                    }
12171                }
12172            }
12173        }
12174        return cpr != null ? cpr.newHolder(conn) : null;
12175    }
12176
12177    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
12178            ProcessRecord r, final int userId) {
12179        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
12180                cpi.packageName, userId)) {
12181
12182            final boolean callerForeground = r == null || r.setSchedGroup
12183                    != ProcessList.SCHED_GROUP_BACKGROUND;
12184
12185            // Show a permission review UI only for starting from a foreground app
12186            if (!callerForeground) {
12187                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
12188                        + cpi.packageName + " requires a permissions review");
12189                return false;
12190            }
12191
12192            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
12193            intent.addFlags(FLAG_ACTIVITY_NEW_TASK
12194                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
12195            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
12196
12197            if (DEBUG_PERMISSIONS_REVIEW) {
12198                Slog.i(TAG, "u" + userId + " Launching permission review "
12199                        + "for package " + cpi.packageName);
12200            }
12201
12202            final UserHandle userHandle = new UserHandle(userId);
12203            mHandler.post(new Runnable() {
12204                @Override
12205                public void run() {
12206                    mContext.startActivityAsUser(intent, userHandle);
12207                }
12208            });
12209
12210            return false;
12211        }
12212
12213        return true;
12214    }
12215
12216    /**
12217     * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
12218     * PackageManager could be unavailable at construction time and therefore needs to be accessed
12219     * on demand.
12220     */
12221    IPackageManager getPackageManager() {
12222        return AppGlobals.getPackageManager();
12223    }
12224
12225    ActivityStartController getActivityStartController() {
12226        return mActivityStartController;
12227    }
12228
12229    PackageManagerInternal getPackageManagerInternalLocked() {
12230        if (mPackageManagerInt == null) {
12231            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12232        }
12233        return mPackageManagerInt;
12234    }
12235
12236    @Override
12237    public final ContentProviderHolder getContentProvider(
12238            IApplicationThread caller, String name, int userId, boolean stable) {
12239        enforceNotIsolatedCaller("getContentProvider");
12240        if (caller == null) {
12241            String msg = "null IApplicationThread when getting content provider "
12242                    + name;
12243            Slog.w(TAG, msg);
12244            throw new SecurityException(msg);
12245        }
12246        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
12247        // with cross-user grant.
12248        return getContentProviderImpl(caller, name, null, stable, userId);
12249    }
12250
12251    public ContentProviderHolder getContentProviderExternal(
12252            String name, int userId, IBinder token) {
12253        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12254            "Do not have permission in call getContentProviderExternal()");
12255        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12256                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
12257        return getContentProviderExternalUnchecked(name, token, userId);
12258    }
12259
12260    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12261            IBinder token, int userId) {
12262        return getContentProviderImpl(null, name, token, true, userId);
12263    }
12264
12265    /**
12266     * Drop a content provider from a ProcessRecord's bookkeeping
12267     */
12268    public void removeContentProvider(IBinder connection, boolean stable) {
12269        enforceNotIsolatedCaller("removeContentProvider");
12270        long ident = Binder.clearCallingIdentity();
12271        try {
12272            synchronized (this) {
12273                ContentProviderConnection conn;
12274                try {
12275                    conn = (ContentProviderConnection)connection;
12276                } catch (ClassCastException e) {
12277                    String msg ="removeContentProvider: " + connection
12278                            + " not a ContentProviderConnection";
12279                    Slog.w(TAG, msg);
12280                    throw new IllegalArgumentException(msg);
12281                }
12282                if (conn == null) {
12283                    throw new NullPointerException("connection is null");
12284                }
12285                if (decProviderCountLocked(conn, null, null, stable)) {
12286                    updateOomAdjLocked();
12287                }
12288            }
12289        } finally {
12290            Binder.restoreCallingIdentity(ident);
12291        }
12292    }
12293
12294    public void removeContentProviderExternal(String name, IBinder token) {
12295        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12296            "Do not have permission in call removeContentProviderExternal()");
12297        int userId = UserHandle.getCallingUserId();
12298        long ident = Binder.clearCallingIdentity();
12299        try {
12300            removeContentProviderExternalUnchecked(name, token, userId);
12301        } finally {
12302            Binder.restoreCallingIdentity(ident);
12303        }
12304    }
12305
12306    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12307        synchronized (this) {
12308            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12309            if(cpr == null) {
12310                //remove from mProvidersByClass
12311                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12312                return;
12313            }
12314
12315            //update content provider record entry info
12316            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12317            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12318            if (localCpr.hasExternalProcessHandles()) {
12319                if (localCpr.removeExternalProcessHandleLocked(token)) {
12320                    updateOomAdjLocked();
12321                } else {
12322                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12323                            + " with no external reference for token: "
12324                            + token + ".");
12325                }
12326            } else {
12327                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12328                        + " with no external references.");
12329            }
12330        }
12331    }
12332
12333    public final void publishContentProviders(IApplicationThread caller,
12334            List<ContentProviderHolder> providers) {
12335        if (providers == null) {
12336            return;
12337        }
12338
12339        enforceNotIsolatedCaller("publishContentProviders");
12340        synchronized (this) {
12341            final ProcessRecord r = getRecordForAppLocked(caller);
12342            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12343            if (r == null) {
12344                throw new SecurityException(
12345                        "Unable to find app for caller " + caller
12346                      + " (pid=" + Binder.getCallingPid()
12347                      + ") when publishing content providers");
12348            }
12349
12350            final long origId = Binder.clearCallingIdentity();
12351
12352            final int N = providers.size();
12353            for (int i = 0; i < N; i++) {
12354                ContentProviderHolder src = providers.get(i);
12355                if (src == null || src.info == null || src.provider == null) {
12356                    continue;
12357                }
12358                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12359                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12360                if (dst != null) {
12361                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12362                    mProviderMap.putProviderByClass(comp, dst);
12363                    String names[] = dst.info.authority.split(";");
12364                    for (int j = 0; j < names.length; j++) {
12365                        mProviderMap.putProviderByName(names[j], dst);
12366                    }
12367
12368                    int launchingCount = mLaunchingProviders.size();
12369                    int j;
12370                    boolean wasInLaunchingProviders = false;
12371                    for (j = 0; j < launchingCount; j++) {
12372                        if (mLaunchingProviders.get(j) == dst) {
12373                            mLaunchingProviders.remove(j);
12374                            wasInLaunchingProviders = true;
12375                            j--;
12376                            launchingCount--;
12377                        }
12378                    }
12379                    if (wasInLaunchingProviders) {
12380                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12381                    }
12382                    synchronized (dst) {
12383                        dst.provider = src.provider;
12384                        dst.proc = r;
12385                        dst.notifyAll();
12386                    }
12387                    updateOomAdjLocked(r, true);
12388                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12389                            src.info.authority);
12390                }
12391            }
12392
12393            Binder.restoreCallingIdentity(origId);
12394        }
12395    }
12396
12397    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12398        ContentProviderConnection conn;
12399        try {
12400            conn = (ContentProviderConnection)connection;
12401        } catch (ClassCastException e) {
12402            String msg ="refContentProvider: " + connection
12403                    + " not a ContentProviderConnection";
12404            Slog.w(TAG, msg);
12405            throw new IllegalArgumentException(msg);
12406        }
12407        if (conn == null) {
12408            throw new NullPointerException("connection is null");
12409        }
12410
12411        synchronized (this) {
12412            if (stable > 0) {
12413                conn.numStableIncs += stable;
12414            }
12415            stable = conn.stableCount + stable;
12416            if (stable < 0) {
12417                throw new IllegalStateException("stableCount < 0: " + stable);
12418            }
12419
12420            if (unstable > 0) {
12421                conn.numUnstableIncs += unstable;
12422            }
12423            unstable = conn.unstableCount + unstable;
12424            if (unstable < 0) {
12425                throw new IllegalStateException("unstableCount < 0: " + unstable);
12426            }
12427
12428            if ((stable+unstable) <= 0) {
12429                throw new IllegalStateException("ref counts can't go to zero here: stable="
12430                        + stable + " unstable=" + unstable);
12431            }
12432            conn.stableCount = stable;
12433            conn.unstableCount = unstable;
12434            return !conn.dead;
12435        }
12436    }
12437
12438    public void unstableProviderDied(IBinder connection) {
12439        ContentProviderConnection conn;
12440        try {
12441            conn = (ContentProviderConnection)connection;
12442        } catch (ClassCastException e) {
12443            String msg ="refContentProvider: " + connection
12444                    + " not a ContentProviderConnection";
12445            Slog.w(TAG, msg);
12446            throw new IllegalArgumentException(msg);
12447        }
12448        if (conn == null) {
12449            throw new NullPointerException("connection is null");
12450        }
12451
12452        // Safely retrieve the content provider associated with the connection.
12453        IContentProvider provider;
12454        synchronized (this) {
12455            provider = conn.provider.provider;
12456        }
12457
12458        if (provider == null) {
12459            // Um, yeah, we're way ahead of you.
12460            return;
12461        }
12462
12463        // Make sure the caller is being honest with us.
12464        if (provider.asBinder().pingBinder()) {
12465            // Er, no, still looks good to us.
12466            synchronized (this) {
12467                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12468                        + " says " + conn + " died, but we don't agree");
12469                return;
12470            }
12471        }
12472
12473        // Well look at that!  It's dead!
12474        synchronized (this) {
12475            if (conn.provider.provider != provider) {
12476                // But something changed...  good enough.
12477                return;
12478            }
12479
12480            ProcessRecord proc = conn.provider.proc;
12481            if (proc == null || proc.thread == null) {
12482                // Seems like the process is already cleaned up.
12483                return;
12484            }
12485
12486            // As far as we're concerned, this is just like receiving a
12487            // death notification...  just a bit prematurely.
12488            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12489                    + ") early provider death");
12490            final long ident = Binder.clearCallingIdentity();
12491            try {
12492                appDiedLocked(proc);
12493            } finally {
12494                Binder.restoreCallingIdentity(ident);
12495            }
12496        }
12497    }
12498
12499    @Override
12500    public void appNotRespondingViaProvider(IBinder connection) {
12501        enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12502
12503        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12504        if (conn == null) {
12505            Slog.w(TAG, "ContentProviderConnection is null");
12506            return;
12507        }
12508
12509        final ProcessRecord host = conn.provider.proc;
12510        if (host == null) {
12511            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12512            return;
12513        }
12514
12515        mHandler.post(new Runnable() {
12516            @Override
12517            public void run() {
12518                mAppErrors.appNotResponding(host, null, null, false,
12519                        "ContentProvider not responding");
12520            }
12521        });
12522    }
12523
12524    public final void installSystemProviders() {
12525        List<ProviderInfo> providers;
12526        synchronized (this) {
12527            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12528            providers = generateApplicationProvidersLocked(app);
12529            if (providers != null) {
12530                for (int i=providers.size()-1; i>=0; i--) {
12531                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12532                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12533                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12534                                + ": not system .apk");
12535                        providers.remove(i);
12536                    }
12537                }
12538            }
12539        }
12540        if (providers != null) {
12541            mSystemThread.installSystemProviders(providers);
12542        }
12543
12544        mConstants.start(mContext.getContentResolver());
12545        mCoreSettingsObserver = new CoreSettingsObserver(this);
12546        mFontScaleSettingObserver = new FontScaleSettingObserver();
12547        mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
12548        GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12549
12550        // Now that the settings provider is published we can consider sending
12551        // in a rescue party.
12552        RescueParty.onSettingsProviderPublished(mContext);
12553
12554        //mUsageStatsService.monitorPackages();
12555    }
12556
12557    void startPersistentApps(int matchFlags) {
12558        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12559
12560        synchronized (this) {
12561            try {
12562                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12563                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12564                for (ApplicationInfo app : apps) {
12565                    if (!"android".equals(app.packageName)) {
12566                        addAppLocked(app, null, false, null /* ABI override */);
12567                    }
12568                }
12569            } catch (RemoteException ex) {
12570            }
12571        }
12572    }
12573
12574    /**
12575     * When a user is unlocked, we need to install encryption-unaware providers
12576     * belonging to any running apps.
12577     */
12578    void installEncryptionUnawareProviders(int userId) {
12579        // We're only interested in providers that are encryption unaware, and
12580        // we don't care about uninstalled apps, since there's no way they're
12581        // running at this point.
12582        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12583
12584        synchronized (this) {
12585            final int NP = mProcessNames.getMap().size();
12586            for (int ip = 0; ip < NP; ip++) {
12587                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12588                final int NA = apps.size();
12589                for (int ia = 0; ia < NA; ia++) {
12590                    final ProcessRecord app = apps.valueAt(ia);
12591                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12592
12593                    final int NG = app.pkgList.size();
12594                    for (int ig = 0; ig < NG; ig++) {
12595                        try {
12596                            final String pkgName = app.pkgList.keyAt(ig);
12597                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12598                                    .getPackageInfo(pkgName, matchFlags, userId);
12599                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12600                                for (ProviderInfo pi : pkgInfo.providers) {
12601                                    // TODO: keep in sync with generateApplicationProvidersLocked
12602                                    final boolean processMatch = Objects.equals(pi.processName,
12603                                            app.processName) || pi.multiprocess;
12604                                    final boolean userMatch = isSingleton(pi.processName,
12605                                            pi.applicationInfo, pi.name, pi.flags)
12606                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12607                                    if (processMatch && userMatch) {
12608                                        Log.v(TAG, "Installing " + pi);
12609                                        app.thread.scheduleInstallProvider(pi);
12610                                    } else {
12611                                        Log.v(TAG, "Skipping " + pi);
12612                                    }
12613                                }
12614                            }
12615                        } catch (RemoteException ignored) {
12616                        }
12617                    }
12618                }
12619            }
12620        }
12621    }
12622
12623    /**
12624     * Allows apps to retrieve the MIME type of a URI.
12625     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12626     * users, then it does not need permission to access the ContentProvider.
12627     * Either, it needs cross-user uri grants.
12628     *
12629     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12630     *
12631     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12632     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12633     */
12634    public String getProviderMimeType(Uri uri, int userId) {
12635        enforceNotIsolatedCaller("getProviderMimeType");
12636        final String name = uri.getAuthority();
12637        int callingUid = Binder.getCallingUid();
12638        int callingPid = Binder.getCallingPid();
12639        long ident = 0;
12640        boolean clearedIdentity = false;
12641        userId = mUserController.unsafeConvertIncomingUser(userId);
12642        if (canClearIdentity(callingPid, callingUid, userId)) {
12643            clearedIdentity = true;
12644            ident = Binder.clearCallingIdentity();
12645        }
12646        ContentProviderHolder holder = null;
12647        try {
12648            holder = getContentProviderExternalUnchecked(name, null, userId);
12649            if (holder != null) {
12650                return holder.provider.getType(uri);
12651            }
12652        } catch (RemoteException e) {
12653            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12654            return null;
12655        } catch (Exception e) {
12656            Log.w(TAG, "Exception while determining type of " + uri, e);
12657            return null;
12658        } finally {
12659            // We need to clear the identity to call removeContentProviderExternalUnchecked
12660            if (!clearedIdentity) {
12661                ident = Binder.clearCallingIdentity();
12662            }
12663            try {
12664                if (holder != null) {
12665                    removeContentProviderExternalUnchecked(name, null, userId);
12666                }
12667            } finally {
12668                Binder.restoreCallingIdentity(ident);
12669            }
12670        }
12671
12672        return null;
12673    }
12674
12675    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12676        if (UserHandle.getUserId(callingUid) == userId) {
12677            return true;
12678        }
12679        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12680                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12681                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12682                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12683                return true;
12684        }
12685        return false;
12686    }
12687
12688    // =========================================================
12689    // GLOBAL MANAGEMENT
12690    // =========================================================
12691
12692    @GuardedBy("this")
12693    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12694            boolean isolated, int isolatedUid) {
12695        String proc = customProcess != null ? customProcess : info.processName;
12696        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12697        final int userId = UserHandle.getUserId(info.uid);
12698        int uid = info.uid;
12699        if (isolated) {
12700            if (isolatedUid == 0) {
12701                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12702                while (true) {
12703                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12704                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12705                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12706                    }
12707                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12708                    mNextIsolatedProcessUid++;
12709                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12710                        // No process for this uid, use it.
12711                        break;
12712                    }
12713                    stepsLeft--;
12714                    if (stepsLeft <= 0) {
12715                        return null;
12716                    }
12717                }
12718            } else {
12719                // Special case for startIsolatedProcess (internal only), where
12720                // the uid of the isolated process is specified by the caller.
12721                uid = isolatedUid;
12722            }
12723            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12724
12725            // Register the isolated UID with this application so BatteryStats knows to
12726            // attribute resource usage to the application.
12727            //
12728            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12729            // about the process state of the isolated UID *before* it is registered with the
12730            // owning application.
12731            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12732        }
12733        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12734        if (!mBooted && !mBooting
12735                && userId == UserHandle.USER_SYSTEM
12736                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12737            // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
12738            r.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
12739            r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
12740            r.persistent = true;
12741            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12742        }
12743        if (isolated && isolatedUid != 0) {
12744            // Special case for startIsolatedProcess (internal only) - assume the process
12745            // is required by the system server to prevent it being killed.
12746            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
12747        }
12748        addProcessNameLocked(r);
12749        return r;
12750    }
12751
12752    private boolean uidOnBackgroundWhitelist(final int uid) {
12753        final int appId = UserHandle.getAppId(uid);
12754        final int[] whitelist = mBackgroundAppIdWhitelist;
12755        final int N = whitelist.length;
12756        for (int i = 0; i < N; i++) {
12757            if (appId == whitelist[i]) {
12758                return true;
12759            }
12760        }
12761        return false;
12762    }
12763
12764    @Override
12765    public void backgroundWhitelistUid(final int uid) {
12766        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12767            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12768        }
12769
12770        if (DEBUG_BACKGROUND_CHECK) {
12771            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12772        }
12773        synchronized (this) {
12774            final int N = mBackgroundAppIdWhitelist.length;
12775            int[] newList = new int[N+1];
12776            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12777            newList[N] = UserHandle.getAppId(uid);
12778            mBackgroundAppIdWhitelist = newList;
12779        }
12780    }
12781
12782    @GuardedBy("this")
12783    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12784            String abiOverride) {
12785        ProcessRecord app;
12786        if (!isolated) {
12787            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12788                    info.uid, true);
12789        } else {
12790            app = null;
12791        }
12792
12793        if (app == null) {
12794            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12795            updateLruProcessLocked(app, false, null);
12796            updateOomAdjLocked();
12797        }
12798
12799        // This package really, really can not be stopped.
12800        try {
12801            AppGlobals.getPackageManager().setPackageStoppedState(
12802                    info.packageName, false, UserHandle.getUserId(app.uid));
12803        } catch (RemoteException e) {
12804        } catch (IllegalArgumentException e) {
12805            Slog.w(TAG, "Failed trying to unstop package "
12806                    + info.packageName + ": " + e);
12807        }
12808
12809        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12810            app.persistent = true;
12811            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12812        }
12813        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12814            mPersistentStartingProcesses.add(app);
12815            startProcessLocked(app, "added application",
12816                    customProcess != null ? customProcess : app.processName, abiOverride);
12817        }
12818
12819        return app;
12820    }
12821
12822    public void unhandledBack() {
12823        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12824                "unhandledBack()");
12825
12826        synchronized(this) {
12827            final long origId = Binder.clearCallingIdentity();
12828            try {
12829                getFocusedStack().unhandledBackLocked();
12830            } finally {
12831                Binder.restoreCallingIdentity(origId);
12832            }
12833        }
12834    }
12835
12836    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12837        enforceNotIsolatedCaller("openContentUri");
12838        final int userId = UserHandle.getCallingUserId();
12839        final Uri uri = Uri.parse(uriString);
12840        String name = uri.getAuthority();
12841        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12842        ParcelFileDescriptor pfd = null;
12843        if (cph != null) {
12844            // We record the binder invoker's uid in thread-local storage before
12845            // going to the content provider to open the file.  Later, in the code
12846            // that handles all permissions checks, we look for this uid and use
12847            // that rather than the Activity Manager's own uid.  The effect is that
12848            // we do the check against the caller's permissions even though it looks
12849            // to the content provider like the Activity Manager itself is making
12850            // the request.
12851            Binder token = new Binder();
12852            sCallerIdentity.set(new Identity(
12853                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12854            try {
12855                pfd = cph.provider.openFile(null, uri, "r", null, token);
12856            } catch (FileNotFoundException e) {
12857                // do nothing; pfd will be returned null
12858            } finally {
12859                // Ensure that whatever happens, we clean up the identity state
12860                sCallerIdentity.remove();
12861                // Ensure we're done with the provider.
12862                removeContentProviderExternalUnchecked(name, null, userId);
12863            }
12864        } else {
12865            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12866        }
12867        return pfd;
12868    }
12869
12870    // Actually is sleeping or shutting down or whatever else in the future
12871    // is an inactive state.
12872    boolean isSleepingOrShuttingDownLocked() {
12873        return isSleepingLocked() || mShuttingDown;
12874    }
12875
12876    boolean isShuttingDownLocked() {
12877        return mShuttingDown;
12878    }
12879
12880    boolean isSleepingLocked() {
12881        return mSleeping;
12882    }
12883
12884    void onWakefulnessChanged(int wakefulness) {
12885        synchronized(this) {
12886            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12887            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12888            mWakefulness = wakefulness;
12889
12890            if (wasAwake != isAwake) {
12891                // Also update state in a special way for running foreground services UI.
12892                mServices.updateScreenStateLocked(isAwake);
12893                mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12894                        .sendToTarget();
12895            }
12896        }
12897    }
12898
12899    @GuardedBy("this")
12900    void finishRunningVoiceLocked() {
12901        if (mRunningVoice != null) {
12902            mRunningVoice = null;
12903            mVoiceWakeLock.release();
12904            updateSleepIfNeededLocked();
12905        }
12906    }
12907
12908    void startTimeTrackingFocusedActivityLocked() {
12909        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12910        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12911            mCurAppTimeTracker.start(resumedActivity.packageName);
12912        }
12913    }
12914
12915    @GuardedBy("this")
12916    void updateSleepIfNeededLocked() {
12917        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12918        final boolean wasSleeping = mSleeping;
12919
12920        if (!shouldSleep) {
12921            // If wasSleeping is true, we need to wake up activity manager state from when
12922            // we started sleeping. In either case, we need to apply the sleep tokens, which
12923            // will wake up stacks or put them to sleep as appropriate.
12924            if (wasSleeping) {
12925                mSleeping = false;
12926                startTimeTrackingFocusedActivityLocked();
12927                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12928                mStackSupervisor.comeOutOfSleepIfNeededLocked();
12929            }
12930            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12931            if (wasSleeping) {
12932                updateOomAdjLocked();
12933            }
12934        } else if (!mSleeping && shouldSleep) {
12935            mSleeping = true;
12936            if (mCurAppTimeTracker != null) {
12937                mCurAppTimeTracker.stop();
12938            }
12939            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12940            mStackSupervisor.goingToSleepLocked();
12941            updateOomAdjLocked();
12942        }
12943    }
12944
12945    /** Pokes the task persister. */
12946    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12947        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12948    }
12949
12950    /**
12951     * Notifies all listeners when the pinned stack animation starts.
12952     */
12953    @Override
12954    public void notifyPinnedStackAnimationStarted() {
12955        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12956    }
12957
12958    /**
12959     * Notifies all listeners when the pinned stack animation ends.
12960     */
12961    @Override
12962    public void notifyPinnedStackAnimationEnded() {
12963        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12964    }
12965
12966    @Override
12967    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12968        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12969    }
12970
12971    @Override
12972    public boolean shutdown(int timeout) {
12973        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12974                != PackageManager.PERMISSION_GRANTED) {
12975            throw new SecurityException("Requires permission "
12976                    + android.Manifest.permission.SHUTDOWN);
12977        }
12978
12979        // TODO: Where should the corresponding '1' (start) write go?
12980        StatsLog.write(StatsLog.DEVICE_ON_STATUS_CHANGED,
12981                StatsLog.DEVICE_ON_STATUS_CHANGED__STATE__OFF);
12982
12983        boolean timedout = false;
12984
12985        synchronized(this) {
12986            mShuttingDown = true;
12987            mStackSupervisor.prepareForShutdownLocked();
12988            updateEventDispatchingLocked();
12989            timedout = mStackSupervisor.shutdownLocked(timeout);
12990        }
12991
12992        mAppOpsService.shutdown();
12993        if (mUsageStatsService != null) {
12994            mUsageStatsService.prepareShutdown();
12995        }
12996        mBatteryStatsService.shutdown();
12997        synchronized (this) {
12998            mProcessStats.shutdownLocked();
12999            notifyTaskPersisterLocked(null, true);
13000        }
13001
13002        return timedout;
13003    }
13004
13005    public final void activitySlept(IBinder token) {
13006        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
13007
13008        final long origId = Binder.clearCallingIdentity();
13009
13010        synchronized (this) {
13011            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13012            if (r != null) {
13013                mStackSupervisor.activitySleptLocked(r);
13014            }
13015        }
13016
13017        Binder.restoreCallingIdentity(origId);
13018    }
13019
13020    @GuardedBy("this")
13021    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
13022        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
13023        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
13024        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
13025            boolean wasRunningVoice = mRunningVoice != null;
13026            mRunningVoice = session;
13027            if (!wasRunningVoice) {
13028                mVoiceWakeLock.acquire();
13029                updateSleepIfNeededLocked();
13030            }
13031        }
13032    }
13033
13034    private void updateEventDispatchingLocked() {
13035        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
13036    }
13037
13038    @Override
13039    public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
13040        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
13041                != PackageManager.PERMISSION_GRANTED) {
13042            throw new SecurityException("Requires permission "
13043                    + android.Manifest.permission.DEVICE_POWER);
13044        }
13045
13046        synchronized(this) {
13047            long ident = Binder.clearCallingIdentity();
13048            try {
13049                mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
13050            } finally {
13051                Binder.restoreCallingIdentity(ident);
13052            }
13053        }
13054
13055        mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
13056                .sendToTarget();
13057    }
13058
13059    @Override
13060    public void notifyLockedProfile(@UserIdInt int userId) {
13061        try {
13062            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
13063                throw new SecurityException("Only privileged app can call notifyLockedProfile");
13064            }
13065        } catch (RemoteException ex) {
13066            throw new SecurityException("Fail to check is caller a privileged app", ex);
13067        }
13068
13069        synchronized (this) {
13070            final long ident = Binder.clearCallingIdentity();
13071            try {
13072                if (mUserController.shouldConfirmCredentials(userId)) {
13073                    if (mKeyguardController.isKeyguardLocked()) {
13074                        // Showing launcher to avoid user entering credential twice.
13075                        final int currentUserId = mUserController.getCurrentUserId();
13076                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
13077                    }
13078                    mStackSupervisor.lockAllProfileTasks(userId);
13079                }
13080            } finally {
13081                Binder.restoreCallingIdentity(ident);
13082            }
13083        }
13084    }
13085
13086    @Override
13087    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
13088        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
13089        synchronized (this) {
13090            final long ident = Binder.clearCallingIdentity();
13091            try {
13092                intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
13093                        FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
13094                        FLAG_ACTIVITY_TASK_ON_HOME);
13095                ActivityOptions activityOptions = options != null
13096                        ? new ActivityOptions(options)
13097                        : ActivityOptions.makeBasic();
13098                activityOptions.setLaunchTaskId(
13099                        mStackSupervisor.getHomeActivity().getTask().taskId);
13100                mContext.startActivityAsUser(intent, activityOptions.toBundle(),
13101                        UserHandle.CURRENT);
13102            } finally {
13103                Binder.restoreCallingIdentity(ident);
13104            }
13105        }
13106    }
13107
13108    @Override
13109    public void stopAppSwitches() {
13110        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
13111                != PackageManager.PERMISSION_GRANTED) {
13112            throw new SecurityException("viewquires permission "
13113                    + android.Manifest.permission.STOP_APP_SWITCHES);
13114        }
13115
13116        synchronized(this) {
13117            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
13118                    + APP_SWITCH_DELAY_TIME;
13119            mDidAppSwitch = false;
13120            mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
13121        }
13122    }
13123
13124    public void resumeAppSwitches() {
13125        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
13126                != PackageManager.PERMISSION_GRANTED) {
13127            throw new SecurityException("Requires permission "
13128                    + android.Manifest.permission.STOP_APP_SWITCHES);
13129        }
13130
13131        synchronized(this) {
13132            // Note that we don't execute any pending app switches... we will
13133            // let those wait until either the timeout, or the next start
13134            // activity request.
13135            mAppSwitchesAllowedTime = 0;
13136        }
13137    }
13138
13139    boolean checkAllowAppSwitchUid(int uid) {
13140        ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
13141        if (types != null) {
13142            for (int i = types.size() - 1; i >= 0; i--) {
13143                if (types.valueAt(i).intValue() == uid) {
13144                    return true;
13145                }
13146            }
13147        }
13148        return false;
13149    }
13150
13151    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
13152            int callingPid, int callingUid, String name) {
13153        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
13154            return true;
13155        }
13156
13157        int perm = checkComponentPermission(
13158                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
13159                sourceUid, -1, true);
13160        if (perm == PackageManager.PERMISSION_GRANTED) {
13161            return true;
13162        }
13163        if (checkAllowAppSwitchUid(sourceUid)) {
13164            return true;
13165        }
13166
13167        // If the actual IPC caller is different from the logical source, then
13168        // also see if they are allowed to control app switches.
13169        if (callingUid != -1 && callingUid != sourceUid) {
13170            perm = checkComponentPermission(
13171                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
13172                    callingUid, -1, true);
13173            if (perm == PackageManager.PERMISSION_GRANTED) {
13174                return true;
13175            }
13176            if (checkAllowAppSwitchUid(callingUid)) {
13177                return true;
13178            }
13179        }
13180
13181        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
13182        return false;
13183    }
13184
13185    public void setDebugApp(String packageName, boolean waitForDebugger,
13186            boolean persistent) {
13187        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
13188                "setDebugApp()");
13189
13190        long ident = Binder.clearCallingIdentity();
13191        try {
13192            // Note that this is not really thread safe if there are multiple
13193            // callers into it at the same time, but that's not a situation we
13194            // care about.
13195            if (persistent) {
13196                final ContentResolver resolver = mContext.getContentResolver();
13197                Settings.Global.putString(
13198                    resolver, Settings.Global.DEBUG_APP,
13199                    packageName);
13200                Settings.Global.putInt(
13201                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13202                    waitForDebugger ? 1 : 0);
13203            }
13204
13205            synchronized (this) {
13206                if (!persistent) {
13207                    mOrigDebugApp = mDebugApp;
13208                    mOrigWaitForDebugger = mWaitForDebugger;
13209                }
13210                mDebugApp = packageName;
13211                mWaitForDebugger = waitForDebugger;
13212                mDebugTransient = !persistent;
13213                if (packageName != null) {
13214                    forceStopPackageLocked(packageName, -1, false, false, true, true,
13215                            false, UserHandle.USER_ALL, "set debug app");
13216                }
13217            }
13218        } finally {
13219            Binder.restoreCallingIdentity(ident);
13220        }
13221    }
13222
13223    /**
13224     * Set or remove an agent to be run whenever an app with the given process name starts.
13225     *
13226     * This method will not check whether the given process name matches a debuggable app. That
13227     * would require scanning all current packages, and a rescan when new packages are installed
13228     * or updated.
13229     *
13230     * Instead, do the check when an application is started and matched to a stored agent.
13231     *
13232     * @param packageName the process name of the app.
13233     * @param agent the agent string to be used, or null to remove any previously set agent.
13234     */
13235    @Override
13236    public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
13237        synchronized (this) {
13238            // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13239            // its own permission.
13240            if (checkCallingPermission(
13241                    android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
13242                        PackageManager.PERMISSION_GRANTED) {
13243                throw new SecurityException(
13244                        "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13245            }
13246
13247            if (agent == null) {
13248                if (mAppAgentMap != null) {
13249                    mAppAgentMap.remove(packageName);
13250                    if (mAppAgentMap.isEmpty()) {
13251                        mAppAgentMap = null;
13252                    }
13253                }
13254            } else {
13255                if (mAppAgentMap == null) {
13256                    mAppAgentMap = new HashMap<>();
13257                }
13258                if (mAppAgentMap.size() >= 100) {
13259                    // Limit the size of the map, to avoid OOMEs.
13260                    Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
13261                            + "/" + agent);
13262                    return;
13263                }
13264                mAppAgentMap.put(packageName, agent);
13265            }
13266        }
13267    }
13268
13269    void setTrackAllocationApp(ApplicationInfo app, String processName) {
13270        synchronized (this) {
13271            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13272            if (!isDebuggable) {
13273                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13274                    throw new SecurityException("Process not debuggable: " + app.packageName);
13275                }
13276            }
13277
13278            mTrackAllocationApp = processName;
13279        }
13280    }
13281
13282    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
13283        synchronized (this) {
13284            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13285            if (!isDebuggable) {
13286                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13287                    throw new SecurityException("Process not debuggable: " + app.packageName);
13288                }
13289            }
13290            mProfileApp = processName;
13291
13292            if (mProfilerInfo != null) {
13293                if (mProfilerInfo.profileFd != null) {
13294                    try {
13295                        mProfilerInfo.profileFd.close();
13296                    } catch (IOException e) {
13297                    }
13298                }
13299            }
13300            mProfilerInfo = new ProfilerInfo(profilerInfo);
13301            mProfileType = 0;
13302        }
13303    }
13304
13305    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
13306        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13307        if (!isDebuggable) {
13308            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13309                throw new SecurityException("Process not debuggable: " + app.packageName);
13310            }
13311        }
13312        mNativeDebuggingApp = processName;
13313    }
13314
13315    @Override
13316    public void setAlwaysFinish(boolean enabled) {
13317        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13318                "setAlwaysFinish()");
13319
13320        long ident = Binder.clearCallingIdentity();
13321        try {
13322            Settings.Global.putInt(
13323                    mContext.getContentResolver(),
13324                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13325
13326            synchronized (this) {
13327                mAlwaysFinishActivities = enabled;
13328            }
13329        } finally {
13330            Binder.restoreCallingIdentity(ident);
13331        }
13332    }
13333
13334    @Override
13335    public void setActivityController(IActivityController controller, boolean imAMonkey) {
13336        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13337                "setActivityController()");
13338        synchronized (this) {
13339            mController = controller;
13340            mControllerIsAMonkey = imAMonkey;
13341            Watchdog.getInstance().setActivityController(controller);
13342        }
13343    }
13344
13345    @Override
13346    public void setUserIsMonkey(boolean userIsMonkey) {
13347        synchronized (this) {
13348            synchronized (mPidsSelfLocked) {
13349                final int callingPid = Binder.getCallingPid();
13350                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13351                if (proc == null) {
13352                    throw new SecurityException("Unknown process: " + callingPid);
13353                }
13354                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13355                    throw new SecurityException("Only an instrumentation process "
13356                            + "with a UiAutomation can call setUserIsMonkey");
13357                }
13358            }
13359            mUserIsMonkey = userIsMonkey;
13360        }
13361    }
13362
13363    @Override
13364    public boolean isUserAMonkey() {
13365        synchronized (this) {
13366            // If there is a controller also implies the user is a monkey.
13367            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13368        }
13369    }
13370
13371    /**
13372     * @deprecated This method is only used by a few internal components and it will soon be
13373     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13374     * No new code should be calling it.
13375     */
13376    @Deprecated
13377    @Override
13378    public void requestBugReport(int bugreportType) {
13379        String extraOptions = null;
13380        switch (bugreportType) {
13381            case ActivityManager.BUGREPORT_OPTION_FULL:
13382                // Default options.
13383                break;
13384            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13385                extraOptions = "bugreportplus";
13386                break;
13387            case ActivityManager.BUGREPORT_OPTION_REMOTE:
13388                extraOptions = "bugreportremote";
13389                break;
13390            case ActivityManager.BUGREPORT_OPTION_WEAR:
13391                extraOptions = "bugreportwear";
13392                break;
13393            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13394                extraOptions = "bugreporttelephony";
13395                break;
13396            case ActivityManager.BUGREPORT_OPTION_WIFI:
13397                extraOptions = "bugreportwifi";
13398                break;
13399            default:
13400                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13401                        + bugreportType);
13402        }
13403        // Always log caller, even if it does not have permission to dump.
13404        String type = extraOptions == null ? "bugreport" : extraOptions;
13405        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13406
13407        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13408        if (extraOptions != null) {
13409            SystemProperties.set("dumpstate.options", extraOptions);
13410        }
13411        SystemProperties.set("ctl.start", "bugreport");
13412    }
13413
13414    /**
13415     * @deprecated This method is only used by a few internal components and it will soon be
13416     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13417     * No new code should be calling it.
13418     */
13419    @Deprecated
13420    private void requestBugReportWithDescription(String shareTitle, String shareDescription,
13421                                                 int bugreportType) {
13422        if (!TextUtils.isEmpty(shareTitle)) {
13423            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13424                String errorStr = "shareTitle should be less than " +
13425                        MAX_BUGREPORT_TITLE_SIZE + " characters";
13426                throw new IllegalArgumentException(errorStr);
13427            } else {
13428                if (!TextUtils.isEmpty(shareDescription)) {
13429                    int length;
13430                    try {
13431                        length = shareDescription.getBytes("UTF-8").length;
13432                    } catch (UnsupportedEncodingException e) {
13433                        String errorStr = "shareDescription: UnsupportedEncodingException";
13434                        throw new IllegalArgumentException(errorStr);
13435                    }
13436                    if (length > SystemProperties.PROP_VALUE_MAX) {
13437                        String errorStr = "shareTitle should be less than " +
13438                                SystemProperties.PROP_VALUE_MAX + " bytes";
13439                        throw new IllegalArgumentException(errorStr);
13440                    } else {
13441                        SystemProperties.set("dumpstate.options.description", shareDescription);
13442                    }
13443                }
13444                SystemProperties.set("dumpstate.options.title", shareTitle);
13445            }
13446        }
13447
13448        Slog.d(TAG, "Bugreport notification title " + shareTitle
13449                + " description " + shareDescription);
13450        requestBugReport(bugreportType);
13451    }
13452
13453    /**
13454     * @deprecated This method is only used by a few internal components and it will soon be
13455     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13456     * No new code should be calling it.
13457     */
13458    @Deprecated
13459    @Override
13460    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13461        requestBugReportWithDescription(shareTitle, shareDescription,
13462                ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13463    }
13464
13465    /**
13466     * @deprecated This method is only used by a few internal components and it will soon be
13467     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13468     * No new code should be calling it.
13469     */
13470    @Deprecated
13471    @Override
13472    public void requestWifiBugReport(String shareTitle, String shareDescription) {
13473        requestBugReportWithDescription(shareTitle, shareDescription,
13474                ActivityManager.BUGREPORT_OPTION_WIFI);
13475    }
13476
13477
13478    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13479        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13480    }
13481
13482    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13483        if (r != null && (r.instr != null || r.usingWrapper)) {
13484            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13485        }
13486        return KEY_DISPATCHING_TIMEOUT;
13487    }
13488
13489    @Override
13490    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13491        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13492                != PackageManager.PERMISSION_GRANTED) {
13493            throw new SecurityException("Requires permission "
13494                    + android.Manifest.permission.FILTER_EVENTS);
13495        }
13496        ProcessRecord proc;
13497        long timeout;
13498        synchronized (this) {
13499            synchronized (mPidsSelfLocked) {
13500                proc = mPidsSelfLocked.get(pid);
13501            }
13502            timeout = getInputDispatchingTimeoutLocked(proc);
13503        }
13504
13505        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13506            return -1;
13507        }
13508
13509        return timeout;
13510    }
13511
13512    /**
13513     * Handle input dispatching timeouts.
13514     * Returns whether input dispatching should be aborted or not.
13515     */
13516    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13517            final ActivityRecord activity, final ActivityRecord parent,
13518            final boolean aboveSystem, String reason) {
13519        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13520                != PackageManager.PERMISSION_GRANTED) {
13521            throw new SecurityException("Requires permission "
13522                    + android.Manifest.permission.FILTER_EVENTS);
13523        }
13524
13525        final String annotation;
13526        if (reason == null) {
13527            annotation = "Input dispatching timed out";
13528        } else {
13529            annotation = "Input dispatching timed out (" + reason + ")";
13530        }
13531
13532        if (proc != null) {
13533            synchronized (this) {
13534                if (proc.debugging) {
13535                    return false;
13536                }
13537
13538                if (proc.instr != null) {
13539                    Bundle info = new Bundle();
13540                    info.putString("shortMsg", "keyDispatchingTimedOut");
13541                    info.putString("longMsg", annotation);
13542                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13543                    return true;
13544                }
13545            }
13546            mHandler.post(new Runnable() {
13547                @Override
13548                public void run() {
13549                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13550                }
13551            });
13552        }
13553
13554        return true;
13555    }
13556
13557    @Override
13558    public Bundle getAssistContextExtras(int requestType) {
13559        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13560                null, null, true /* focused */, true /* newSessionId */,
13561                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13562        if (pae == null) {
13563            return null;
13564        }
13565        synchronized (pae) {
13566            while (!pae.haveResult) {
13567                try {
13568                    pae.wait();
13569                } catch (InterruptedException e) {
13570                }
13571            }
13572        }
13573        synchronized (this) {
13574            buildAssistBundleLocked(pae, pae.result);
13575            mPendingAssistExtras.remove(pae);
13576            mUiHandler.removeCallbacks(pae);
13577        }
13578        return pae.extras;
13579    }
13580
13581    @Override
13582    public boolean isAssistDataAllowedOnCurrentActivity() {
13583        int userId;
13584        synchronized (this) {
13585            final ActivityStack focusedStack = getFocusedStack();
13586            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
13587                return false;
13588            }
13589
13590            final ActivityRecord activity = focusedStack.getTopActivity();
13591            if (activity == null) {
13592                return false;
13593            }
13594            userId = activity.userId;
13595        }
13596        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13597                Context.DEVICE_POLICY_SERVICE);
13598        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13599    }
13600
13601    @Override
13602    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13603        long ident = Binder.clearCallingIdentity();
13604        try {
13605            synchronized (this) {
13606                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13607                ActivityRecord top = getFocusedStack().getTopActivity();
13608                if (top != caller) {
13609                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13610                            + " is not current top " + top);
13611                    return false;
13612                }
13613                if (!top.nowVisible) {
13614                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13615                            + " is not visible");
13616                    return false;
13617                }
13618            }
13619            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13620                    token);
13621        } finally {
13622            Binder.restoreCallingIdentity(ident);
13623        }
13624    }
13625
13626    @Override
13627    public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
13628            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13629        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13630                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13631                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13632    }
13633
13634    @Override
13635    public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
13636            IBinder activityToken, int flags) {
13637        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13638                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13639                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13640    }
13641
13642    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13643            IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13644            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13645            int flags) {
13646        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13647                "enqueueAssistContext()");
13648
13649        synchronized (this) {
13650            ActivityRecord activity = getFocusedStack().getTopActivity();
13651            if (activity == null) {
13652                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13653                return null;
13654            }
13655            if (activity.app == null || activity.app.thread == null) {
13656                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13657                return null;
13658            }
13659            if (focused) {
13660                if (activityToken != null) {
13661                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13662                    if (activity != caller) {
13663                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13664                                + " is not current top " + activity);
13665                        return null;
13666                    }
13667                }
13668            } else {
13669                activity = ActivityRecord.forTokenLocked(activityToken);
13670                if (activity == null) {
13671                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13672                            + " couldn't be found");
13673                    return null;
13674                }
13675                if (activity.app == null || activity.app.thread == null) {
13676                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13677                    return null;
13678                }
13679            }
13680
13681            PendingAssistExtras pae;
13682            Bundle extras = new Bundle();
13683            if (args != null) {
13684                extras.putAll(args);
13685            }
13686            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13687            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13688
13689            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13690                    userHandle);
13691            pae.isHome = activity.isActivityTypeHome();
13692
13693            // Increment the sessionId if necessary
13694            if (newSessionId) {
13695                mViSessionId++;
13696            }
13697            try {
13698                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13699                        mViSessionId, flags);
13700                mPendingAssistExtras.add(pae);
13701                mUiHandler.postDelayed(pae, timeout);
13702            } catch (RemoteException e) {
13703                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13704                return null;
13705            }
13706            return pae;
13707        }
13708    }
13709
13710    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13711        IAssistDataReceiver receiver;
13712        synchronized (this) {
13713            mPendingAssistExtras.remove(pae);
13714            receiver = pae.receiver;
13715        }
13716        if (receiver != null) {
13717            // Caller wants result sent back to them.
13718            Bundle sendBundle = new Bundle();
13719            // At least return the receiver extras
13720            sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13721            try {
13722                pae.receiver.onHandleAssistData(sendBundle);
13723            } catch (RemoteException e) {
13724            }
13725        }
13726    }
13727
13728    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13729        if (result != null) {
13730            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13731        }
13732        if (pae.hint != null) {
13733            pae.extras.putBoolean(pae.hint, true);
13734        }
13735    }
13736
13737    /** Called from an app when assist data is ready. */
13738    @Override
13739    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13740            AssistContent content, Uri referrer) {
13741        PendingAssistExtras pae = (PendingAssistExtras)token;
13742        synchronized (pae) {
13743            pae.result = extras;
13744            pae.structure = structure;
13745            pae.content = content;
13746            if (referrer != null) {
13747                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13748            }
13749            if (structure != null) {
13750                structure.setHomeActivity(pae.isHome);
13751            }
13752            pae.haveResult = true;
13753            pae.notifyAll();
13754            if (pae.intent == null && pae.receiver == null) {
13755                // Caller is just waiting for the result.
13756                return;
13757            }
13758        }
13759        // We are now ready to launch the assist activity.
13760        IAssistDataReceiver sendReceiver = null;
13761        Bundle sendBundle = null;
13762        synchronized (this) {
13763            buildAssistBundleLocked(pae, extras);
13764            boolean exists = mPendingAssistExtras.remove(pae);
13765            mUiHandler.removeCallbacks(pae);
13766            if (!exists) {
13767                // Timed out.
13768                return;
13769            }
13770
13771            if ((sendReceiver=pae.receiver) != null) {
13772                // Caller wants result sent back to them.
13773                sendBundle = new Bundle();
13774                sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
13775                sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
13776                sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
13777                sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13778            }
13779        }
13780        if (sendReceiver != null) {
13781            try {
13782                sendReceiver.onHandleAssistData(sendBundle);
13783            } catch (RemoteException e) {
13784            }
13785            return;
13786        }
13787
13788        final long ident = Binder.clearCallingIdentity();
13789        try {
13790            if (TextUtils.equals(pae.intent.getAction(),
13791                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13792                pae.intent.putExtras(pae.extras);
13793                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13794            } else {
13795                pae.intent.replaceExtras(pae.extras);
13796                pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
13797                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
13798                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13799                closeSystemDialogs("assist");
13800
13801                try {
13802                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13803                } catch (ActivityNotFoundException e) {
13804                    Slog.w(TAG, "No activity to handle assist action.", e);
13805                }
13806            }
13807        } finally {
13808            Binder.restoreCallingIdentity(ident);
13809        }
13810    }
13811
13812    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13813            Bundle args) {
13814        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13815                true /* focused */, true /* newSessionId */, userHandle, args,
13816                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13817    }
13818
13819    public void registerProcessObserver(IProcessObserver observer) {
13820        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13821                "registerProcessObserver()");
13822        synchronized (this) {
13823            mProcessObservers.register(observer);
13824        }
13825    }
13826
13827    @Override
13828    public void unregisterProcessObserver(IProcessObserver observer) {
13829        synchronized (this) {
13830            mProcessObservers.unregister(observer);
13831        }
13832    }
13833
13834    @Override
13835    public int getUidProcessState(int uid, String callingPackage) {
13836        if (!hasUsageStatsPermission(callingPackage)) {
13837            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13838                    "getUidProcessState");
13839        }
13840
13841        synchronized (this) {
13842            UidRecord uidRec = mActiveUids.get(uid);
13843            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13844        }
13845    }
13846
13847    @Override
13848    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13849            String callingPackage) {
13850        if (!hasUsageStatsPermission(callingPackage)) {
13851            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13852                    "registerUidObserver");
13853        }
13854        synchronized (this) {
13855            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13856                    callingPackage, which, cutpoint));
13857        }
13858    }
13859
13860    @Override
13861    public void unregisterUidObserver(IUidObserver observer) {
13862        synchronized (this) {
13863            mUidObservers.unregister(observer);
13864        }
13865    }
13866
13867    @Override
13868    public boolean convertFromTranslucent(IBinder token) {
13869        final long origId = Binder.clearCallingIdentity();
13870        try {
13871            synchronized (this) {
13872                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13873                if (r == null) {
13874                    return false;
13875                }
13876                final boolean translucentChanged = r.changeWindowTranslucency(true);
13877                if (translucentChanged) {
13878                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13879                }
13880                mWindowManager.setAppFullscreen(token, true);
13881                return translucentChanged;
13882            }
13883        } finally {
13884            Binder.restoreCallingIdentity(origId);
13885        }
13886    }
13887
13888    @Override
13889    public boolean convertToTranslucent(IBinder token, Bundle options) {
13890        SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
13891        final long origId = Binder.clearCallingIdentity();
13892        try {
13893            synchronized (this) {
13894                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13895                if (r == null) {
13896                    return false;
13897                }
13898                final TaskRecord task = r.getTask();
13899                int index = task.mActivities.lastIndexOf(r);
13900                if (index > 0) {
13901                    ActivityRecord under = task.mActivities.get(index - 1);
13902                    under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
13903                }
13904                final boolean translucentChanged = r.changeWindowTranslucency(false);
13905                if (translucentChanged) {
13906                    r.getStack().convertActivityToTranslucent(r);
13907                }
13908                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13909                mWindowManager.setAppFullscreen(token, false);
13910                return translucentChanged;
13911            }
13912        } finally {
13913            Binder.restoreCallingIdentity(origId);
13914        }
13915    }
13916
13917    @Override
13918    public Bundle getActivityOptions(IBinder token) {
13919        final long origId = Binder.clearCallingIdentity();
13920        try {
13921            synchronized (this) {
13922                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13923                if (r != null) {
13924                    final ActivityOptions activityOptions = r.takeOptionsLocked();
13925                    return activityOptions == null ? null : activityOptions.toBundle();
13926                }
13927                return null;
13928            }
13929        } finally {
13930            Binder.restoreCallingIdentity(origId);
13931        }
13932    }
13933
13934    @Override
13935    public void setImmersive(IBinder token, boolean immersive) {
13936        synchronized(this) {
13937            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13938            if (r == null) {
13939                throw new IllegalArgumentException();
13940            }
13941            r.immersive = immersive;
13942
13943            // update associated state if we're frontmost
13944            if (r == mStackSupervisor.getResumedActivityLocked()) {
13945                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13946                applyUpdateLockStateLocked(r);
13947            }
13948        }
13949    }
13950
13951    @Override
13952    public boolean isImmersive(IBinder token) {
13953        synchronized (this) {
13954            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13955            if (r == null) {
13956                throw new IllegalArgumentException();
13957            }
13958            return r.immersive;
13959        }
13960    }
13961
13962    @Override
13963    public void setVrThread(int tid) {
13964        enforceSystemHasVrFeature();
13965        synchronized (this) {
13966            synchronized (mPidsSelfLocked) {
13967                final int pid = Binder.getCallingPid();
13968                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13969                mVrController.setVrThreadLocked(tid, pid, proc);
13970            }
13971        }
13972    }
13973
13974    @Override
13975    public void setPersistentVrThread(int tid) {
13976        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13977            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13978                    + Binder.getCallingPid()
13979                    + ", uid=" + Binder.getCallingUid()
13980                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13981            Slog.w(TAG, msg);
13982            throw new SecurityException(msg);
13983        }
13984        enforceSystemHasVrFeature();
13985        synchronized (this) {
13986            synchronized (mPidsSelfLocked) {
13987                final int pid = Binder.getCallingPid();
13988                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13989                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13990            }
13991        }
13992    }
13993
13994    /**
13995     * Schedule the given thread a normal scheduling priority.
13996     *
13997     * @param tid the tid of the thread to adjust the scheduling of.
13998     * @param suppressLogs {@code true} if any error logging should be disabled.
13999     *
14000     * @return {@code true} if this succeeded.
14001     */
14002    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
14003        try {
14004            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
14005            return true;
14006        } catch (IllegalArgumentException e) {
14007            if (!suppressLogs) {
14008                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14009            }
14010        } catch (SecurityException e) {
14011            if (!suppressLogs) {
14012                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14013            }
14014        }
14015        return false;
14016    }
14017
14018    /**
14019     * Schedule the given thread an FIFO scheduling priority.
14020     *
14021     * @param tid the tid of the thread to adjust the scheduling of.
14022     * @param suppressLogs {@code true} if any error logging should be disabled.
14023     *
14024     * @return {@code true} if this succeeded.
14025     */
14026    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
14027        try {
14028            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
14029            return true;
14030        } catch (IllegalArgumentException e) {
14031            if (!suppressLogs) {
14032                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14033            }
14034        } catch (SecurityException e) {
14035            if (!suppressLogs) {
14036                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14037            }
14038        }
14039        return false;
14040    }
14041
14042    /**
14043     * Check that we have the features required for VR-related API calls, and throw an exception if
14044     * not.
14045     */
14046    private void enforceSystemHasVrFeature() {
14047        if (!mContext.getPackageManager().hasSystemFeature(
14048                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
14049            throw new UnsupportedOperationException("VR mode not supported on this device!");
14050        }
14051    }
14052
14053    @Override
14054    public void setRenderThread(int tid) {
14055        synchronized (this) {
14056            ProcessRecord proc;
14057            int pid = Binder.getCallingPid();
14058            if (pid == Process.myPid()) {
14059                demoteSystemServerRenderThread(tid);
14060                return;
14061            }
14062            synchronized (mPidsSelfLocked) {
14063                proc = mPidsSelfLocked.get(pid);
14064                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
14065                    // ensure the tid belongs to the process
14066                    if (!isThreadInProcess(pid, tid)) {
14067                        throw new IllegalArgumentException(
14068                            "Render thread does not belong to process");
14069                    }
14070                    proc.renderThreadTid = tid;
14071                    if (DEBUG_OOM_ADJ) {
14072                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
14073                    }
14074                    // promote to FIFO now
14075                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
14076                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
14077                        if (mUseFifoUiScheduling) {
14078                            setThreadScheduler(proc.renderThreadTid,
14079                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
14080                        } else {
14081                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
14082                        }
14083                    }
14084                } else {
14085                    if (DEBUG_OOM_ADJ) {
14086                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
14087                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
14088                               mUseFifoUiScheduling);
14089                    }
14090                }
14091            }
14092        }
14093    }
14094
14095    /**
14096     * We only use RenderThread in system_server to store task snapshots to the disk, which should
14097     * happen in the background. Thus, demote render thread from system_server to a lower priority.
14098     *
14099     * @param tid the tid of the RenderThread
14100     */
14101    private void demoteSystemServerRenderThread(int tid) {
14102        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
14103    }
14104
14105    @Override
14106    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
14107        enforceSystemHasVrFeature();
14108
14109        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14110
14111        ActivityRecord r;
14112        synchronized (this) {
14113            r = ActivityRecord.isInStackLocked(token);
14114        }
14115
14116        if (r == null) {
14117            throw new IllegalArgumentException();
14118        }
14119
14120        int err;
14121        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
14122                VrManagerInternal.NO_ERROR) {
14123            return err;
14124        }
14125
14126        synchronized(this) {
14127            r.requestedVrComponent = (enabled) ? packageName : null;
14128
14129            // Update associated state if this activity is currently focused
14130            if (r == mStackSupervisor.getResumedActivityLocked()) {
14131                applyUpdateVrModeLocked(r);
14132            }
14133            return 0;
14134        }
14135    }
14136
14137    @Override
14138    public boolean isVrModePackageEnabled(ComponentName packageName) {
14139        enforceSystemHasVrFeature();
14140
14141        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14142
14143        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
14144                VrManagerInternal.NO_ERROR;
14145    }
14146
14147    public boolean isTopActivityImmersive() {
14148        enforceNotIsolatedCaller("startActivity");
14149        synchronized (this) {
14150            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
14151            return (r != null) ? r.immersive : false;
14152        }
14153    }
14154
14155    /**
14156     * @return whether the system should disable UI modes incompatible with VR mode.
14157     */
14158    boolean shouldDisableNonVrUiLocked() {
14159        return mVrController.shouldDisableNonVrUiLocked();
14160    }
14161
14162    @Override
14163    public boolean isTopOfTask(IBinder token) {
14164        synchronized (this) {
14165            ActivityRecord r = ActivityRecord.isInStackLocked(token);
14166            if (r == null) {
14167                throw new IllegalArgumentException();
14168            }
14169            return r.getTask().getTopActivity() == r;
14170        }
14171    }
14172
14173    @Override
14174    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
14175        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
14176            String msg = "Permission Denial: setHasTopUi() from pid="
14177                    + Binder.getCallingPid()
14178                    + ", uid=" + Binder.getCallingUid()
14179                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
14180            Slog.w(TAG, msg);
14181            throw new SecurityException(msg);
14182        }
14183        final int pid = Binder.getCallingPid();
14184        final long origId = Binder.clearCallingIdentity();
14185        try {
14186            synchronized (this) {
14187                boolean changed = false;
14188                ProcessRecord pr;
14189                synchronized (mPidsSelfLocked) {
14190                    pr = mPidsSelfLocked.get(pid);
14191                    if (pr == null) {
14192                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
14193                        return;
14194                    }
14195                    if (pr.hasTopUi != hasTopUi) {
14196                        if (DEBUG_OOM_ADJ) {
14197                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
14198                        }
14199                        pr.hasTopUi = hasTopUi;
14200                        changed = true;
14201                    }
14202                }
14203                if (changed) {
14204                    updateOomAdjLocked(pr, true);
14205                }
14206            }
14207        } finally {
14208            Binder.restoreCallingIdentity(origId);
14209        }
14210    }
14211
14212    public final void enterSafeMode() {
14213        synchronized(this) {
14214            // It only makes sense to do this before the system is ready
14215            // and started launching other packages.
14216            if (!mSystemReady) {
14217                try {
14218                    AppGlobals.getPackageManager().enterSafeMode();
14219                } catch (RemoteException e) {
14220                }
14221            }
14222
14223            mSafeMode = true;
14224        }
14225    }
14226
14227    public final void showSafeModeOverlay() {
14228        View v = LayoutInflater.from(mContext).inflate(
14229                com.android.internal.R.layout.safe_mode, null);
14230        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
14231        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
14232        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
14233        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
14234        lp.gravity = Gravity.BOTTOM | Gravity.START;
14235        lp.format = v.getBackground().getOpacity();
14236        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
14237                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
14238        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
14239        ((WindowManager)mContext.getSystemService(
14240                Context.WINDOW_SERVICE)).addView(v, lp);
14241    }
14242
14243    @Override
14244    public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
14245            String sourcePkg, String tag) {
14246        if (workSource != null && workSource.isEmpty()) {
14247            workSource = null;
14248        }
14249
14250        if (sourceUid <= 0 && workSource == null) {
14251            // Try and derive a UID to attribute things to based on the caller.
14252            if (sender != null) {
14253                if (!(sender instanceof PendingIntentRecord)) {
14254                    return;
14255                }
14256
14257                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14258                final int callerUid = Binder.getCallingUid();
14259                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14260            } else {
14261                // TODO(narayan): Should we throw an exception in this case ? It means that we
14262                // haven't been able to derive a UID to attribute things to.
14263                return;
14264            }
14265        }
14266
14267        if (DEBUG_POWER) {
14268            Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
14269                    + ", workSource=" + workSource + ", tag=" + tag + "]");
14270        }
14271
14272        mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
14273    }
14274
14275    @Override
14276    public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14277            String tag) {
14278        if (workSource != null && workSource.isEmpty()) {
14279            workSource = null;
14280        }
14281
14282        if (sourceUid <= 0 && workSource == null) {
14283            // Try and derive a UID to attribute things to based on the caller.
14284            if (sender != null) {
14285                if (!(sender instanceof PendingIntentRecord)) {
14286                    return;
14287                }
14288
14289                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14290                final int callerUid = Binder.getCallingUid();
14291                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14292            } else {
14293                // TODO(narayan): Should we throw an exception in this case ? It means that we
14294                // haven't been able to derive a UID to attribute things to.
14295                return;
14296            }
14297        }
14298
14299        if (DEBUG_POWER) {
14300            Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14301                    ", tag=" + tag + "]");
14302        }
14303
14304        mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14305    }
14306
14307    @Override
14308    public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14309            String tag) {
14310        if (workSource != null && workSource.isEmpty()) {
14311            workSource = null;
14312        }
14313
14314        if (sourceUid <= 0 && workSource == null) {
14315            // Try and derive a UID to attribute things to based on the caller.
14316            if (sender != null) {
14317                if (!(sender instanceof PendingIntentRecord)) {
14318                    return;
14319                }
14320
14321                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14322                final int callerUid = Binder.getCallingUid();
14323                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14324            } else {
14325                // TODO(narayan): Should we throw an exception in this case ? It means that we
14326                // haven't been able to derive a UID to attribute things to.
14327                return;
14328            }
14329        }
14330
14331        if (DEBUG_POWER) {
14332            Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14333                    ", tag=" + tag + "]");
14334        }
14335
14336        mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
14337    }
14338
14339    public boolean killPids(int[] pids, String pReason, boolean secure) {
14340        if (Binder.getCallingUid() != SYSTEM_UID) {
14341            throw new SecurityException("killPids only available to the system");
14342        }
14343        String reason = (pReason == null) ? "Unknown" : pReason;
14344        // XXX Note: don't acquire main activity lock here, because the window
14345        // manager calls in with its locks held.
14346
14347        boolean killed = false;
14348        synchronized (mPidsSelfLocked) {
14349            int worstType = 0;
14350            for (int i=0; i<pids.length; i++) {
14351                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14352                if (proc != null) {
14353                    int type = proc.setAdj;
14354                    if (type > worstType) {
14355                        worstType = type;
14356                    }
14357                }
14358            }
14359
14360            // If the worst oom_adj is somewhere in the cached proc LRU range,
14361            // then constrain it so we will kill all cached procs.
14362            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14363                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14364                worstType = ProcessList.CACHED_APP_MIN_ADJ;
14365            }
14366
14367            // If this is not a secure call, don't let it kill processes that
14368            // are important.
14369            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14370                worstType = ProcessList.SERVICE_ADJ;
14371            }
14372
14373            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14374            for (int i=0; i<pids.length; i++) {
14375                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14376                if (proc == null) {
14377                    continue;
14378                }
14379                int adj = proc.setAdj;
14380                if (adj >= worstType && !proc.killedByAm) {
14381                    proc.kill(reason, true);
14382                    killed = true;
14383                }
14384            }
14385        }
14386        return killed;
14387    }
14388
14389    @Override
14390    public void killUid(int appId, int userId, String reason) {
14391        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14392        synchronized (this) {
14393            final long identity = Binder.clearCallingIdentity();
14394            try {
14395                killPackageProcessesLocked(null, appId, userId,
14396                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14397                        reason != null ? reason : "kill uid");
14398            } finally {
14399                Binder.restoreCallingIdentity(identity);
14400            }
14401        }
14402    }
14403
14404    @Override
14405    public boolean killProcessesBelowForeground(String reason) {
14406        if (Binder.getCallingUid() != SYSTEM_UID) {
14407            throw new SecurityException("killProcessesBelowForeground() only available to system");
14408        }
14409
14410        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14411    }
14412
14413    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14414        if (Binder.getCallingUid() != SYSTEM_UID) {
14415            throw new SecurityException("killProcessesBelowAdj() only available to system");
14416        }
14417
14418        boolean killed = false;
14419        synchronized (mPidsSelfLocked) {
14420            final int size = mPidsSelfLocked.size();
14421            for (int i = 0; i < size; i++) {
14422                final int pid = mPidsSelfLocked.keyAt(i);
14423                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14424                if (proc == null) continue;
14425
14426                final int adj = proc.setAdj;
14427                if (adj > belowAdj && !proc.killedByAm) {
14428                    proc.kill(reason, true);
14429                    killed = true;
14430                }
14431            }
14432        }
14433        return killed;
14434    }
14435
14436    @Override
14437    public void hang(final IBinder who, boolean allowRestart) {
14438        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14439                != PackageManager.PERMISSION_GRANTED) {
14440            throw new SecurityException("Requires permission "
14441                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14442        }
14443
14444        final IBinder.DeathRecipient death = new DeathRecipient() {
14445            @Override
14446            public void binderDied() {
14447                synchronized (this) {
14448                    notifyAll();
14449                }
14450            }
14451        };
14452
14453        try {
14454            who.linkToDeath(death, 0);
14455        } catch (RemoteException e) {
14456            Slog.w(TAG, "hang: given caller IBinder is already dead.");
14457            return;
14458        }
14459
14460        synchronized (this) {
14461            Watchdog.getInstance().setAllowRestart(allowRestart);
14462            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14463            synchronized (death) {
14464                while (who.isBinderAlive()) {
14465                    try {
14466                        death.wait();
14467                    } catch (InterruptedException e) {
14468                    }
14469                }
14470            }
14471            Watchdog.getInstance().setAllowRestart(true);
14472        }
14473    }
14474
14475    @Override
14476    public void restart() {
14477        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14478                != PackageManager.PERMISSION_GRANTED) {
14479            throw new SecurityException("Requires permission "
14480                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14481        }
14482
14483        Log.i(TAG, "Sending shutdown broadcast...");
14484
14485        BroadcastReceiver br = new BroadcastReceiver() {
14486            @Override public void onReceive(Context context, Intent intent) {
14487                // Now the broadcast is done, finish up the low-level shutdown.
14488                Log.i(TAG, "Shutting down activity manager...");
14489                shutdown(10000);
14490                Log.i(TAG, "Shutdown complete, restarting!");
14491                killProcess(myPid());
14492                System.exit(10);
14493            }
14494        };
14495
14496        // First send the high-level shut down broadcast.
14497        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14498        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14499        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
14500        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
14501        mContext.sendOrderedBroadcastAsUser(intent,
14502                UserHandle.ALL, null, br, mHandler, 0, null, null);
14503        */
14504        br.onReceive(mContext, intent);
14505    }
14506
14507    private long getLowRamTimeSinceIdle(long now) {
14508        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
14509    }
14510
14511    @Override
14512    public void performIdleMaintenance() {
14513        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14514                != PackageManager.PERMISSION_GRANTED) {
14515            throw new SecurityException("Requires permission "
14516                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14517        }
14518
14519        synchronized (this) {
14520            final long now = SystemClock.uptimeMillis();
14521            final long timeSinceLastIdle = now - mLastIdleTime;
14522            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
14523            mLastIdleTime = now;
14524            mLowRamTimeSinceLastIdle = 0;
14525            if (mLowRamStartTime != 0) {
14526                mLowRamStartTime = now;
14527            }
14528
14529            StringBuilder sb = new StringBuilder(128);
14530            sb.append("Idle maintenance over ");
14531            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14532            sb.append(" low RAM for ");
14533            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14534            Slog.i(TAG, sb.toString());
14535
14536            // If at least 1/3 of our time since the last idle period has been spent
14537            // with RAM low, then we want to kill processes.
14538            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14539
14540            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14541                ProcessRecord proc = mLruProcesses.get(i);
14542                if (proc.notCachedSinceIdle) {
14543                    if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
14544                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14545                        if (doKilling && proc.initialIdlePss != 0
14546                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14547                            sb = new StringBuilder(128);
14548                            sb.append("Kill");
14549                            sb.append(proc.processName);
14550                            sb.append(" in idle maint: pss=");
14551                            sb.append(proc.lastPss);
14552                            sb.append(", swapPss=");
14553                            sb.append(proc.lastSwapPss);
14554                            sb.append(", initialPss=");
14555                            sb.append(proc.initialIdlePss);
14556                            sb.append(", period=");
14557                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14558                            sb.append(", lowRamPeriod=");
14559                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14560                            Slog.wtfQuiet(TAG, sb.toString());
14561                            proc.kill("idle maint (pss " + proc.lastPss
14562                                    + " from " + proc.initialIdlePss + ")", true);
14563                        }
14564                    }
14565                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14566                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14567                    proc.notCachedSinceIdle = true;
14568                    proc.initialIdlePss = 0;
14569                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
14570                            mTestPssMode, isSleepingLocked(), now);
14571                }
14572            }
14573        }
14574    }
14575
14576    @Override
14577    public void sendIdleJobTrigger() {
14578        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14579                != PackageManager.PERMISSION_GRANTED) {
14580            throw new SecurityException("Requires permission "
14581                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14582        }
14583
14584        final long ident = Binder.clearCallingIdentity();
14585        try {
14586            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14587                    .setPackage("android")
14588                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14589            broadcastIntent(null, intent, null, null, 0, null, null, null,
14590                    OP_NONE, null, true, false, UserHandle.USER_ALL);
14591        } finally {
14592            Binder.restoreCallingIdentity(ident);
14593        }
14594    }
14595
14596    private void retrieveSettings() {
14597        final ContentResolver resolver = mContext.getContentResolver();
14598        final boolean freeformWindowManagement =
14599                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14600                        || Settings.Global.getInt(
14601                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14602
14603        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14604        final boolean supportsPictureInPicture = supportsMultiWindow &&
14605                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14606        final boolean supportsSplitScreenMultiWindow =
14607                ActivityManager.supportsSplitScreenMultiWindow(mContext);
14608        final boolean supportsMultiDisplay = mContext.getPackageManager()
14609                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14610        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14611        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14612        final boolean alwaysFinishActivities =
14613                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14614        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14615        final boolean forceResizable = Settings.Global.getInt(
14616                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14617        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14618                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14619        final boolean supportsLeanbackOnly =
14620                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14621        mHiddenApiBlacklist.registerObserver();
14622
14623        // Transfer any global setting for forcing RTL layout, into a System Property
14624        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14625
14626        final Configuration configuration = new Configuration();
14627        Settings.System.getConfiguration(resolver, configuration);
14628        if (forceRtl) {
14629            // This will take care of setting the correct layout direction flags
14630            configuration.setLayoutDirection(configuration.locale);
14631        }
14632
14633        synchronized (this) {
14634            mDebugApp = mOrigDebugApp = debugApp;
14635            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14636            mAlwaysFinishActivities = alwaysFinishActivities;
14637            mSupportsLeanbackOnly = supportsLeanbackOnly;
14638            mForceResizableActivities = forceResizable;
14639            final boolean multiWindowFormEnabled = freeformWindowManagement
14640                    || supportsSplitScreenMultiWindow
14641                    || supportsPictureInPicture
14642                    || supportsMultiDisplay;
14643            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14644                mSupportsMultiWindow = true;
14645                mSupportsFreeformWindowManagement = freeformWindowManagement;
14646                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14647                mSupportsPictureInPicture = supportsPictureInPicture;
14648                mSupportsMultiDisplay = supportsMultiDisplay;
14649            } else {
14650                mSupportsMultiWindow = false;
14651                mSupportsFreeformWindowManagement = false;
14652                mSupportsSplitScreenMultiWindow = false;
14653                mSupportsPictureInPicture = false;
14654                mSupportsMultiDisplay = false;
14655            }
14656            mWindowManager.setForceResizableTasks(mForceResizableActivities);
14657            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14658            // This happens before any activities are started, so we can change global configuration
14659            // in-place.
14660            updateConfigurationLocked(configuration, null, true);
14661            final Configuration globalConfig = getGlobalConfiguration();
14662            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14663
14664            // Load resources only after the current configuration has been set.
14665            final Resources res = mContext.getResources();
14666            mThumbnailWidth = res.getDimensionPixelSize(
14667                    com.android.internal.R.dimen.thumbnail_width);
14668            mThumbnailHeight = res.getDimensionPixelSize(
14669                    com.android.internal.R.dimen.thumbnail_height);
14670            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14671                    com.android.internal.R.string.config_appsNotReportingCrashes));
14672            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14673                    com.android.internal.R.bool.config_customUserSwitchUi);
14674            mUserController.mMaxRunningUsers = res.getInteger(
14675                    com.android.internal.R.integer.config_multiuserMaxRunningUsers);
14676
14677            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14678                mFullscreenThumbnailScale = (float) res
14679                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14680                    (float) globalConfig.screenWidthDp;
14681            } else {
14682                mFullscreenThumbnailScale = res.getFraction(
14683                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14684            }
14685            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14686        }
14687    }
14688
14689    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14690        traceLog.traceBegin("PhaseActivityManagerReady");
14691        synchronized(this) {
14692            if (mSystemReady) {
14693                // If we're done calling all the receivers, run the next "boot phase" passed in
14694                // by the SystemServer
14695                if (goingCallback != null) {
14696                    goingCallback.run();
14697                }
14698                return;
14699            }
14700
14701            mLocalDeviceIdleController
14702                    = LocalServices.getService(DeviceIdleController.LocalService.class);
14703            mAssistUtils = new AssistUtils(mContext);
14704            mVrController.onSystemReady();
14705            // Make sure we have the current profile info, since it is needed for security checks.
14706            mUserController.onSystemReady();
14707            mRecentTasks.onSystemReadyLocked();
14708            mAppOpsService.systemReady();
14709            mSystemReady = true;
14710        }
14711
14712        try {
14713            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14714                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14715                    .getSerial();
14716        } catch (RemoteException e) {}
14717
14718        ArrayList<ProcessRecord> procsToKill = null;
14719        synchronized(mPidsSelfLocked) {
14720            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14721                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14722                if (!isAllowedWhileBooting(proc.info)){
14723                    if (procsToKill == null) {
14724                        procsToKill = new ArrayList<ProcessRecord>();
14725                    }
14726                    procsToKill.add(proc);
14727                }
14728            }
14729        }
14730
14731        synchronized(this) {
14732            if (procsToKill != null) {
14733                for (int i=procsToKill.size()-1; i>=0; i--) {
14734                    ProcessRecord proc = procsToKill.get(i);
14735                    Slog.i(TAG, "Removing system update proc: " + proc);
14736                    removeProcessLocked(proc, true, false, "system update done");
14737                }
14738            }
14739
14740            // Now that we have cleaned up any update processes, we
14741            // are ready to start launching real processes and know that
14742            // we won't trample on them any more.
14743            mProcessesReady = true;
14744        }
14745
14746        Slog.i(TAG, "System now ready");
14747        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14748            SystemClock.uptimeMillis());
14749
14750        synchronized(this) {
14751            // Make sure we have no pre-ready processes sitting around.
14752
14753            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14754                ResolveInfo ri = mContext.getPackageManager()
14755                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14756                                STOCK_PM_FLAGS);
14757                CharSequence errorMsg = null;
14758                if (ri != null) {
14759                    ActivityInfo ai = ri.activityInfo;
14760                    ApplicationInfo app = ai.applicationInfo;
14761                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14762                        mTopAction = Intent.ACTION_FACTORY_TEST;
14763                        mTopData = null;
14764                        mTopComponent = new ComponentName(app.packageName,
14765                                ai.name);
14766                    } else {
14767                        errorMsg = mContext.getResources().getText(
14768                                com.android.internal.R.string.factorytest_not_system);
14769                    }
14770                } else {
14771                    errorMsg = mContext.getResources().getText(
14772                            com.android.internal.R.string.factorytest_no_action);
14773                }
14774                if (errorMsg != null) {
14775                    mTopAction = null;
14776                    mTopData = null;
14777                    mTopComponent = null;
14778                    Message msg = Message.obtain();
14779                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14780                    msg.getData().putCharSequence("msg", errorMsg);
14781                    mUiHandler.sendMessage(msg);
14782                }
14783            }
14784        }
14785
14786        retrieveSettings();
14787        final int currentUserId = mUserController.getCurrentUserId();
14788        synchronized (this) {
14789            readGrantedUriPermissionsLocked();
14790        }
14791
14792        final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
14793        if (pmi != null) {
14794            pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
14795                    state -> updateForceBackgroundCheck(state.batterySaverEnabled));
14796            updateForceBackgroundCheck(
14797                    pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
14798        } else {
14799            Slog.wtf(TAG, "PowerManagerInternal not found.");
14800        }
14801
14802        if (goingCallback != null) goingCallback.run();
14803        traceLog.traceBegin("ActivityManagerStartApps");
14804        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14805                Integer.toString(currentUserId), currentUserId);
14806        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14807                Integer.toString(currentUserId), currentUserId);
14808        mSystemServiceManager.startUser(currentUserId);
14809
14810        synchronized (this) {
14811            // Only start up encryption-aware persistent apps; once user is
14812            // unlocked we'll come back around and start unaware apps
14813            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14814
14815            // Start up initial activity.
14816            mBooting = true;
14817            // Enable home activity for system user, so that the system can always boot. We don't
14818            // do this when the system user is not setup since the setup wizard should be the one
14819            // to handle home activity in this case.
14820            if (UserManager.isSplitSystemUser() &&
14821                    Settings.Secure.getInt(mContext.getContentResolver(),
14822                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14823                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14824                try {
14825                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14826                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14827                            UserHandle.USER_SYSTEM);
14828                } catch (RemoteException e) {
14829                    throw e.rethrowAsRuntimeException();
14830                }
14831            }
14832            startHomeActivityLocked(currentUserId, "systemReady");
14833
14834            try {
14835                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14836                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14837                            + " data partition or your device will be unstable.");
14838                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14839                }
14840            } catch (RemoteException e) {
14841            }
14842
14843            if (!Build.isBuildConsistent()) {
14844                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14845                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14846            }
14847
14848            long ident = Binder.clearCallingIdentity();
14849            try {
14850                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14851                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14852                        | Intent.FLAG_RECEIVER_FOREGROUND);
14853                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14854                broadcastIntentLocked(null, null, intent,
14855                        null, null, 0, null, null, null, OP_NONE,
14856                        null, false, false, MY_PID, SYSTEM_UID,
14857                        currentUserId);
14858                intent = new Intent(Intent.ACTION_USER_STARTING);
14859                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14860                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14861                broadcastIntentLocked(null, null, intent,
14862                        null, new IIntentReceiver.Stub() {
14863                            @Override
14864                            public void performReceive(Intent intent, int resultCode, String data,
14865                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14866                                    throws RemoteException {
14867                            }
14868                        }, 0, null, null,
14869                        new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
14870                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14871            } catch (Throwable t) {
14872                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14873            } finally {
14874                Binder.restoreCallingIdentity(ident);
14875            }
14876            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14877            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
14878
14879            BinderInternal.nSetBinderProxyCountEnabled(true);
14880            BinderInternal.setBinderProxyCountCallback(
14881                    new BinderInternal.BinderProxyLimitListener() {
14882                        @Override
14883                        public void onLimitReached(int uid) {
14884                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
14885                                    + Process.myUid());
14886                            if (uid == Process.SYSTEM_UID) {
14887                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
14888                            } else {
14889                                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
14890                                        "Too many Binders sent to SYSTEM");
14891                            }
14892                        }
14893                    }, mHandler);
14894
14895            traceLog.traceEnd(); // ActivityManagerStartApps
14896            traceLog.traceEnd(); // PhaseActivityManagerReady
14897        }
14898    }
14899
14900    private void updateForceBackgroundCheck(boolean enabled) {
14901        synchronized (this) {
14902            if (mForceBackgroundCheck != enabled) {
14903                mForceBackgroundCheck = enabled;
14904
14905                if (DEBUG_BACKGROUND_CHECK) {
14906                    Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
14907                }
14908
14909                if (mForceBackgroundCheck) {
14910                    // Stop background services for idle UIDs.
14911                    doStopUidForIdleUidsLocked();
14912                }
14913            }
14914        }
14915    }
14916
14917    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14918        synchronized (this) {
14919            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14920        }
14921    }
14922
14923    void skipCurrentReceiverLocked(ProcessRecord app) {
14924        for (BroadcastQueue queue : mBroadcastQueues) {
14925            queue.skipCurrentReceiverLocked(app);
14926        }
14927    }
14928
14929    /**
14930     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14931     * The application process will exit immediately after this call returns.
14932     * @param app object of the crashing app, null for the system server
14933     * @param crashInfo describing the exception
14934     */
14935    public void handleApplicationCrash(IBinder app,
14936            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14937        ProcessRecord r = findAppProcess(app, "Crash");
14938        final String processName = app == null ? "system_server"
14939                : (r == null ? "unknown" : r.processName);
14940
14941        handleApplicationCrashInner("crash", r, processName, crashInfo);
14942    }
14943
14944    /* Native crash reporting uses this inner version because it needs to be somewhat
14945     * decoupled from the AM-managed cleanup lifecycle
14946     */
14947    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14948            ApplicationErrorReport.CrashInfo crashInfo) {
14949        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14950                UserHandle.getUserId(Binder.getCallingUid()), processName,
14951                r == null ? -1 : r.info.flags,
14952                crashInfo.exceptionClassName,
14953                crashInfo.exceptionMessage,
14954                crashInfo.throwFileName,
14955                crashInfo.throwLineNumber);
14956
14957        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14958
14959        mAppErrors.crashApplication(r, crashInfo);
14960    }
14961
14962    public void handleApplicationStrictModeViolation(
14963            IBinder app,
14964            int violationMask,
14965            StrictMode.ViolationInfo info) {
14966        // We're okay if the ProcessRecord is missing; it probably means that
14967        // we're reporting a violation from the system process itself.
14968        final ProcessRecord r = findAppProcess(app, "StrictMode");
14969
14970        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14971            Integer stackFingerprint = info.hashCode();
14972            boolean logIt = true;
14973            synchronized (mAlreadyLoggedViolatedStacks) {
14974                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14975                    logIt = false;
14976                    // TODO: sub-sample into EventLog for these, with
14977                    // the info.durationMillis?  Then we'd get
14978                    // the relative pain numbers, without logging all
14979                    // the stack traces repeatedly.  We'd want to do
14980                    // likewise in the client code, which also does
14981                    // dup suppression, before the Binder call.
14982                } else {
14983                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14984                        mAlreadyLoggedViolatedStacks.clear();
14985                    }
14986                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14987                }
14988            }
14989            if (logIt) {
14990                logStrictModeViolationToDropBox(r, info);
14991            }
14992        }
14993
14994        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14995            AppErrorResult result = new AppErrorResult();
14996            synchronized (this) {
14997                final long origId = Binder.clearCallingIdentity();
14998
14999                Message msg = Message.obtain();
15000                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
15001                HashMap<String, Object> data = new HashMap<String, Object>();
15002                data.put("result", result);
15003                data.put("app", r);
15004                data.put("violationMask", violationMask);
15005                data.put("info", info);
15006                msg.obj = data;
15007                mUiHandler.sendMessage(msg);
15008
15009                Binder.restoreCallingIdentity(origId);
15010            }
15011            int res = result.get();
15012            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
15013        }
15014    }
15015
15016    // Depending on the policy in effect, there could be a bunch of
15017    // these in quick succession so we try to batch these together to
15018    // minimize disk writes, number of dropbox entries, and maximize
15019    // compression, by having more fewer, larger records.
15020    private void logStrictModeViolationToDropBox(
15021            ProcessRecord process,
15022            StrictMode.ViolationInfo info) {
15023        if (info == null) {
15024            return;
15025        }
15026        final boolean isSystemApp = process == null ||
15027                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
15028                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
15029        final String processName = process == null ? "unknown" : process.processName;
15030        final DropBoxManager dbox = (DropBoxManager)
15031                mContext.getSystemService(Context.DROPBOX_SERVICE);
15032
15033        // Exit early if the dropbox isn't configured to accept this report type.
15034        final String dropboxTag = processClass(process) + "_strictmode";
15035        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15036
15037        final StringBuilder sb = new StringBuilder(1024);
15038        synchronized (sb) {
15039            appendDropBoxProcessHeaders(process, processName, sb);
15040            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15041            sb.append("System-App: ").append(isSystemApp).append("\n");
15042            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
15043            if (info.violationNumThisLoop != 0) {
15044                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
15045            }
15046            if (info.numAnimationsRunning != 0) {
15047                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
15048            }
15049            if (info.broadcastIntentAction != null) {
15050                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
15051            }
15052            if (info.durationMillis != -1) {
15053                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
15054            }
15055            if (info.numInstances != -1) {
15056                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
15057            }
15058            if (info.tags != null) {
15059                for (String tag : info.tags) {
15060                    sb.append("Span-Tag: ").append(tag).append("\n");
15061                }
15062            }
15063            sb.append("\n");
15064            sb.append(info.getStackTrace());
15065            sb.append("\n");
15066            if (info.getViolationDetails() != null) {
15067                sb.append(info.getViolationDetails());
15068                sb.append("\n");
15069            }
15070        }
15071
15072        final String res = sb.toString();
15073        IoThread.getHandler().post(() -> {
15074            dbox.addText(dropboxTag, res);
15075        });
15076    }
15077
15078    /**
15079     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
15080     * @param app object of the crashing app, null for the system server
15081     * @param tag reported by the caller
15082     * @param system whether this wtf is coming from the system
15083     * @param crashInfo describing the context of the error
15084     * @return true if the process should exit immediately (WTF is fatal)
15085     */
15086    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
15087            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15088        final int callingUid = Binder.getCallingUid();
15089        final int callingPid = Binder.getCallingPid();
15090
15091        if (system) {
15092            // If this is coming from the system, we could very well have low-level
15093            // system locks held, so we want to do this all asynchronously.  And we
15094            // never want this to become fatal, so there is that too.
15095            mHandler.post(new Runnable() {
15096                @Override public void run() {
15097                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
15098                }
15099            });
15100            return false;
15101        }
15102
15103        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
15104                crashInfo);
15105
15106        final boolean isFatal = Build.IS_ENG || Settings.Global
15107                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
15108        final boolean isSystem = (r == null) || r.persistent;
15109
15110        if (isFatal && !isSystem) {
15111            mAppErrors.crashApplication(r, crashInfo);
15112            return true;
15113        } else {
15114            return false;
15115        }
15116    }
15117
15118    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
15119            final ApplicationErrorReport.CrashInfo crashInfo) {
15120        final ProcessRecord r = findAppProcess(app, "WTF");
15121        final String processName = app == null ? "system_server"
15122                : (r == null ? "unknown" : r.processName);
15123
15124        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
15125                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
15126
15127        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
15128
15129        return r;
15130    }
15131
15132    /**
15133     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
15134     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
15135     */
15136    private ProcessRecord findAppProcess(IBinder app, String reason) {
15137        if (app == null) {
15138            return null;
15139        }
15140
15141        synchronized (this) {
15142            final int NP = mProcessNames.getMap().size();
15143            for (int ip=0; ip<NP; ip++) {
15144                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
15145                final int NA = apps.size();
15146                for (int ia=0; ia<NA; ia++) {
15147                    ProcessRecord p = apps.valueAt(ia);
15148                    if (p.thread != null && p.thread.asBinder() == app) {
15149                        return p;
15150                    }
15151                }
15152            }
15153
15154            Slog.w(TAG, "Can't find mystery application for " + reason
15155                    + " from pid=" + Binder.getCallingPid()
15156                    + " uid=" + Binder.getCallingUid() + ": " + app);
15157            return null;
15158        }
15159    }
15160
15161    /**
15162     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
15163     * to append various headers to the dropbox log text.
15164     */
15165    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
15166            StringBuilder sb) {
15167        // Watchdog thread ends up invoking this function (with
15168        // a null ProcessRecord) to add the stack file to dropbox.
15169        // Do not acquire a lock on this (am) in such cases, as it
15170        // could cause a potential deadlock, if and when watchdog
15171        // is invoked due to unavailability of lock on am and it
15172        // would prevent watchdog from killing system_server.
15173        if (process == null) {
15174            sb.append("Process: ").append(processName).append("\n");
15175            return;
15176        }
15177        // Note: ProcessRecord 'process' is guarded by the service
15178        // instance.  (notably process.pkgList, which could otherwise change
15179        // concurrently during execution of this method)
15180        synchronized (this) {
15181            sb.append("Process: ").append(processName).append("\n");
15182            sb.append("PID: ").append(process.pid).append("\n");
15183            int flags = process.info.flags;
15184            IPackageManager pm = AppGlobals.getPackageManager();
15185            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
15186            for (int ip=0; ip<process.pkgList.size(); ip++) {
15187                String pkg = process.pkgList.keyAt(ip);
15188                sb.append("Package: ").append(pkg);
15189                try {
15190                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
15191                    if (pi != null) {
15192                        sb.append(" v").append(pi.getLongVersionCode());
15193                        if (pi.versionName != null) {
15194                            sb.append(" (").append(pi.versionName).append(")");
15195                        }
15196                    }
15197                } catch (RemoteException e) {
15198                    Slog.e(TAG, "Error getting package info: " + pkg, e);
15199                }
15200                sb.append("\n");
15201            }
15202            if (process.info.isInstantApp()) {
15203                sb.append("Instant-App: true\n");
15204            }
15205        }
15206    }
15207
15208    private static String processClass(ProcessRecord process) {
15209        if (process == null || process.pid == MY_PID) {
15210            return "system_server";
15211        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15212            return "system_app";
15213        } else {
15214            return "data_app";
15215        }
15216    }
15217
15218    private volatile long mWtfClusterStart;
15219    private volatile int mWtfClusterCount;
15220
15221    /**
15222     * Write a description of an error (crash, WTF, ANR) to the drop box.
15223     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
15224     * @param process which caused the error, null means the system server
15225     * @param activity which triggered the error, null if unknown
15226     * @param parent activity related to the error, null if unknown
15227     * @param subject line related to the error, null if absent
15228     * @param report in long form describing the error, null if absent
15229     * @param dataFile text file to include in the report, null if none
15230     * @param crashInfo giving an application stack trace, null if absent
15231     */
15232    public void addErrorToDropBox(String eventType,
15233            ProcessRecord process, String processName, ActivityRecord activity,
15234            ActivityRecord parent, String subject,
15235            final String report, final File dataFile,
15236            final ApplicationErrorReport.CrashInfo crashInfo) {
15237        // NOTE -- this must never acquire the ActivityManagerService lock,
15238        // otherwise the watchdog may be prevented from resetting the system.
15239
15240        // Bail early if not published yet
15241        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
15242        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
15243
15244        // Exit early if the dropbox isn't configured to accept this report type.
15245        final String dropboxTag = processClass(process) + "_" + eventType;
15246        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15247
15248        // Log to StatsLog before the rate-limiting.
15249        // The logging below is adapated from appendDropboxProcessHeaders.
15250        StatsLog.write(StatsLog.DROPBOX_ERROR_CHANGED,
15251                process != null ? process.uid : -1,
15252                dropboxTag,
15253                processName,
15254                process != null ? process.pid : -1,
15255                (process != null && process.info != null) ?
15256                        (process.info.isInstantApp() ? 1 : 0) : -1,
15257                activity != null ? activity.shortComponentName : null,
15258                activity != null ? activity.packageName : null,
15259                process != null ? (process.isInterestingToUserLocked() ? 1 : 0) : -1);
15260
15261        // Rate-limit how often we're willing to do the heavy lifting below to
15262        // collect and record logs; currently 5 logs per 10 second period.
15263        final long now = SystemClock.elapsedRealtime();
15264        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
15265            mWtfClusterStart = now;
15266            mWtfClusterCount = 1;
15267        } else {
15268            if (mWtfClusterCount++ >= 5) return;
15269        }
15270
15271        final StringBuilder sb = new StringBuilder(1024);
15272        appendDropBoxProcessHeaders(process, processName, sb);
15273        if (process != null) {
15274            sb.append("Foreground: ")
15275                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
15276                    .append("\n");
15277        }
15278        if (activity != null) {
15279            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15280        }
15281        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15282            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15283        }
15284        if (parent != null && parent != activity) {
15285            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15286        }
15287        if (subject != null) {
15288            sb.append("Subject: ").append(subject).append("\n");
15289        }
15290        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15291        if (Debug.isDebuggerConnected()) {
15292            sb.append("Debugger: Connected\n");
15293        }
15294        sb.append("\n");
15295
15296        // Do the rest in a worker thread to avoid blocking the caller on I/O
15297        // (After this point, we shouldn't access AMS internal data structures.)
15298        Thread worker = new Thread("Error dump: " + dropboxTag) {
15299            @Override
15300            public void run() {
15301                if (report != null) {
15302                    sb.append(report);
15303                }
15304
15305                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
15306                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
15307                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
15308                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
15309
15310                if (dataFile != null && maxDataFileSize > 0) {
15311                    try {
15312                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15313                                    "\n\n[[TRUNCATED]]"));
15314                    } catch (IOException e) {
15315                        Slog.e(TAG, "Error reading " + dataFile, e);
15316                    }
15317                }
15318                if (crashInfo != null && crashInfo.stackTrace != null) {
15319                    sb.append(crashInfo.stackTrace);
15320                }
15321
15322                if (lines > 0) {
15323                    sb.append("\n");
15324
15325                    // Merge several logcat streams, and take the last N lines
15326                    InputStreamReader input = null;
15327                    try {
15328                        java.lang.Process logcat = new ProcessBuilder(
15329                                "/system/bin/timeout", "-k", "15s", "10s",
15330                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
15331                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
15332                                        .redirectErrorStream(true).start();
15333
15334                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
15335                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
15336                        input = new InputStreamReader(logcat.getInputStream());
15337
15338                        int num;
15339                        char[] buf = new char[8192];
15340                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
15341                    } catch (IOException e) {
15342                        Slog.e(TAG, "Error running logcat", e);
15343                    } finally {
15344                        if (input != null) try { input.close(); } catch (IOException e) {}
15345                    }
15346                }
15347
15348                dbox.addText(dropboxTag, sb.toString());
15349            }
15350        };
15351
15352        if (process == null) {
15353            // If process is null, we are being called from some internal code
15354            // and may be about to die -- run this synchronously.
15355            final int oldMask = StrictMode.allowThreadDiskWritesMask();
15356            try {
15357                worker.run();
15358            } finally {
15359                StrictMode.setThreadPolicyMask(oldMask);
15360            }
15361        } else {
15362            worker.start();
15363        }
15364    }
15365
15366    @Override
15367    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15368        enforceNotIsolatedCaller("getProcessesInErrorState");
15369        // assume our apps are happy - lazy create the list
15370        List<ActivityManager.ProcessErrorStateInfo> errList = null;
15371
15372        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15373                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15374        int userId = UserHandle.getUserId(Binder.getCallingUid());
15375
15376        synchronized (this) {
15377
15378            // iterate across all processes
15379            for (int i=mLruProcesses.size()-1; i>=0; i--) {
15380                ProcessRecord app = mLruProcesses.get(i);
15381                if (!allUsers && app.userId != userId) {
15382                    continue;
15383                }
15384                if ((app.thread != null) && (app.crashing || app.notResponding)) {
15385                    // This one's in trouble, so we'll generate a report for it
15386                    // crashes are higher priority (in case there's a crash *and* an anr)
15387                    ActivityManager.ProcessErrorStateInfo report = null;
15388                    if (app.crashing) {
15389                        report = app.crashingReport;
15390                    } else if (app.notResponding) {
15391                        report = app.notRespondingReport;
15392                    }
15393
15394                    if (report != null) {
15395                        if (errList == null) {
15396                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15397                        }
15398                        errList.add(report);
15399                    } else {
15400                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
15401                                " crashing = " + app.crashing +
15402                                " notResponding = " + app.notResponding);
15403                    }
15404                }
15405            }
15406        }
15407
15408        return errList;
15409    }
15410
15411    static int procStateToImportance(int procState, int memAdj,
15412            ActivityManager.RunningAppProcessInfo currApp,
15413            int clientTargetSdk) {
15414        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15415                procState, clientTargetSdk);
15416        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15417            currApp.lru = memAdj;
15418        } else {
15419            currApp.lru = 0;
15420        }
15421        return imp;
15422    }
15423
15424    private void fillInProcMemInfo(ProcessRecord app,
15425            ActivityManager.RunningAppProcessInfo outInfo,
15426            int clientTargetSdk) {
15427        outInfo.pid = app.pid;
15428        outInfo.uid = app.info.uid;
15429        if (mHeavyWeightProcess == app) {
15430            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15431        }
15432        if (app.persistent) {
15433            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15434        }
15435        if (app.activities.size() > 0) {
15436            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15437        }
15438        outInfo.lastTrimLevel = app.trimMemoryLevel;
15439        int adj = app.curAdj;
15440        int procState = app.curProcState;
15441        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15442        outInfo.importanceReasonCode = app.adjTypeCode;
15443        outInfo.processState = app.curProcState;
15444    }
15445
15446    @Override
15447    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15448        enforceNotIsolatedCaller("getRunningAppProcesses");
15449
15450        final int callingUid = Binder.getCallingUid();
15451        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15452
15453        // Lazy instantiation of list
15454        List<ActivityManager.RunningAppProcessInfo> runList = null;
15455        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15456                callingUid) == PackageManager.PERMISSION_GRANTED;
15457        final int userId = UserHandle.getUserId(callingUid);
15458        final boolean allUids = isGetTasksAllowed(
15459                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
15460
15461        synchronized (this) {
15462            // Iterate across all processes
15463            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15464                ProcessRecord app = mLruProcesses.get(i);
15465                if ((!allUsers && app.userId != userId)
15466                        || (!allUids && app.uid != callingUid)) {
15467                    continue;
15468                }
15469                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15470                    // Generate process state info for running application
15471                    ActivityManager.RunningAppProcessInfo currApp =
15472                        new ActivityManager.RunningAppProcessInfo(app.processName,
15473                                app.pid, app.getPackageList());
15474                    fillInProcMemInfo(app, currApp, clientTargetSdk);
15475                    if (app.adjSource instanceof ProcessRecord) {
15476                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15477                        currApp.importanceReasonImportance =
15478                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
15479                                        app.adjSourceProcState);
15480                    } else if (app.adjSource instanceof ActivityRecord) {
15481                        ActivityRecord r = (ActivityRecord)app.adjSource;
15482                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15483                    }
15484                    if (app.adjTarget instanceof ComponentName) {
15485                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15486                    }
15487                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15488                    //        + " lru=" + currApp.lru);
15489                    if (runList == null) {
15490                        runList = new ArrayList<>();
15491                    }
15492                    runList.add(currApp);
15493                }
15494            }
15495        }
15496        return runList;
15497    }
15498
15499    @Override
15500    public List<ApplicationInfo> getRunningExternalApplications() {
15501        enforceNotIsolatedCaller("getRunningExternalApplications");
15502        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
15503        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
15504        if (runningApps != null && runningApps.size() > 0) {
15505            Set<String> extList = new HashSet<String>();
15506            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
15507                if (app.pkgList != null) {
15508                    for (String pkg : app.pkgList) {
15509                        extList.add(pkg);
15510                    }
15511                }
15512            }
15513            IPackageManager pm = AppGlobals.getPackageManager();
15514            for (String pkg : extList) {
15515                try {
15516                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
15517                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
15518                        retList.add(info);
15519                    }
15520                } catch (RemoteException e) {
15521                }
15522            }
15523        }
15524        return retList;
15525    }
15526
15527    @Override
15528    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15529        enforceNotIsolatedCaller("getMyMemoryState");
15530
15531        final int callingUid = Binder.getCallingUid();
15532        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15533
15534        synchronized (this) {
15535            ProcessRecord proc;
15536            synchronized (mPidsSelfLocked) {
15537                proc = mPidsSelfLocked.get(Binder.getCallingPid());
15538            }
15539            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15540        }
15541    }
15542
15543    @Override
15544    public int getMemoryTrimLevel() {
15545        enforceNotIsolatedCaller("getMyMemoryState");
15546        synchronized (this) {
15547            return mLastMemoryLevel;
15548        }
15549    }
15550
15551    @Override
15552    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15553            FileDescriptor err, String[] args, ShellCallback callback,
15554            ResultReceiver resultReceiver) {
15555        (new ActivityManagerShellCommand(this, false)).exec(
15556                this, in, out, err, args, callback, resultReceiver);
15557    }
15558
15559    SleepToken acquireSleepToken(String tag, int displayId) {
15560        synchronized (this) {
15561            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15562            updateSleepIfNeededLocked();
15563            return token;
15564        }
15565    }
15566
15567    @Override
15568    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15569        PriorityDump.dump(mPriorityDumper, fd, pw, args);
15570    }
15571
15572    /**
15573     * Wrapper function to print out debug data filtered by specified arguments.
15574    */
15575    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
15576        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15577
15578        boolean dumpAll = false;
15579        boolean dumpClient = false;
15580        boolean dumpCheckin = false;
15581        boolean dumpCheckinFormat = false;
15582        boolean dumpNormalPriority = false;
15583        boolean dumpVisibleStacksOnly = false;
15584        boolean dumpFocusedStackOnly = false;
15585        String dumpPackage = null;
15586
15587        int opti = 0;
15588        while (opti < args.length) {
15589            String opt = args[opti];
15590            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15591                break;
15592            }
15593            opti++;
15594            if ("-a".equals(opt)) {
15595                dumpAll = true;
15596            } else if ("-c".equals(opt)) {
15597                dumpClient = true;
15598            } else if ("-v".equals(opt)) {
15599                dumpVisibleStacksOnly = true;
15600            } else if ("-f".equals(opt)) {
15601                dumpFocusedStackOnly = true;
15602            } else if ("-p".equals(opt)) {
15603                if (opti < args.length) {
15604                    dumpPackage = args[opti];
15605                    opti++;
15606                } else {
15607                    pw.println("Error: -p option requires package argument");
15608                    return;
15609                }
15610                dumpClient = true;
15611            } else if ("--checkin".equals(opt)) {
15612                dumpCheckin = dumpCheckinFormat = true;
15613            } else if ("-C".equals(opt)) {
15614                dumpCheckinFormat = true;
15615            } else if ("--normal-priority".equals(opt)) {
15616                dumpNormalPriority = true;
15617            } else if ("-h".equals(opt)) {
15618                ActivityManagerShellCommand.dumpHelp(pw, true);
15619                return;
15620            } else {
15621                pw.println("Unknown argument: " + opt + "; use -h for help");
15622            }
15623        }
15624
15625        long origId = Binder.clearCallingIdentity();
15626
15627        if (useProto) {
15628            final ProtoOutputStream proto = new ProtoOutputStream(fd);
15629            String cmd = opti < args.length ? args[opti] : "";
15630            opti++;
15631
15632            if ("activities".equals(cmd) || "a".equals(cmd)) {
15633                // output proto is ActivityStackSupervisorProto
15634                synchronized (this) {
15635                    writeActivitiesToProtoLocked(proto);
15636                }
15637            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15638                // output proto is BroadcastProto
15639                synchronized (this) {
15640                    writeBroadcastsToProtoLocked(proto);
15641                }
15642            } else if ("provider".equals(cmd)) {
15643                String[] newArgs;
15644                String name;
15645                if (opti >= args.length) {
15646                    name = null;
15647                    newArgs = EMPTY_STRING_ARRAY;
15648                } else {
15649                    name = args[opti];
15650                    opti++;
15651                    newArgs = new String[args.length - opti];
15652                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15653                            args.length - opti);
15654                }
15655                if (!dumpProviderProto(fd, pw, name, newArgs)) {
15656                    pw.println("No providers match: " + name);
15657                    pw.println("Use -h for help.");
15658                }
15659            } else if ("service".equals(cmd)) {
15660                mServices.writeToProto(proto);
15661            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15662                if (opti < args.length) {
15663                    dumpPackage = args[opti];
15664                    opti++;
15665                }
15666                // output proto is ProcessProto
15667                synchronized (this) {
15668                    writeProcessesToProtoLocked(proto, dumpPackage);
15669                }
15670            } else {
15671                // default option, dump everything, output is ActivityManagerServiceProto
15672                synchronized (this) {
15673                    long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
15674                    writeActivitiesToProtoLocked(proto);
15675                    proto.end(activityToken);
15676
15677                    long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
15678                    writeBroadcastsToProtoLocked(proto);
15679                    proto.end(broadcastToken);
15680
15681                    long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
15682                    mServices.writeToProto(proto);
15683                    proto.end(serviceToken);
15684
15685                    long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
15686                    writeProcessesToProtoLocked(proto, dumpPackage);
15687                    proto.end(processToken);
15688                }
15689            }
15690            proto.flush();
15691            Binder.restoreCallingIdentity(origId);
15692            return;
15693        }
15694
15695        int dumpAppId = getAppId(dumpPackage);
15696        boolean more = false;
15697        // Is the caller requesting to dump a particular piece of data?
15698        if (opti < args.length) {
15699            String cmd = args[opti];
15700            opti++;
15701            if ("activities".equals(cmd) || "a".equals(cmd)) {
15702                synchronized (this) {
15703                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15704                }
15705            } else if ("lastanr".equals(cmd)) {
15706                synchronized (this) {
15707                    dumpLastANRLocked(pw);
15708                }
15709            } else if ("starter".equals(cmd)) {
15710                synchronized (this) {
15711                    dumpActivityStarterLocked(pw, dumpPackage);
15712                }
15713            } else if ("containers".equals(cmd)) {
15714                synchronized (this) {
15715                    dumpActivityContainersLocked(pw);
15716                }
15717            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15718                synchronized (this) {
15719                    if (mRecentTasks != null) {
15720                        mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
15721                    }
15722                }
15723            } else if ("binder-proxies".equals(cmd)) {
15724                if (opti >= args.length) {
15725                    dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
15726                            "Counts of Binder Proxies held by SYSTEM");
15727                } else {
15728                    String uid = args[opti];
15729                    opti++;
15730                    // Ensure Binder Proxy Count is as up to date as possible
15731                    System.gc();
15732                    System.runFinalization();
15733                    System.gc();
15734                    pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
15735                }
15736            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15737                if (opti < args.length) {
15738                    dumpPackage = args[opti];
15739                    opti++;
15740                }
15741                synchronized (this) {
15742                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15743                }
15744            } else if ("broadcast-stats".equals(cmd)) {
15745                if (opti < args.length) {
15746                    dumpPackage = args[opti];
15747                    opti++;
15748                }
15749                synchronized (this) {
15750                    if (dumpCheckinFormat) {
15751                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15752                                dumpPackage);
15753                    } else {
15754                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15755                    }
15756                }
15757            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15758                if (opti < args.length) {
15759                    dumpPackage = args[opti];
15760                    opti++;
15761                }
15762                synchronized (this) {
15763                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15764                }
15765            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15766                if (opti < args.length) {
15767                    dumpPackage = args[opti];
15768                    opti++;
15769                }
15770                synchronized (this) {
15771                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
15772                }
15773            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15774                synchronized (this) {
15775                    dumpOomLocked(fd, pw, args, opti, true);
15776                }
15777            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15778                synchronized (this) {
15779                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15780                }
15781            } else if ("provider".equals(cmd)) {
15782                String[] newArgs;
15783                String name;
15784                if (opti >= args.length) {
15785                    name = null;
15786                    newArgs = EMPTY_STRING_ARRAY;
15787                } else {
15788                    name = args[opti];
15789                    opti++;
15790                    newArgs = new String[args.length - opti];
15791                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15792                }
15793                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15794                    pw.println("No providers match: " + name);
15795                    pw.println("Use -h for help.");
15796                }
15797            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15798                synchronized (this) {
15799                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15800                }
15801            } else if ("service".equals(cmd)) {
15802                String[] newArgs;
15803                String name;
15804                if (opti >= args.length) {
15805                    name = null;
15806                    newArgs = EMPTY_STRING_ARRAY;
15807                } else {
15808                    name = args[opti];
15809                    opti++;
15810                    newArgs = new String[args.length - opti];
15811                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15812                            args.length - opti);
15813                }
15814                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15815                    pw.println("No services match: " + name);
15816                    pw.println("Use -h for help.");
15817                }
15818            } else if ("package".equals(cmd)) {
15819                String[] newArgs;
15820                if (opti >= args.length) {
15821                    pw.println("package: no package name specified");
15822                    pw.println("Use -h for help.");
15823                } else {
15824                    dumpPackage = args[opti];
15825                    opti++;
15826                    newArgs = new String[args.length - opti];
15827                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15828                            args.length - opti);
15829                    args = newArgs;
15830                    opti = 0;
15831                    more = true;
15832                }
15833            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15834                synchronized (this) {
15835                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15836                }
15837            } else if ("settings".equals(cmd)) {
15838                synchronized (this) {
15839                    mConstants.dump(pw);
15840                }
15841            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15842                if (dumpClient) {
15843                    ActiveServices.ServiceDumper dumper;
15844                    synchronized (this) {
15845                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15846                                dumpPackage);
15847                    }
15848                    dumper.dumpWithClient();
15849                } else {
15850                    synchronized (this) {
15851                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15852                                dumpPackage).dumpLocked();
15853                    }
15854                }
15855            } else if ("locks".equals(cmd)) {
15856                LockGuard.dump(fd, pw, args);
15857            } else {
15858                // Dumping a single activity?
15859                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15860                        dumpFocusedStackOnly)) {
15861                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15862                    int res = shell.exec(this, null, fd, null, args, null,
15863                            new ResultReceiver(null));
15864                    if (res < 0) {
15865                        pw.println("Bad activity command, or no activities match: " + cmd);
15866                        pw.println("Use -h for help.");
15867                    }
15868                }
15869            }
15870            if (!more) {
15871                Binder.restoreCallingIdentity(origId);
15872                return;
15873            }
15874        }
15875
15876        // No piece of data specified, dump everything.
15877        if (dumpCheckinFormat) {
15878            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15879        } else if (dumpClient) {
15880            ActiveServices.ServiceDumper sdumper;
15881            synchronized (this) {
15882                mConstants.dump(pw);
15883                pw.println();
15884                if (dumpAll) {
15885                    pw.println("-------------------------------------------------------------------------------");
15886                }
15887                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15888                pw.println();
15889                if (dumpAll) {
15890                    pw.println("-------------------------------------------------------------------------------");
15891                }
15892                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15893                pw.println();
15894                if (dumpAll) {
15895                    pw.println("-------------------------------------------------------------------------------");
15896                }
15897                if (dumpAll || dumpPackage != null) {
15898                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15899                    pw.println();
15900                    if (dumpAll) {
15901                        pw.println("-------------------------------------------------------------------------------");
15902                    }
15903                }
15904                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15905                pw.println();
15906                if (dumpAll) {
15907                    pw.println("-------------------------------------------------------------------------------");
15908                }
15909                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15910                pw.println();
15911                if (dumpAll) {
15912                    pw.println("-------------------------------------------------------------------------------");
15913                }
15914                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15915                        dumpPackage);
15916            }
15917            sdumper.dumpWithClient();
15918            pw.println();
15919            synchronized (this) {
15920                if (dumpAll) {
15921                    pw.println("-------------------------------------------------------------------------------");
15922                }
15923                if (mRecentTasks != null) {
15924                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
15925                }
15926                pw.println();
15927                if (dumpAll) {
15928                    pw.println("-------------------------------------------------------------------------------");
15929                }
15930                dumpLastANRLocked(pw);
15931                pw.println();
15932                if (dumpAll) {
15933                    pw.println("-------------------------------------------------------------------------------");
15934                }
15935                dumpActivityStarterLocked(pw, dumpPackage);
15936                pw.println();
15937                if (dumpAll) {
15938                    pw.println("-------------------------------------------------------------------------------");
15939                }
15940                dumpActivityContainersLocked(pw);
15941                pw.println();
15942                if (dumpAll) {
15943                    pw.println("-------------------------------------------------------------------------------");
15944                }
15945                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15946                if (mAssociations.size() > 0) {
15947                    pw.println();
15948                    if (dumpAll) {
15949                        pw.println("-------------------------------------------------------------------------------");
15950                    }
15951                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15952                }
15953                pw.println();
15954                if (dumpAll) {
15955                    pw.println("-------------------------------------------------------------------------------");
15956                }
15957                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
15958            }
15959
15960        } else {
15961            synchronized (this) {
15962                mConstants.dump(pw);
15963                pw.println();
15964                if (dumpAll) {
15965                    pw.println("-------------------------------------------------------------------------------");
15966                }
15967                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15968                pw.println();
15969                if (dumpAll) {
15970                    pw.println("-------------------------------------------------------------------------------");
15971                }
15972                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15973                pw.println();
15974                if (dumpAll) {
15975                    pw.println("-------------------------------------------------------------------------------");
15976                }
15977                if (dumpAll || dumpPackage != null) {
15978                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15979                    pw.println();
15980                    if (dumpAll) {
15981                        pw.println("-------------------------------------------------------------------------------");
15982                    }
15983                }
15984                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15985                pw.println();
15986                if (dumpAll) {
15987                    pw.println("-------------------------------------------------------------------------------");
15988                }
15989                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15990                pw.println();
15991                if (dumpAll) {
15992                    pw.println("-------------------------------------------------------------------------------");
15993                }
15994                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15995                        .dumpLocked();
15996                pw.println();
15997                if (dumpAll) {
15998                    pw.println("-------------------------------------------------------------------------------");
15999                }
16000                if (mRecentTasks != null) {
16001                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
16002                }
16003                pw.println();
16004                if (dumpAll) {
16005                    pw.println("-------------------------------------------------------------------------------");
16006                }
16007                dumpLastANRLocked(pw);
16008                pw.println();
16009                if (dumpAll) {
16010                    pw.println("-------------------------------------------------------------------------------");
16011                }
16012                dumpActivityStarterLocked(pw, dumpPackage);
16013                pw.println();
16014                if (dumpAll) {
16015                    pw.println("-------------------------------------------------------------------------------");
16016                }
16017                dumpActivityContainersLocked(pw);
16018                // Activities section is dumped as part of the Critical priority dump. Exclude the
16019                // section if priority is Normal.
16020                if (!dumpNormalPriority){
16021                    pw.println();
16022                    if (dumpAll) {
16023                        pw.println("-------------------------------------------------------------------------------");
16024                    }
16025                    dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16026                }
16027                if (mAssociations.size() > 0) {
16028                    pw.println();
16029                    if (dumpAll) {
16030                        pw.println("-------------------------------------------------------------------------------");
16031                    }
16032                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16033                }
16034                pw.println();
16035                if (dumpAll) {
16036                    pw.println("-------------------------------------------------------------------------------");
16037                }
16038                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16039            }
16040        }
16041        Binder.restoreCallingIdentity(origId);
16042    }
16043
16044    private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
16045        // The output proto of "activity --proto activities" is ActivityStackSupervisorProto
16046        mStackSupervisor.writeToProto(proto);
16047    }
16048
16049    private void dumpLastANRLocked(PrintWriter pw) {
16050        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
16051        if (mLastANRState == null) {
16052            pw.println("  <no ANR has occurred since boot>");
16053        } else {
16054            pw.println(mLastANRState);
16055        }
16056    }
16057
16058    private void dumpActivityContainersLocked(PrintWriter pw) {
16059        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
16060        mStackSupervisor.dumpChildrenNames(pw, " ");
16061        pw.println(" ");
16062    }
16063
16064    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
16065        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
16066        mActivityStartController.dump(pw, "", dumpPackage);
16067    }
16068
16069    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16070            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16071        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
16072                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
16073    }
16074
16075    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16076            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
16077        pw.println(header);
16078
16079        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
16080                dumpPackage);
16081        boolean needSep = printedAnything;
16082
16083        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
16084                mStackSupervisor.getResumedActivityLocked(),
16085                dumpPackage, needSep, "  ResumedActivity: ");
16086        if (printed) {
16087            printedAnything = true;
16088            needSep = false;
16089        }
16090
16091        if (dumpPackage == null) {
16092            if (needSep) {
16093                pw.println();
16094            }
16095            printedAnything = true;
16096            mStackSupervisor.dump(pw, "  ");
16097        }
16098
16099        if (!printedAnything) {
16100            pw.println("  (nothing)");
16101        }
16102    }
16103
16104    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16105            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16106        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
16107
16108        int dumpUid = 0;
16109        if (dumpPackage != null) {
16110            IPackageManager pm = AppGlobals.getPackageManager();
16111            try {
16112                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
16113            } catch (RemoteException e) {
16114            }
16115        }
16116
16117        boolean printedAnything = false;
16118
16119        final long now = SystemClock.uptimeMillis();
16120
16121        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
16122            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
16123                    = mAssociations.valueAt(i1);
16124            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
16125                SparseArray<ArrayMap<String, Association>> sourceUids
16126                        = targetComponents.valueAt(i2);
16127                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
16128                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
16129                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
16130                        Association ass = sourceProcesses.valueAt(i4);
16131                        if (dumpPackage != null) {
16132                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
16133                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
16134                                continue;
16135                            }
16136                        }
16137                        printedAnything = true;
16138                        pw.print("  ");
16139                        pw.print(ass.mTargetProcess);
16140                        pw.print("/");
16141                        UserHandle.formatUid(pw, ass.mTargetUid);
16142                        pw.print(" <- ");
16143                        pw.print(ass.mSourceProcess);
16144                        pw.print("/");
16145                        UserHandle.formatUid(pw, ass.mSourceUid);
16146                        pw.println();
16147                        pw.print("    via ");
16148                        pw.print(ass.mTargetComponent.flattenToShortString());
16149                        pw.println();
16150                        pw.print("    ");
16151                        long dur = ass.mTime;
16152                        if (ass.mNesting > 0) {
16153                            dur += now - ass.mStartTime;
16154                        }
16155                        TimeUtils.formatDuration(dur, pw);
16156                        pw.print(" (");
16157                        pw.print(ass.mCount);
16158                        pw.print(" times)");
16159                        pw.print("  ");
16160                        for (int i=0; i<ass.mStateTimes.length; i++) {
16161                            long amt = ass.mStateTimes[i];
16162                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16163                                amt += now - ass.mLastStateUptime;
16164                            }
16165                            if (amt != 0) {
16166                                pw.print(" ");
16167                                pw.print(ProcessList.makeProcStateString(
16168                                            i + ActivityManager.MIN_PROCESS_STATE));
16169                                pw.print("=");
16170                                TimeUtils.formatDuration(amt, pw);
16171                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16172                                    pw.print("*");
16173                                }
16174                            }
16175                        }
16176                        pw.println();
16177                        if (ass.mNesting > 0) {
16178                            pw.print("    Currently active: ");
16179                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
16180                            pw.println();
16181                        }
16182                    }
16183                }
16184            }
16185
16186        }
16187
16188        if (!printedAnything) {
16189            pw.println("  (nothing)");
16190        }
16191    }
16192
16193    private int getAppId(String dumpPackage) {
16194        if (dumpPackage != null) {
16195            try {
16196                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
16197                        dumpPackage, 0);
16198                return UserHandle.getAppId(info.uid);
16199            } catch (NameNotFoundException e) {
16200                e.printStackTrace();
16201            }
16202        }
16203        return -1;
16204    }
16205
16206    boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
16207                String header, boolean needSep) {
16208        boolean printed = false;
16209        for (int i=0; i<uids.size(); i++) {
16210            UidRecord uidRec = uids.valueAt(i);
16211            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
16212                continue;
16213            }
16214            if (!printed) {
16215                printed = true;
16216                if (needSep) {
16217                    pw.println();
16218                }
16219                pw.print("  ");
16220                pw.println(header);
16221                needSep = true;
16222            }
16223            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
16224            pw.print(": "); pw.println(uidRec);
16225        }
16226        return printed;
16227    }
16228
16229    boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
16230        if(counts != null) {
16231            pw.println(header);
16232            for (int i = 0; i < counts.size(); i++) {
16233                final int uid = counts.keyAt(i);
16234                final int binderCount = counts.valueAt(i);
16235                pw.print("    UID ");
16236                pw.print(uid);
16237                pw.print(", binder count = ");
16238                pw.print(binderCount);
16239                pw.print(", package(s)= ");
16240                final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
16241                if (pkgNames != null) {
16242                    for (int j = 0; j < pkgNames.length; j++) {
16243                        pw.print(pkgNames[j]);
16244                        pw.print("; ");
16245                    }
16246                } else {
16247                    pw.print("NO PACKAGE NAME FOUND");
16248                }
16249                pw.println();
16250            }
16251            pw.println();
16252            return true;
16253        }
16254        return false;
16255    }
16256
16257    @GuardedBy("this")
16258    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16259            int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
16260        boolean needSep = false;
16261        int numPers = 0;
16262
16263        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
16264
16265        if (dumpAll) {
16266            final int NP = mProcessNames.getMap().size();
16267            for (int ip=0; ip<NP; ip++) {
16268                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16269                final int NA = procs.size();
16270                for (int ia=0; ia<NA; ia++) {
16271                    ProcessRecord r = procs.valueAt(ia);
16272                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16273                        continue;
16274                    }
16275                    if (!needSep) {
16276                        pw.println("  All known processes:");
16277                        needSep = true;
16278                    }
16279                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
16280                        pw.print(" UID "); pw.print(procs.keyAt(ia));
16281                        pw.print(" "); pw.println(r);
16282                    r.dump(pw, "    ");
16283                    if (r.persistent) {
16284                        numPers++;
16285                    }
16286                }
16287            }
16288        }
16289
16290        if (mIsolatedProcesses.size() > 0) {
16291            boolean printed = false;
16292            for (int i=0; i<mIsolatedProcesses.size(); i++) {
16293                ProcessRecord r = mIsolatedProcesses.valueAt(i);
16294                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16295                    continue;
16296                }
16297                if (!printed) {
16298                    if (needSep) {
16299                        pw.println();
16300                    }
16301                    pw.println("  Isolated process list (sorted by uid):");
16302                    printed = true;
16303                    needSep = true;
16304                }
16305                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
16306                pw.println(r);
16307            }
16308        }
16309
16310        if (mActiveInstrumentation.size() > 0) {
16311            boolean printed = false;
16312            for (int i=0; i<mActiveInstrumentation.size(); i++) {
16313                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16314                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16315                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16316                    continue;
16317                }
16318                if (!printed) {
16319                    if (needSep) {
16320                        pw.println();
16321                    }
16322                    pw.println("  Active instrumentation:");
16323                    printed = true;
16324                    needSep = true;
16325                }
16326                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
16327                pw.println(ai);
16328                ai.dump(pw, "      ");
16329            }
16330        }
16331
16332        if (mActiveUids.size() > 0) {
16333            if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16334                needSep = true;
16335            }
16336        }
16337        if (dumpAll) {
16338            if (mValidateUids.size() > 0) {
16339                if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16340                        needSep)) {
16341                    needSep = true;
16342                }
16343            }
16344        }
16345
16346        if (mLruProcesses.size() > 0) {
16347            if (needSep) {
16348                pw.println();
16349            }
16350            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16351                    pw.print(" total, non-act at ");
16352                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16353                    pw.print(", non-svc at ");
16354                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16355                    pw.println("):");
16356            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
16357            needSep = true;
16358        }
16359
16360        if (dumpAll || dumpPackage != null) {
16361            synchronized (mPidsSelfLocked) {
16362                boolean printed = false;
16363                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16364                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16365                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16366                        continue;
16367                    }
16368                    if (!printed) {
16369                        if (needSep) pw.println();
16370                        needSep = true;
16371                        pw.println("  PID mappings:");
16372                        printed = true;
16373                    }
16374                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16375                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16376                }
16377            }
16378        }
16379
16380        if (mImportantProcesses.size() > 0) {
16381            synchronized (mPidsSelfLocked) {
16382                boolean printed = false;
16383                for (int i = 0; i< mImportantProcesses.size(); i++) {
16384                    ProcessRecord r = mPidsSelfLocked.get(
16385                            mImportantProcesses.valueAt(i).pid);
16386                    if (dumpPackage != null && (r == null
16387                            || !r.pkgList.containsKey(dumpPackage))) {
16388                        continue;
16389                    }
16390                    if (!printed) {
16391                        if (needSep) pw.println();
16392                        needSep = true;
16393                        pw.println("  Foreground Processes:");
16394                        printed = true;
16395                    }
16396                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
16397                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16398                }
16399            }
16400        }
16401
16402        if (mPersistentStartingProcesses.size() > 0) {
16403            if (needSep) pw.println();
16404            needSep = true;
16405            pw.println("  Persisent processes that are starting:");
16406            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
16407                    "Starting Norm", "Restarting PERS", dumpPackage);
16408        }
16409
16410        if (mRemovedProcesses.size() > 0) {
16411            if (needSep) pw.println();
16412            needSep = true;
16413            pw.println("  Processes that are being removed:");
16414            dumpProcessList(pw, this, mRemovedProcesses, "    ",
16415                    "Removed Norm", "Removed PERS", dumpPackage);
16416        }
16417
16418        if (mProcessesOnHold.size() > 0) {
16419            if (needSep) pw.println();
16420            needSep = true;
16421            pw.println("  Processes that are on old until the system is ready:");
16422            dumpProcessList(pw, this, mProcessesOnHold, "    ",
16423                    "OnHold Norm", "OnHold PERS", dumpPackage);
16424        }
16425
16426        needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16427
16428        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16429
16430        if (dumpPackage == null) {
16431            pw.println();
16432            needSep = false;
16433            mUserController.dump(pw, dumpAll);
16434        }
16435        if (mHomeProcess != null && (dumpPackage == null
16436                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16437            if (needSep) {
16438                pw.println();
16439                needSep = false;
16440            }
16441            pw.println("  mHomeProcess: " + mHomeProcess);
16442        }
16443        if (mPreviousProcess != null && (dumpPackage == null
16444                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16445            if (needSep) {
16446                pw.println();
16447                needSep = false;
16448            }
16449            pw.println("  mPreviousProcess: " + mPreviousProcess);
16450        }
16451        if (dumpAll && (mPreviousProcess == null || dumpPackage == null
16452                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16453            StringBuilder sb = new StringBuilder(128);
16454            sb.append("  mPreviousProcessVisibleTime: ");
16455            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
16456            pw.println(sb);
16457        }
16458        if (mHeavyWeightProcess != null && (dumpPackage == null
16459                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16460            if (needSep) {
16461                pw.println();
16462                needSep = false;
16463            }
16464            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16465        }
16466        if (dumpAll && mPendingStarts.size() > 0) {
16467            if (needSep) pw.println();
16468            needSep = true;
16469            pw.println("  mPendingStarts: ");
16470            for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
16471                pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
16472            }
16473        }
16474        if (dumpPackage == null) {
16475            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
16476            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
16477        }
16478        if (dumpAll) {
16479            if (dumpPackage == null) {
16480                pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
16481            }
16482            if (mCompatModePackages.getPackages().size() > 0) {
16483                boolean printed = false;
16484                for (Map.Entry<String, Integer> entry
16485                        : mCompatModePackages.getPackages().entrySet()) {
16486                    String pkg = entry.getKey();
16487                    int mode = entry.getValue();
16488                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
16489                        continue;
16490                    }
16491                    if (!printed) {
16492                        pw.println("  mScreenCompatPackages:");
16493                        printed = true;
16494                    }
16495                    pw.print("    "); pw.print(pkg); pw.print(": ");
16496                            pw.print(mode); pw.println();
16497                }
16498            }
16499            final int NI = mUidObservers.getRegisteredCallbackCount();
16500            boolean printed = false;
16501            for (int i=0; i<NI; i++) {
16502                final UidObserverRegistration reg = (UidObserverRegistration)
16503                        mUidObservers.getRegisteredCallbackCookie(i);
16504                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16505                    if (!printed) {
16506                        pw.println("  mUidObservers:");
16507                        printed = true;
16508                    }
16509                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
16510                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
16511                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
16512                        pw.print(" IDLE");
16513                    }
16514                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
16515                        pw.print(" ACT" );
16516                    }
16517                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
16518                        pw.print(" GONE");
16519                    }
16520                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
16521                        pw.print(" STATE");
16522                        pw.print(" (cut="); pw.print(reg.cutpoint);
16523                        pw.print(")");
16524                    }
16525                    pw.println();
16526                    if (reg.lastProcStates != null) {
16527                        final int NJ = reg.lastProcStates.size();
16528                        for (int j=0; j<NJ; j++) {
16529                            pw.print("      Last ");
16530                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
16531                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
16532                        }
16533                    }
16534                }
16535            }
16536            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
16537            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
16538            if (mPendingTempWhitelist.size() > 0) {
16539                pw.println("  mPendingTempWhitelist:");
16540                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
16541                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
16542                    pw.print("    ");
16543                    UserHandle.formatUid(pw, ptw.targetUid);
16544                    pw.print(": ");
16545                    TimeUtils.formatDuration(ptw.duration, pw);
16546                    pw.print(" ");
16547                    pw.println(ptw.tag);
16548                }
16549            }
16550        }
16551        if (dumpPackage == null) {
16552            pw.println("  mWakefulness="
16553                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
16554            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
16555            pw.println("  mSleeping=" + mSleeping);
16556            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
16557            if (mRunningVoice != null) {
16558                pw.println("  mRunningVoice=" + mRunningVoice);
16559                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
16560            }
16561            pw.println("  mVrController=" + mVrController);
16562        }
16563        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16564                || mOrigWaitForDebugger) {
16565            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16566                    || dumpPackage.equals(mOrigDebugApp)) {
16567                if (needSep) {
16568                    pw.println();
16569                    needSep = false;
16570                }
16571                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
16572                        + " mDebugTransient=" + mDebugTransient
16573                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
16574            }
16575        }
16576        if (mCurAppTimeTracker != null) {
16577            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
16578        }
16579        if (mMemWatchProcesses.getMap().size() > 0) {
16580            pw.println("  Mem watch processes:");
16581            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
16582                    = mMemWatchProcesses.getMap();
16583            for (int i=0; i<procs.size(); i++) {
16584                final String proc = procs.keyAt(i);
16585                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16586                for (int j=0; j<uids.size(); j++) {
16587                    if (needSep) {
16588                        pw.println();
16589                        needSep = false;
16590                    }
16591                    StringBuilder sb = new StringBuilder();
16592                    sb.append("    ").append(proc).append('/');
16593                    UserHandle.formatUid(sb, uids.keyAt(j));
16594                    Pair<Long, String> val = uids.valueAt(j);
16595                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
16596                    if (val.second != null) {
16597                        sb.append(", report to ").append(val.second);
16598                    }
16599                    pw.println(sb.toString());
16600                }
16601            }
16602            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
16603            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
16604            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
16605                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
16606        }
16607        if (mTrackAllocationApp != null) {
16608            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16609                if (needSep) {
16610                    pw.println();
16611                    needSep = false;
16612                }
16613                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
16614            }
16615        }
16616        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16617                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16618            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16619                if (needSep) {
16620                    pw.println();
16621                    needSep = false;
16622                }
16623                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16624                if (mProfilerInfo != null) {
16625                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16626                            mProfilerInfo.profileFd);
16627                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16628                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16629                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16630                    pw.println("  mProfileType=" + mProfileType);
16631                }
16632            }
16633        }
16634        if (mNativeDebuggingApp != null) {
16635            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16636                if (needSep) {
16637                    pw.println();
16638                    needSep = false;
16639                }
16640                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16641            }
16642        }
16643        if (mAllowAppSwitchUids.size() > 0) {
16644            boolean printed = false;
16645            for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
16646                ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
16647                for (int j = 0; j < types.size(); j++) {
16648                    if (dumpPackage == null ||
16649                            UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
16650                        if (needSep) {
16651                            pw.println();
16652                            needSep = false;
16653                        }
16654                        if (!printed) {
16655                            pw.println("  mAllowAppSwitchUids:");
16656                            printed = true;
16657                        }
16658                        pw.print("    User ");
16659                        pw.print(mAllowAppSwitchUids.keyAt(i));
16660                        pw.print(": Type ");
16661                        pw.print(types.keyAt(j));
16662                        pw.print(" = ");
16663                        UserHandle.formatUid(pw, types.valueAt(j).intValue());
16664                        pw.println();
16665                    }
16666                }
16667            }
16668        }
16669        if (dumpPackage == null) {
16670            if (mAlwaysFinishActivities) {
16671                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16672            }
16673            if (mController != null) {
16674                pw.println("  mController=" + mController
16675                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16676            }
16677            if (dumpAll) {
16678                pw.println("  Total persistent processes: " + numPers);
16679                pw.println("  mProcessesReady=" + mProcessesReady
16680                        + " mSystemReady=" + mSystemReady
16681                        + " mBooted=" + mBooted
16682                        + " mFactoryTest=" + mFactoryTest);
16683                pw.println("  mBooting=" + mBooting
16684                        + " mCallFinishBooting=" + mCallFinishBooting
16685                        + " mBootAnimationComplete=" + mBootAnimationComplete);
16686                pw.print("  mLastPowerCheckUptime=");
16687                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16688                        pw.println("");
16689                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16690                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16691                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16692                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16693                        + " (" + mLruProcesses.size() + " total)"
16694                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16695                        + " mNumServiceProcs=" + mNumServiceProcs
16696                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16697                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16698                        + " mLastMemoryLevel=" + mLastMemoryLevel
16699                        + " mLastNumProcesses=" + mLastNumProcesses);
16700                long now = SystemClock.uptimeMillis();
16701                pw.print("  mLastIdleTime=");
16702                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
16703                        pw.print(" mLowRamSinceLastIdle=");
16704                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16705                        pw.println();
16706            }
16707        }
16708        pw.println("  mForceBackgroundCheck=" + mForceBackgroundCheck);
16709    }
16710
16711    @GuardedBy("this")
16712    void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
16713        int numPers = 0;
16714
16715        final int NP = mProcessNames.getMap().size();
16716        for (int ip=0; ip<NP; ip++) {
16717            SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16718            final int NA = procs.size();
16719            for (int ia = 0; ia<NA; ia++) {
16720                ProcessRecord r = procs.valueAt(ia);
16721                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16722                    continue;
16723                }
16724                r.writeToProto(proto, ProcessesProto.PROCS);
16725                if (r.persistent) {
16726                    numPers++;
16727                }
16728            }
16729        }
16730
16731        for (int i=0; i<mIsolatedProcesses.size(); i++) {
16732            ProcessRecord r = mIsolatedProcesses.valueAt(i);
16733            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16734                continue;
16735            }
16736            r.writeToProto(proto, ProcessesProto.ISOLATED_PROCS);
16737        }
16738
16739        for (int i=0; i<mActiveInstrumentation.size(); i++) {
16740            ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16741            if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16742                    && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16743                continue;
16744            }
16745            ai.writeToProto(proto, ProcessesProto.ACTIVE_INSTRUMENTATIONS);
16746        }
16747
16748        int whichAppId = getAppId(dumpPackage);
16749        for (int i=0; i<mActiveUids.size(); i++) {
16750            UidRecord uidRec = mActiveUids.valueAt(i);
16751            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16752                continue;
16753            }
16754            uidRec.writeToProto(proto, ProcessesProto.ACTIVE_UIDS);
16755        }
16756
16757        for (int i=0; i<mValidateUids.size(); i++) {
16758            UidRecord uidRec = mValidateUids.valueAt(i);
16759            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16760                continue;
16761            }
16762            uidRec.writeToProto(proto, ProcessesProto.VALIDATE_UIDS);
16763        }
16764
16765        if (mLruProcesses.size() > 0) {
16766            long lruToken = proto.start(ProcessesProto.LRU_PROCS);
16767            int total = mLruProcesses.size();
16768            proto.write(ProcessesProto.LruProcesses.SIZE, total);
16769            proto.write(ProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
16770            proto.write(ProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
16771            writeProcessOomListToProto(proto, ProcessesProto.LruProcesses.LIST, this,
16772                    mLruProcesses,false, dumpPackage);
16773            proto.end(lruToken);
16774        }
16775
16776        if (dumpPackage != null) {
16777            synchronized (mPidsSelfLocked) {
16778                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16779                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16780                    if (!r.pkgList.containsKey(dumpPackage)) {
16781                        continue;
16782                    }
16783                    r.writeToProto(proto, ProcessesProto.PIDS_SELF_LOCKED);
16784                }
16785            }
16786        }
16787
16788        if (mImportantProcesses.size() > 0) {
16789            synchronized (mPidsSelfLocked) {
16790                for (int i=0; i<mImportantProcesses.size(); i++) {
16791                    ImportanceToken it = mImportantProcesses.valueAt(i);
16792                    ProcessRecord r = mPidsSelfLocked.get(it.pid);
16793                    if (dumpPackage != null && (r == null
16794                            || !r.pkgList.containsKey(dumpPackage))) {
16795                        continue;
16796                    }
16797                    it.writeToProto(proto, ProcessesProto.IMPORTANT_PROCS);
16798                }
16799            }
16800        }
16801
16802        for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
16803            ProcessRecord r = mPersistentStartingProcesses.get(i);
16804            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16805                continue;
16806            }
16807            r.writeToProto(proto, ProcessesProto.PERSISTENT_STARTING_PROCS);
16808        }
16809
16810        for (int i=0; i<mRemovedProcesses.size(); i++) {
16811            ProcessRecord r = mRemovedProcesses.get(i);
16812            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16813                continue;
16814            }
16815            r.writeToProto(proto, ProcessesProto.REMOVED_PROCS);
16816        }
16817
16818        for (int i=0; i<mProcessesOnHold.size(); i++) {
16819            ProcessRecord r = mProcessesOnHold.get(i);
16820            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16821                continue;
16822            }
16823            r.writeToProto(proto, ProcessesProto.ON_HOLD_PROCS);
16824        }
16825
16826        writeProcessesToGcToProto(proto, ProcessesProto.GC_PROCS, dumpPackage);
16827        mAppErrors.writeToProto(proto, ProcessesProto.APP_ERRORS, dumpPackage);
16828
16829        if (dumpPackage == null) {
16830            mUserController.writeToProto(proto, ProcessesProto.USER_CONTROLLER);
16831            getGlobalConfiguration().writeToProto(proto, ProcessesProto.GLOBAL_CONFIGURATION);
16832            proto.write(ProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
16833        }
16834
16835        if (mHomeProcess != null && (dumpPackage == null
16836                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16837            mHomeProcess.writeToProto(proto, ProcessesProto.HOME_PROC);
16838        }
16839
16840        if (mPreviousProcess != null && (dumpPackage == null
16841                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16842            mPreviousProcess.writeToProto(proto, ProcessesProto.PREVIOUS_PROC);
16843            proto.write(ProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
16844        }
16845
16846        if (mHeavyWeightProcess != null && (dumpPackage == null
16847                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16848            mHeavyWeightProcess.writeToProto(proto, ProcessesProto.HEAVY_WEIGHT_PROC);
16849        }
16850
16851        for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
16852            String pkg = entry.getKey();
16853            int mode = entry.getValue();
16854            if (dumpPackage == null || dumpPackage.equals(pkg)) {
16855                long compatToken = proto.start(ProcessesProto.SCREEN_COMPAT_PACKAGES);
16856                proto.write(ProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
16857                proto.write(ProcessesProto.ScreenCompatPackage.MODE, mode);
16858                proto.end(compatToken);
16859            }
16860        }
16861
16862        final int NI = mUidObservers.getRegisteredCallbackCount();
16863        for (int i=0; i<NI; i++) {
16864            final UidObserverRegistration reg = (UidObserverRegistration)
16865                    mUidObservers.getRegisteredCallbackCookie(i);
16866            if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16867                reg.writeToProto(proto, ProcessesProto.UID_OBSERVERS);
16868            }
16869        }
16870
16871        for (int v : mDeviceIdleWhitelist) {
16872            proto.write(ProcessesProto.DEVICE_IDLE_WHITELIST, v);
16873        }
16874
16875        for (int v : mDeviceIdleTempWhitelist) {
16876            proto.write(ProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
16877        }
16878
16879        if (mPendingTempWhitelist.size() > 0) {
16880            for (int i=0; i < mPendingTempWhitelist.size(); i++) {
16881                mPendingTempWhitelist.valueAt(i).writeToProto(proto,
16882                        ProcessesProto.PENDING_TEMP_WHITELIST);
16883            }
16884        }
16885
16886        if (dumpPackage == null) {
16887            final long sleepToken = proto.start(ProcessesProto.SLEEP_STATUS);
16888            proto.write(ProcessesProto.SleepStatus.WAKEFULNESS,
16889                    PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
16890            for (SleepToken st : mStackSupervisor.mSleepTokens) {
16891                proto.write(ProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
16892            }
16893            proto.write(ProcessesProto.SleepStatus.SLEEPING, mSleeping);
16894            proto.write(ProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
16895            proto.write(ProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
16896            proto.end(sleepToken);
16897
16898            if (mRunningVoice != null) {
16899                final long vrToken = proto.start(ProcessesProto.RUNNING_VOICE);
16900                proto.write(ProcessesProto.VoiceProto.SESSION, mRunningVoice.toString());
16901                mVoiceWakeLock.writeToProto(proto, ProcessesProto.VoiceProto.WAKELOCK);
16902                proto.end(vrToken);
16903            }
16904
16905            mVrController.writeToProto(proto, ProcessesProto.VR_CONTROLLER);
16906        }
16907
16908        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16909                || mOrigWaitForDebugger) {
16910            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16911                    || dumpPackage.equals(mOrigDebugApp)) {
16912                final long debugAppToken = proto.start(ProcessesProto.DEBUG);
16913                proto.write(ProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
16914                proto.write(ProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
16915                proto.write(ProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
16916                proto.write(ProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
16917                proto.end(debugAppToken);
16918            }
16919        }
16920
16921        if (mCurAppTimeTracker != null) {
16922            mCurAppTimeTracker.writeToProto(proto, ProcessesProto.CURRENT_TRACKER, true);
16923        }
16924
16925        if (mMemWatchProcesses.getMap().size() > 0) {
16926            final long token = proto.start(ProcessesProto.MEM_WATCH_PROCESSES);
16927            ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
16928            for (int i=0; i<procs.size(); i++) {
16929                final String proc = procs.keyAt(i);
16930                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16931                final long ptoken = proto.start(ProcessesProto.MemWatchProcess.PROCS);
16932                proto.write(ProcessesProto.MemWatchProcess.Process.NAME, proc);
16933                for (int j=0; j<uids.size(); j++) {
16934                    final long utoken = proto.start(ProcessesProto.MemWatchProcess.Process.MEM_STATS);
16935                    Pair<Long, String> val = uids.valueAt(j);
16936                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
16937                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
16938                            DebugUtils.sizeValueToString(val.first, new StringBuilder()));
16939                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
16940                    proto.end(utoken);
16941                }
16942                proto.end(ptoken);
16943            }
16944
16945            final long dtoken = proto.start(ProcessesProto.MemWatchProcess.DUMP);
16946            proto.write(ProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
16947            proto.write(ProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
16948            proto.write(ProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
16949            proto.write(ProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
16950            proto.end(dtoken);
16951
16952            proto.end(token);
16953        }
16954
16955        if (mTrackAllocationApp != null) {
16956            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16957                proto.write(ProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
16958            }
16959        }
16960
16961        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16962                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16963            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16964                final long token = proto.start(ProcessesProto.PROFILE);
16965                proto.write(ProcessesProto.Profile.APP_NAME, mProfileApp);
16966                mProfileProc.writeToProto(proto,ProcessesProto.Profile.PROC);
16967                if (mProfilerInfo != null) {
16968                    mProfilerInfo.writeToProto(proto, ProcessesProto.Profile.INFO);
16969                    proto.write(ProcessesProto.Profile.TYPE, mProfileType);
16970                }
16971                proto.end(token);
16972            }
16973        }
16974
16975        if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16976            proto.write(ProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
16977        }
16978
16979        if (dumpPackage == null) {
16980            proto.write(ProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
16981            if (mController != null) {
16982                final long token = proto.start(ProcessesProto.CONTROLLER);
16983                proto.write(ProcessesProto.Controller.CONTROLLER, mController.toString());
16984                proto.write(ProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
16985                proto.end(token);
16986            }
16987            proto.write(ProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
16988            proto.write(ProcessesProto.PROCESSES_READY, mProcessesReady);
16989            proto.write(ProcessesProto.SYSTEM_READY, mSystemReady);
16990            proto.write(ProcessesProto.BOOTED, mBooted);
16991            proto.write(ProcessesProto.FACTORY_TEST, mFactoryTest);
16992            proto.write(ProcessesProto.BOOTING, mBooting);
16993            proto.write(ProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
16994            proto.write(ProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
16995            proto.write(ProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
16996            mStackSupervisor.mGoingToSleep.writeToProto(proto, ProcessesProto.GOING_TO_SLEEP);
16997            mStackSupervisor.mLaunchingActivity.writeToProto(proto, ProcessesProto.LAUNCHING_ACTIVITY);
16998            proto.write(ProcessesProto.ADJ_SEQ, mAdjSeq);
16999            proto.write(ProcessesProto.LRU_SEQ, mLruSeq);
17000            proto.write(ProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
17001            proto.write(ProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
17002            proto.write(ProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
17003            proto.write(ProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
17004            proto.write(ProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
17005            proto.write(ProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
17006            long now = SystemClock.uptimeMillis();
17007            ProtoUtils.toDuration(proto, ProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
17008            proto.write(ProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
17009        }
17010
17011    }
17012
17013    void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
17014        if (mProcessesToGc.size() > 0) {
17015            long now = SystemClock.uptimeMillis();
17016            for (int i=0; i<mProcessesToGc.size(); i++) {
17017                ProcessRecord r = mProcessesToGc.get(i);
17018                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17019                    continue;
17020                }
17021                final long token = proto.start(fieldId);
17022                r.writeToProto(proto, ProcessToGcProto.PROC);
17023                proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
17024                proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
17025                proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
17026                proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
17027                proto.end(token);
17028            }
17029        }
17030    }
17031
17032    boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
17033        if (mProcessesToGc.size() > 0) {
17034            boolean printed = false;
17035            long now = SystemClock.uptimeMillis();
17036            for (int i=0; i<mProcessesToGc.size(); i++) {
17037                ProcessRecord proc = mProcessesToGc.get(i);
17038                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
17039                    continue;
17040                }
17041                if (!printed) {
17042                    if (needSep) pw.println();
17043                    needSep = true;
17044                    pw.println("  Processes that are waiting to GC:");
17045                    printed = true;
17046                }
17047                pw.print("    Process "); pw.println(proc);
17048                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
17049                        pw.print(", last gced=");
17050                        pw.print(now-proc.lastRequestedGc);
17051                        pw.print(" ms ago, last lowMem=");
17052                        pw.print(now-proc.lastLowMemory);
17053                        pw.println(" ms ago");
17054
17055            }
17056        }
17057        return needSep;
17058    }
17059
17060    void printOomLevel(PrintWriter pw, String name, int adj) {
17061        pw.print("    ");
17062        if (adj >= 0) {
17063            pw.print(' ');
17064            if (adj < 10) pw.print(' ');
17065        } else {
17066            if (adj > -10) pw.print(' ');
17067        }
17068        pw.print(adj);
17069        pw.print(": ");
17070        pw.print(name);
17071        pw.print(" (");
17072        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
17073        pw.println(")");
17074    }
17075
17076    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17077            int opti, boolean dumpAll) {
17078        boolean needSep = false;
17079
17080        if (mLruProcesses.size() > 0) {
17081            if (needSep) pw.println();
17082            needSep = true;
17083            pw.println("  OOM levels:");
17084            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
17085            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
17086            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
17087            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
17088            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
17089            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
17090            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
17091            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
17092            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
17093            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
17094            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
17095            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
17096            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
17097            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
17098
17099            if (needSep) pw.println();
17100            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
17101                    pw.print(" total, non-act at ");
17102                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
17103                    pw.print(", non-svc at ");
17104                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
17105                    pw.println("):");
17106            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
17107            needSep = true;
17108        }
17109
17110        dumpProcessesToGc(pw, needSep, null);
17111
17112        pw.println();
17113        pw.println("  mHomeProcess: " + mHomeProcess);
17114        pw.println("  mPreviousProcess: " + mPreviousProcess);
17115        if (mHeavyWeightProcess != null) {
17116            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
17117        }
17118
17119        return true;
17120    }
17121
17122    /**
17123     * There are three ways to call this:
17124     *  - no provider specified: dump all the providers
17125     *  - a flattened component name that matched an existing provider was specified as the
17126     *    first arg: dump that one provider
17127     *  - the first arg isn't the flattened component name of an existing provider:
17128     *    dump all providers whose component contains the first arg as a substring
17129     */
17130    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17131            int opti, boolean dumpAll) {
17132        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
17133    }
17134
17135    /**
17136     * Similar to the dumpProvider, but only dumps the first matching provider.
17137     * The provider is responsible for dumping as proto.
17138     */
17139    protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
17140            String[] args) {
17141        return mProviderMap.dumpProviderProto(fd, pw, name, args);
17142    }
17143
17144    static class ItemMatcher {
17145        ArrayList<ComponentName> components;
17146        ArrayList<String> strings;
17147        ArrayList<Integer> objects;
17148        boolean all;
17149
17150        ItemMatcher() {
17151            all = true;
17152        }
17153
17154        void build(String name) {
17155            ComponentName componentName = ComponentName.unflattenFromString(name);
17156            if (componentName != null) {
17157                if (components == null) {
17158                    components = new ArrayList<ComponentName>();
17159                }
17160                components.add(componentName);
17161                all = false;
17162            } else {
17163                int objectId = 0;
17164                // Not a '/' separated full component name; maybe an object ID?
17165                try {
17166                    objectId = Integer.parseInt(name, 16);
17167                    if (objects == null) {
17168                        objects = new ArrayList<Integer>();
17169                    }
17170                    objects.add(objectId);
17171                    all = false;
17172                } catch (RuntimeException e) {
17173                    // Not an integer; just do string match.
17174                    if (strings == null) {
17175                        strings = new ArrayList<String>();
17176                    }
17177                    strings.add(name);
17178                    all = false;
17179                }
17180            }
17181        }
17182
17183        int build(String[] args, int opti) {
17184            for (; opti<args.length; opti++) {
17185                String name = args[opti];
17186                if ("--".equals(name)) {
17187                    return opti+1;
17188                }
17189                build(name);
17190            }
17191            return opti;
17192        }
17193
17194        boolean match(Object object, ComponentName comp) {
17195            if (all) {
17196                return true;
17197            }
17198            if (components != null) {
17199                for (int i=0; i<components.size(); i++) {
17200                    if (components.get(i).equals(comp)) {
17201                        return true;
17202                    }
17203                }
17204            }
17205            if (objects != null) {
17206                for (int i=0; i<objects.size(); i++) {
17207                    if (System.identityHashCode(object) == objects.get(i)) {
17208                        return true;
17209                    }
17210                }
17211            }
17212            if (strings != null) {
17213                String flat = comp.flattenToString();
17214                for (int i=0; i<strings.size(); i++) {
17215                    if (flat.contains(strings.get(i))) {
17216                        return true;
17217                    }
17218                }
17219            }
17220            return false;
17221        }
17222    }
17223
17224    /**
17225     * There are three things that cmd can be:
17226     *  - a flattened component name that matches an existing activity
17227     *  - the cmd arg isn't the flattened component name of an existing activity:
17228     *    dump all activity whose component contains the cmd as a substring
17229     *  - A hex number of the ActivityRecord object instance.
17230     *
17231     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
17232     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
17233     */
17234    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17235            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
17236        ArrayList<ActivityRecord> activities;
17237
17238        synchronized (this) {
17239            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
17240                    dumpFocusedStackOnly);
17241        }
17242
17243        if (activities.size() <= 0) {
17244            return false;
17245        }
17246
17247        String[] newArgs = new String[args.length - opti];
17248        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
17249
17250        TaskRecord lastTask = null;
17251        boolean needSep = false;
17252        for (int i=activities.size()-1; i>=0; i--) {
17253            ActivityRecord r = activities.get(i);
17254            if (needSep) {
17255                pw.println();
17256            }
17257            needSep = true;
17258            synchronized (this) {
17259                final TaskRecord task = r.getTask();
17260                if (lastTask != task) {
17261                    lastTask = task;
17262                    pw.print("TASK "); pw.print(lastTask.affinity);
17263                            pw.print(" id="); pw.print(lastTask.taskId);
17264                            pw.print(" userId="); pw.println(lastTask.userId);
17265                    if (dumpAll) {
17266                        lastTask.dump(pw, "  ");
17267                    }
17268                }
17269            }
17270            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
17271        }
17272        return true;
17273    }
17274
17275    /**
17276     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
17277     * there is a thread associated with the activity.
17278     */
17279    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
17280            final ActivityRecord r, String[] args, boolean dumpAll) {
17281        String innerPrefix = prefix + "  ";
17282        synchronized (this) {
17283            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
17284                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
17285                    pw.print(" pid=");
17286                    if (r.app != null) pw.println(r.app.pid);
17287                    else pw.println("(not running)");
17288            if (dumpAll) {
17289                r.dump(pw, innerPrefix);
17290            }
17291        }
17292        if (r.app != null && r.app.thread != null) {
17293            // flush anything that is already in the PrintWriter since the thread is going
17294            // to write to the file descriptor directly
17295            pw.flush();
17296            try {
17297                TransferPipe tp = new TransferPipe();
17298                try {
17299                    r.app.thread.dumpActivity(tp.getWriteFd(),
17300                            r.appToken, innerPrefix, args);
17301                    tp.go(fd);
17302                } finally {
17303                    tp.kill();
17304                }
17305            } catch (IOException e) {
17306                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
17307            } catch (RemoteException e) {
17308                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
17309            }
17310        }
17311    }
17312
17313    void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
17314        if (mRegisteredReceivers.size() > 0) {
17315            Iterator it = mRegisteredReceivers.values().iterator();
17316            while (it.hasNext()) {
17317                ReceiverList r = (ReceiverList)it.next();
17318                r.writeToProto(proto, BroadcastProto.RECEIVER_LIST);
17319            }
17320        }
17321        mReceiverResolver.writeToProto(proto, BroadcastProto.RECEIVER_RESOLVER);
17322        for (BroadcastQueue q : mBroadcastQueues) {
17323            q.writeToProto(proto, BroadcastProto.BROADCAST_QUEUE);
17324        }
17325        for (int user=0; user<mStickyBroadcasts.size(); user++) {
17326            long token = proto.start(BroadcastProto.STICKY_BROADCASTS);
17327            proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
17328            for (Map.Entry<String, ArrayList<Intent>> ent
17329                    : mStickyBroadcasts.valueAt(user).entrySet()) {
17330                long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
17331                proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
17332                for (Intent intent : ent.getValue()) {
17333                    intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
17334                            false, true, true, false);
17335                }
17336                proto.end(actionToken);
17337            }
17338            proto.end(token);
17339        }
17340
17341        long handlerToken = proto.start(BroadcastProto.HANDLER);
17342        proto.write(BroadcastProto.MainHandler.HANDLER, mHandler.toString());
17343        mHandler.getLooper().writeToProto(proto, BroadcastProto.MainHandler.LOOPER);
17344        proto.end(handlerToken);
17345    }
17346
17347    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17348            int opti, boolean dumpAll, String dumpPackage) {
17349        boolean needSep = false;
17350        boolean onlyHistory = false;
17351        boolean printedAnything = false;
17352
17353        if ("history".equals(dumpPackage)) {
17354            if (opti < args.length && "-s".equals(args[opti])) {
17355                dumpAll = false;
17356            }
17357            onlyHistory = true;
17358            dumpPackage = null;
17359        }
17360
17361        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
17362        if (!onlyHistory && dumpAll) {
17363            if (mRegisteredReceivers.size() > 0) {
17364                boolean printed = false;
17365                Iterator it = mRegisteredReceivers.values().iterator();
17366                while (it.hasNext()) {
17367                    ReceiverList r = (ReceiverList)it.next();
17368                    if (dumpPackage != null && (r.app == null ||
17369                            !dumpPackage.equals(r.app.info.packageName))) {
17370                        continue;
17371                    }
17372                    if (!printed) {
17373                        pw.println("  Registered Receivers:");
17374                        needSep = true;
17375                        printed = true;
17376                        printedAnything = true;
17377                    }
17378                    pw.print("  * "); pw.println(r);
17379                    r.dump(pw, "    ");
17380                }
17381            }
17382
17383            if (mReceiverResolver.dump(pw, needSep ?
17384                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
17385                    "    ", dumpPackage, false, false)) {
17386                needSep = true;
17387                printedAnything = true;
17388            }
17389        }
17390
17391        for (BroadcastQueue q : mBroadcastQueues) {
17392            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17393            printedAnything |= needSep;
17394        }
17395
17396        needSep = true;
17397
17398        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17399            for (int user=0; user<mStickyBroadcasts.size(); user++) {
17400                if (needSep) {
17401                    pw.println();
17402                }
17403                needSep = true;
17404                printedAnything = true;
17405                pw.print("  Sticky broadcasts for user ");
17406                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
17407                StringBuilder sb = new StringBuilder(128);
17408                for (Map.Entry<String, ArrayList<Intent>> ent
17409                        : mStickyBroadcasts.valueAt(user).entrySet()) {
17410                    pw.print("  * Sticky action "); pw.print(ent.getKey());
17411                    if (dumpAll) {
17412                        pw.println(":");
17413                        ArrayList<Intent> intents = ent.getValue();
17414                        final int N = intents.size();
17415                        for (int i=0; i<N; i++) {
17416                            sb.setLength(0);
17417                            sb.append("    Intent: ");
17418                            intents.get(i).toShortString(sb, false, true, false, false);
17419                            pw.println(sb.toString());
17420                            Bundle bundle = intents.get(i).getExtras();
17421                            if (bundle != null) {
17422                                pw.print("      ");
17423                                pw.println(bundle.toString());
17424                            }
17425                        }
17426                    } else {
17427                        pw.println("");
17428                    }
17429                }
17430            }
17431        }
17432
17433        if (!onlyHistory && dumpAll) {
17434            pw.println();
17435            for (BroadcastQueue queue : mBroadcastQueues) {
17436                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
17437                        + queue.mBroadcastsScheduled);
17438            }
17439            pw.println("  mHandler:");
17440            mHandler.dump(new PrintWriterPrinter(pw), "    ");
17441            needSep = true;
17442            printedAnything = true;
17443        }
17444
17445        if (!printedAnything) {
17446            pw.println("  (nothing)");
17447        }
17448    }
17449
17450    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17451            int opti, boolean dumpAll, String dumpPackage) {
17452        if (mCurBroadcastStats == null) {
17453            return;
17454        }
17455
17456        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
17457        final long now = SystemClock.elapsedRealtime();
17458        if (mLastBroadcastStats != null) {
17459            pw.print("  Last stats (from ");
17460            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
17461            pw.print(" to ");
17462            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
17463            pw.print(", ");
17464            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
17465                    - mLastBroadcastStats.mStartUptime, pw);
17466            pw.println(" uptime):");
17467            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17468                pw.println("    (nothing)");
17469            }
17470            pw.println();
17471        }
17472        pw.print("  Current stats (from ");
17473        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
17474        pw.print(" to now, ");
17475        TimeUtils.formatDuration(SystemClock.uptimeMillis()
17476                - mCurBroadcastStats.mStartUptime, pw);
17477        pw.println(" uptime):");
17478        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17479            pw.println("    (nothing)");
17480        }
17481    }
17482
17483    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17484            int opti, boolean fullCheckin, String dumpPackage) {
17485        if (mCurBroadcastStats == null) {
17486            return;
17487        }
17488
17489        if (mLastBroadcastStats != null) {
17490            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17491            if (fullCheckin) {
17492                mLastBroadcastStats = null;
17493                return;
17494            }
17495        }
17496        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17497        if (fullCheckin) {
17498            mCurBroadcastStats = null;
17499        }
17500    }
17501
17502    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17503            int opti, boolean dumpAll, String dumpPackage) {
17504        boolean needSep;
17505        boolean printedAnything = false;
17506
17507        ItemMatcher matcher = new ItemMatcher();
17508        matcher.build(args, opti);
17509
17510        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
17511
17512        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
17513        printedAnything |= needSep;
17514
17515        if (mLaunchingProviders.size() > 0) {
17516            boolean printed = false;
17517            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
17518                ContentProviderRecord r = mLaunchingProviders.get(i);
17519                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
17520                    continue;
17521                }
17522                if (!printed) {
17523                    if (needSep) pw.println();
17524                    needSep = true;
17525                    pw.println("  Launching content providers:");
17526                    printed = true;
17527                    printedAnything = true;
17528                }
17529                pw.print("  Launching #"); pw.print(i); pw.print(": ");
17530                        pw.println(r);
17531            }
17532        }
17533
17534        if (!printedAnything) {
17535            pw.println("  (nothing)");
17536        }
17537    }
17538
17539    @GuardedBy("this")
17540    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17541            int opti, boolean dumpAll, String dumpPackage) {
17542        boolean needSep = false;
17543        boolean printedAnything = false;
17544
17545        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
17546
17547        if (mGrantedUriPermissions.size() > 0) {
17548            boolean printed = false;
17549            int dumpUid = -2;
17550            if (dumpPackage != null) {
17551                try {
17552                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
17553                            MATCH_ANY_USER, 0);
17554                } catch (NameNotFoundException e) {
17555                    dumpUid = -1;
17556                }
17557            }
17558            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
17559                int uid = mGrantedUriPermissions.keyAt(i);
17560                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
17561                    continue;
17562                }
17563                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
17564                if (!printed) {
17565                    if (needSep) pw.println();
17566                    needSep = true;
17567                    pw.println("  Granted Uri Permissions:");
17568                    printed = true;
17569                    printedAnything = true;
17570                }
17571                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
17572                for (UriPermission perm : perms.values()) {
17573                    pw.print("    "); pw.println(perm);
17574                    if (dumpAll) {
17575                        perm.dump(pw, "      ");
17576                    }
17577                }
17578            }
17579        }
17580
17581        if (!printedAnything) {
17582            pw.println("  (nothing)");
17583        }
17584    }
17585
17586    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17587            int opti, boolean dumpAll, String dumpPackage) {
17588        boolean printed = false;
17589
17590        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
17591
17592        if (mIntentSenderRecords.size() > 0) {
17593            // Organize these by package name, so they are easier to read.
17594            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
17595            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
17596            final Iterator<WeakReference<PendingIntentRecord>> it
17597                    = mIntentSenderRecords.values().iterator();
17598            while (it.hasNext()) {
17599                WeakReference<PendingIntentRecord> ref = it.next();
17600                PendingIntentRecord rec = ref != null ? ref.get() : null;
17601                if (rec == null) {
17602                    weakRefs.add(ref);
17603                    continue;
17604                }
17605                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
17606                    continue;
17607                }
17608                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
17609                if (list == null) {
17610                    list = new ArrayList<>();
17611                    byPackage.put(rec.key.packageName, list);
17612                }
17613                list.add(rec);
17614            }
17615            for (int i = 0; i < byPackage.size(); i++) {
17616                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
17617                printed = true;
17618                pw.print("  * "); pw.print(byPackage.keyAt(i));
17619                pw.print(": "); pw.print(intents.size()); pw.println(" items");
17620                for (int j = 0; j < intents.size(); j++) {
17621                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
17622                    if (dumpAll) {
17623                        intents.get(j).dump(pw, "      ");
17624                    }
17625                }
17626            }
17627            if (weakRefs.size() > 0) {
17628                printed = true;
17629                pw.println("  * WEAK REFS:");
17630                for (int i = 0; i < weakRefs.size(); i++) {
17631                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
17632                }
17633            }
17634        }
17635
17636        if (!printed) {
17637            pw.println("  (nothing)");
17638        }
17639    }
17640
17641    private static final int dumpProcessList(PrintWriter pw,
17642            ActivityManagerService service, List list,
17643            String prefix, String normalLabel, String persistentLabel,
17644            String dumpPackage) {
17645        int numPers = 0;
17646        final int N = list.size()-1;
17647        for (int i=N; i>=0; i--) {
17648            ProcessRecord r = (ProcessRecord)list.get(i);
17649            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17650                continue;
17651            }
17652            pw.println(String.format("%s%s #%2d: %s",
17653                    prefix, (r.persistent ? persistentLabel : normalLabel),
17654                    i, r.toString()));
17655            if (r.persistent) {
17656                numPers++;
17657            }
17658        }
17659        return numPers;
17660    }
17661
17662    private static final ArrayList<Pair<ProcessRecord, Integer>>
17663        sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
17664        ArrayList<Pair<ProcessRecord, Integer>> list
17665                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
17666        for (int i=0; i<origList.size(); i++) {
17667            ProcessRecord r = origList.get(i);
17668            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17669                continue;
17670            }
17671            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
17672        }
17673
17674        Comparator<Pair<ProcessRecord, Integer>> comparator
17675                = new Comparator<Pair<ProcessRecord, Integer>>() {
17676            @Override
17677            public int compare(Pair<ProcessRecord, Integer> object1,
17678                    Pair<ProcessRecord, Integer> object2) {
17679                if (object1.first.setAdj != object2.first.setAdj) {
17680                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
17681                }
17682                if (object1.first.setProcState != object2.first.setProcState) {
17683                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
17684                }
17685                if (object1.second.intValue() != object2.second.intValue()) {
17686                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
17687                }
17688                return 0;
17689            }
17690        };
17691
17692        Collections.sort(list, comparator);
17693        return list;
17694    }
17695
17696    private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
17697            ActivityManagerService service, List<ProcessRecord> origList,
17698            boolean inclDetails, String dumpPackage) {
17699        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17700        if (list.isEmpty()) return false;
17701
17702        final long curUptime = SystemClock.uptimeMillis();
17703
17704        for (int i = list.size() - 1; i >= 0; i--) {
17705            ProcessRecord r = list.get(i).first;
17706            long token = proto.start(fieldId);
17707            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17708            proto.write(ProcessOomProto.PERSISTENT, r.persistent);
17709            proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
17710            proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
17711            int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
17712            switch (r.setSchedGroup) {
17713                case ProcessList.SCHED_GROUP_BACKGROUND:
17714                    schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
17715                    break;
17716                case ProcessList.SCHED_GROUP_DEFAULT:
17717                    schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
17718                    break;
17719                case ProcessList.SCHED_GROUP_TOP_APP:
17720                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
17721                    break;
17722                case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
17723                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
17724                    break;
17725            }
17726            if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
17727                proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
17728            }
17729            if (r.foregroundActivities) {
17730                proto.write(ProcessOomProto.ACTIVITIES, true);
17731            } else if (r.foregroundServices) {
17732                proto.write(ProcessOomProto.SERVICES, true);
17733            }
17734            proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
17735            proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
17736            r.writeToProto(proto, ProcessOomProto.PROC);
17737            proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
17738            if (r.adjSource != null || r.adjTarget != null) {
17739                if (r.adjTarget instanceof  ComponentName) {
17740                    ComponentName cn = (ComponentName) r.adjTarget;
17741                    cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
17742                } else if (r.adjTarget != null) {
17743                    proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
17744                }
17745                if (r.adjSource instanceof ProcessRecord) {
17746                    ProcessRecord p = (ProcessRecord) r.adjSource;
17747                    p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
17748                } else if (r.adjSource != null) {
17749                    proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
17750                }
17751            }
17752            if (inclDetails) {
17753                long detailToken = proto.start(ProcessOomProto.DETAIL);
17754                proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
17755                proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
17756                proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
17757                proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
17758                proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
17759                proto.write(ProcessOomProto.Detail.CURRENT_STATE,
17760                        ProcessList.makeProcStateProtoEnum(r.curProcState));
17761                proto.write(ProcessOomProto.Detail.SET_STATE,
17762                        ProcessList.makeProcStateProtoEnum(r.setProcState));
17763                proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
17764                        r.lastPss*1024, new StringBuilder()));
17765                proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
17766                        r.lastSwapPss*1024, new StringBuilder()));
17767                proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
17768                        r.lastCachedPss*1024, new StringBuilder()));
17769                proto.write(ProcessOomProto.Detail.CACHED, r.cached);
17770                proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
17771                proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
17772
17773                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
17774                    if (r.lastCpuTime != 0) {
17775                        long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17776                        long timeUsed = r.curCpuTime - r.lastCpuTime;
17777                        long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
17778                        proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
17779                        proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
17780                        proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
17781                                (100.0*timeUsed)/uptimeSince);
17782                        proto.end(cpuTimeToken);
17783                    }
17784                }
17785                proto.end(detailToken);
17786            }
17787            proto.end(token);
17788        }
17789
17790        return true;
17791    }
17792
17793    private static final boolean dumpProcessOomList(PrintWriter pw,
17794            ActivityManagerService service, List<ProcessRecord> origList,
17795            String prefix, String normalLabel, String persistentLabel,
17796            boolean inclDetails, String dumpPackage) {
17797
17798        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17799        if (list.isEmpty()) return false;
17800
17801        final long curUptime = SystemClock.uptimeMillis();
17802        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17803
17804        for (int i=list.size()-1; i>=0; i--) {
17805            ProcessRecord r = list.get(i).first;
17806            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17807            char schedGroup;
17808            switch (r.setSchedGroup) {
17809                case ProcessList.SCHED_GROUP_BACKGROUND:
17810                    schedGroup = 'B';
17811                    break;
17812                case ProcessList.SCHED_GROUP_DEFAULT:
17813                    schedGroup = 'F';
17814                    break;
17815                case ProcessList.SCHED_GROUP_TOP_APP:
17816                    schedGroup = 'T';
17817                    break;
17818                default:
17819                    schedGroup = '?';
17820                    break;
17821            }
17822            char foreground;
17823            if (r.foregroundActivities) {
17824                foreground = 'A';
17825            } else if (r.foregroundServices) {
17826                foreground = 'S';
17827            } else {
17828                foreground = ' ';
17829            }
17830            String procState = ProcessList.makeProcStateString(r.curProcState);
17831            pw.print(prefix);
17832            pw.print(r.persistent ? persistentLabel : normalLabel);
17833            pw.print(" #");
17834            int num = (origList.size()-1)-list.get(i).second;
17835            if (num < 10) pw.print(' ');
17836            pw.print(num);
17837            pw.print(": ");
17838            pw.print(oomAdj);
17839            pw.print(' ');
17840            pw.print(schedGroup);
17841            pw.print('/');
17842            pw.print(foreground);
17843            pw.print('/');
17844            pw.print(procState);
17845            pw.print(" trm:");
17846            if (r.trimMemoryLevel < 10) pw.print(' ');
17847            pw.print(r.trimMemoryLevel);
17848            pw.print(' ');
17849            pw.print(r.toShortString());
17850            pw.print(" (");
17851            pw.print(r.adjType);
17852            pw.println(')');
17853            if (r.adjSource != null || r.adjTarget != null) {
17854                pw.print(prefix);
17855                pw.print("    ");
17856                if (r.adjTarget instanceof ComponentName) {
17857                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
17858                } else if (r.adjTarget != null) {
17859                    pw.print(r.adjTarget.toString());
17860                } else {
17861                    pw.print("{null}");
17862                }
17863                pw.print("<=");
17864                if (r.adjSource instanceof ProcessRecord) {
17865                    pw.print("Proc{");
17866                    pw.print(((ProcessRecord)r.adjSource).toShortString());
17867                    pw.println("}");
17868                } else if (r.adjSource != null) {
17869                    pw.println(r.adjSource.toString());
17870                } else {
17871                    pw.println("{null}");
17872                }
17873            }
17874            if (inclDetails) {
17875                pw.print(prefix);
17876                pw.print("    ");
17877                pw.print("oom: max="); pw.print(r.maxAdj);
17878                pw.print(" curRaw="); pw.print(r.curRawAdj);
17879                pw.print(" setRaw="); pw.print(r.setRawAdj);
17880                pw.print(" cur="); pw.print(r.curAdj);
17881                pw.print(" set="); pw.println(r.setAdj);
17882                pw.print(prefix);
17883                pw.print("    ");
17884                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
17885                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
17886                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
17887                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
17888                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
17889                pw.println();
17890                pw.print(prefix);
17891                pw.print("    ");
17892                pw.print("cached="); pw.print(r.cached);
17893                pw.print(" empty="); pw.print(r.empty);
17894                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
17895
17896                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
17897                    if (r.lastCpuTime != 0) {
17898                        long timeUsed = r.curCpuTime - r.lastCpuTime;
17899                        pw.print(prefix);
17900                        pw.print("    ");
17901                        pw.print("run cpu over ");
17902                        TimeUtils.formatDuration(uptimeSince, pw);
17903                        pw.print(" used ");
17904                        TimeUtils.formatDuration(timeUsed, pw);
17905                        pw.print(" (");
17906                        pw.print((timeUsed*100)/uptimeSince);
17907                        pw.println("%)");
17908                    }
17909                }
17910            }
17911        }
17912        return true;
17913    }
17914
17915    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
17916            String[] args) {
17917        ArrayList<ProcessRecord> procs;
17918        synchronized (this) {
17919            if (args != null && args.length > start
17920                    && args[start].charAt(0) != '-') {
17921                procs = new ArrayList<ProcessRecord>();
17922                int pid = -1;
17923                try {
17924                    pid = Integer.parseInt(args[start]);
17925                } catch (NumberFormatException e) {
17926                }
17927                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17928                    ProcessRecord proc = mLruProcesses.get(i);
17929                    if (proc.pid > 0 && proc.pid == pid) {
17930                        procs.add(proc);
17931                    } else if (allPkgs && proc.pkgList != null
17932                            && proc.pkgList.containsKey(args[start])) {
17933                        procs.add(proc);
17934                    } else if (proc.processName.equals(args[start])) {
17935                        procs.add(proc);
17936                    }
17937                }
17938                if (procs.size() <= 0) {
17939                    return null;
17940                }
17941            } else {
17942                procs = new ArrayList<ProcessRecord>(mLruProcesses);
17943            }
17944        }
17945        return procs;
17946    }
17947
17948    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
17949            PrintWriter pw, String[] args) {
17950        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
17951        if (procs == null) {
17952            pw.println("No process found for: " + args[0]);
17953            return;
17954        }
17955
17956        long uptime = SystemClock.uptimeMillis();
17957        long realtime = SystemClock.elapsedRealtime();
17958        pw.println("Applications Graphics Acceleration Info:");
17959        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17960
17961        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17962            ProcessRecord r = procs.get(i);
17963            if (r.thread != null) {
17964                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
17965                pw.flush();
17966                try {
17967                    TransferPipe tp = new TransferPipe();
17968                    try {
17969                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
17970                        tp.go(fd);
17971                    } finally {
17972                        tp.kill();
17973                    }
17974                } catch (IOException e) {
17975                    pw.println("Failure while dumping the app: " + r);
17976                    pw.flush();
17977                } catch (RemoteException e) {
17978                    pw.println("Got a RemoteException while dumping the app " + r);
17979                    pw.flush();
17980                }
17981            }
17982        }
17983    }
17984
17985    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
17986        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
17987        if (procs == null) {
17988            pw.println("No process found for: " + args[0]);
17989            return;
17990        }
17991
17992        pw.println("Applications Database Info:");
17993
17994        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17995            ProcessRecord r = procs.get(i);
17996            if (r.thread != null) {
17997                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
17998                pw.flush();
17999                try {
18000                    TransferPipe tp = new TransferPipe();
18001                    try {
18002                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
18003                        tp.go(fd);
18004                    } finally {
18005                        tp.kill();
18006                    }
18007                } catch (IOException e) {
18008                    pw.println("Failure while dumping the app: " + r);
18009                    pw.flush();
18010                } catch (RemoteException e) {
18011                    pw.println("Got a RemoteException while dumping the app " + r);
18012                    pw.flush();
18013                }
18014            }
18015        }
18016    }
18017
18018    final static class MemItem {
18019        final boolean isProc;
18020        final String label;
18021        final String shortLabel;
18022        final long pss;
18023        final long swapPss;
18024        final int id;
18025        final boolean hasActivities;
18026        ArrayList<MemItem> subitems;
18027
18028        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
18029                boolean _hasActivities) {
18030            isProc = true;
18031            label = _label;
18032            shortLabel = _shortLabel;
18033            pss = _pss;
18034            swapPss = _swapPss;
18035            id = _id;
18036            hasActivities = _hasActivities;
18037        }
18038
18039        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
18040            isProc = false;
18041            label = _label;
18042            shortLabel = _shortLabel;
18043            pss = _pss;
18044            swapPss = _swapPss;
18045            id = _id;
18046            hasActivities = false;
18047        }
18048    }
18049
18050    private static void sortMemItems(List<MemItem> items) {
18051        Collections.sort(items, new Comparator<MemItem>() {
18052            @Override
18053            public int compare(MemItem lhs, MemItem rhs) {
18054                if (lhs.pss < rhs.pss) {
18055                    return 1;
18056                } else if (lhs.pss > rhs.pss) {
18057                    return -1;
18058                }
18059                return 0;
18060            }
18061        });
18062    }
18063
18064    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
18065            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
18066        if (sort && !isCompact) {
18067            sortMemItems(items);
18068        }
18069
18070        for (int i=0; i<items.size(); i++) {
18071            MemItem mi = items.get(i);
18072            if (!isCompact) {
18073                if (dumpSwapPss) {
18074                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
18075                            mi.label, stringifyKBSize(mi.swapPss));
18076                } else {
18077                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
18078                }
18079            } else if (mi.isProc) {
18080                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
18081                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
18082                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
18083                pw.println(mi.hasActivities ? ",a" : ",e");
18084            } else {
18085                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
18086                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
18087            }
18088            if (mi.subitems != null) {
18089                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
18090                        true, isCompact, dumpSwapPss);
18091            }
18092        }
18093    }
18094
18095    static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
18096            ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
18097        if (sort) {
18098            sortMemItems(items);
18099        }
18100
18101        for (int i=0; i<items.size(); i++) {
18102            MemItem mi = items.get(i);
18103            final long token = proto.start(fieldId);
18104
18105            proto.write(MemInfoProto.MemItem.TAG, tag);
18106            proto.write(MemInfoProto.MemItem.LABEL, mi.shortLabel);
18107            proto.write(MemInfoProto.MemItem.IS_PROC, mi.isProc);
18108            proto.write(MemInfoProto.MemItem.ID, mi.id);
18109            proto.write(MemInfoProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
18110            proto.write(MemInfoProto.MemItem.PSS_KB, mi.pss);
18111            if (dumpSwapPss) {
18112                proto.write(MemInfoProto.MemItem.SWAP_PSS_KB, mi.swapPss);
18113            }
18114            if (mi.subitems != null) {
18115                dumpMemItems(proto, MemInfoProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
18116                        true, dumpSwapPss);
18117            }
18118            proto.end(token);
18119        }
18120    }
18121
18122    // These are in KB.
18123    static final long[] DUMP_MEM_BUCKETS = new long[] {
18124        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
18125        120*1024, 160*1024, 200*1024,
18126        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
18127        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
18128    };
18129
18130    static final void appendMemBucket(StringBuilder out, long memKB, String label,
18131            boolean stackLike) {
18132        int start = label.lastIndexOf('.');
18133        if (start >= 0) start++;
18134        else start = 0;
18135        int end = label.length();
18136        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
18137            if (DUMP_MEM_BUCKETS[i] >= memKB) {
18138                long bucket = DUMP_MEM_BUCKETS[i]/1024;
18139                out.append(bucket);
18140                out.append(stackLike ? "MB." : "MB ");
18141                out.append(label, start, end);
18142                return;
18143            }
18144        }
18145        out.append(memKB/1024);
18146        out.append(stackLike ? "MB." : "MB ");
18147        out.append(label, start, end);
18148    }
18149
18150    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
18151            ProcessList.NATIVE_ADJ,
18152            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
18153            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
18154            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
18155            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
18156            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
18157            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
18158    };
18159    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
18160            "Native",
18161            "System", "Persistent", "Persistent Service", "Foreground",
18162            "Visible", "Perceptible",
18163            "Heavy Weight", "Backup",
18164            "A Services", "Home",
18165            "Previous", "B Services", "Cached"
18166    };
18167    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
18168            "native",
18169            "sys", "pers", "persvc", "fore",
18170            "vis", "percept",
18171            "heavy", "backup",
18172            "servicea", "home",
18173            "prev", "serviceb", "cached"
18174    };
18175
18176    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
18177            long realtime, boolean isCheckinRequest, boolean isCompact) {
18178        if (isCompact) {
18179            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
18180        }
18181        if (isCheckinRequest || isCompact) {
18182            // short checkin version
18183            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
18184        } else {
18185            pw.println("Applications Memory Usage (in Kilobytes):");
18186            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18187        }
18188    }
18189
18190    private static final int KSM_SHARED = 0;
18191    private static final int KSM_SHARING = 1;
18192    private static final int KSM_UNSHARED = 2;
18193    private static final int KSM_VOLATILE = 3;
18194
18195    private final long[] getKsmInfo() {
18196        long[] longOut = new long[4];
18197        final int[] SINGLE_LONG_FORMAT = new int[] {
18198            PROC_SPACE_TERM| PROC_OUT_LONG
18199        };
18200        long[] longTmp = new long[1];
18201        readProcFile("/sys/kernel/mm/ksm/pages_shared",
18202                SINGLE_LONG_FORMAT, null, longTmp, null);
18203        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18204        longTmp[0] = 0;
18205        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
18206                SINGLE_LONG_FORMAT, null, longTmp, null);
18207        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18208        longTmp[0] = 0;
18209        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
18210                SINGLE_LONG_FORMAT, null, longTmp, null);
18211        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18212        longTmp[0] = 0;
18213        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
18214                SINGLE_LONG_FORMAT, null, longTmp, null);
18215        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18216        return longOut;
18217    }
18218
18219    private static String stringifySize(long size, int order) {
18220        Locale locale = Locale.US;
18221        switch (order) {
18222            case 1:
18223                return String.format(locale, "%,13d", size);
18224            case 1024:
18225                return String.format(locale, "%,9dK", size / 1024);
18226            case 1024 * 1024:
18227                return String.format(locale, "%,5dM", size / 1024 / 1024);
18228            case 1024 * 1024 * 1024:
18229                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
18230            default:
18231                throw new IllegalArgumentException("Invalid size order");
18232        }
18233    }
18234
18235    private static String stringifyKBSize(long size) {
18236        return stringifySize(size * 1024, 1024);
18237    }
18238
18239    // Update this version number if you change the 'compact' format.
18240    private static final int MEMINFO_COMPACT_VERSION = 1;
18241
18242    private static class MemoryUsageDumpOptions {
18243        boolean dumpDetails;
18244        boolean dumpFullDetails;
18245        boolean dumpDalvik;
18246        boolean dumpSummaryOnly;
18247        boolean dumpUnreachable;
18248        boolean oomOnly;
18249        boolean isCompact;
18250        boolean localOnly;
18251        boolean packages;
18252        boolean isCheckinRequest;
18253        boolean dumpSwapPss;
18254        boolean dumpProto;
18255    }
18256
18257    final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18258            String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
18259        MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
18260        opts.dumpDetails = false;
18261        opts.dumpFullDetails = false;
18262        opts.dumpDalvik = false;
18263        opts.dumpSummaryOnly = false;
18264        opts.dumpUnreachable = false;
18265        opts.oomOnly = false;
18266        opts.isCompact = false;
18267        opts.localOnly = false;
18268        opts.packages = false;
18269        opts.isCheckinRequest = false;
18270        opts.dumpSwapPss = false;
18271        opts.dumpProto = asProto;
18272
18273        int opti = 0;
18274        while (opti < args.length) {
18275            String opt = args[opti];
18276            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18277                break;
18278            }
18279            opti++;
18280            if ("-a".equals(opt)) {
18281                opts.dumpDetails = true;
18282                opts.dumpFullDetails = true;
18283                opts.dumpDalvik = true;
18284                opts.dumpSwapPss = true;
18285            } else if ("-d".equals(opt)) {
18286                opts.dumpDalvik = true;
18287            } else if ("-c".equals(opt)) {
18288                opts.isCompact = true;
18289            } else if ("-s".equals(opt)) {
18290                opts.dumpDetails = true;
18291                opts.dumpSummaryOnly = true;
18292            } else if ("-S".equals(opt)) {
18293                opts.dumpSwapPss = true;
18294            } else if ("--unreachable".equals(opt)) {
18295                opts.dumpUnreachable = true;
18296            } else if ("--oom".equals(opt)) {
18297                opts.oomOnly = true;
18298            } else if ("--local".equals(opt)) {
18299                opts.localOnly = true;
18300            } else if ("--package".equals(opt)) {
18301                opts.packages = true;
18302            } else if ("--checkin".equals(opt)) {
18303                opts.isCheckinRequest = true;
18304            } else if ("--proto".equals(opt)) {
18305                opts.dumpProto = true;
18306
18307            } else if ("-h".equals(opt)) {
18308                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
18309                pw.println("  -a: include all available information for each process.");
18310                pw.println("  -d: include dalvik details.");
18311                pw.println("  -c: dump in a compact machine-parseable representation.");
18312                pw.println("  -s: dump only summary of application memory usage.");
18313                pw.println("  -S: dump also SwapPss.");
18314                pw.println("  --oom: only show processes organized by oom adj.");
18315                pw.println("  --local: only collect details locally, don't call process.");
18316                pw.println("  --package: interpret process arg as package, dumping all");
18317                pw.println("             processes that have loaded that package.");
18318                pw.println("  --checkin: dump data for a checkin");
18319                pw.println("  --proto: dump data to proto");
18320                pw.println("If [process] is specified it can be the name or ");
18321                pw.println("pid of a specific process to dump.");
18322                return;
18323            } else {
18324                pw.println("Unknown argument: " + opt + "; use -h for help");
18325            }
18326        }
18327
18328        String[] innerArgs = new String[args.length-opti];
18329        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18330
18331        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18332        if (opts.dumpProto) {
18333            dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18334        } else {
18335            dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
18336        }
18337    }
18338
18339    private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18340            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18341            ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
18342        long uptime = SystemClock.uptimeMillis();
18343        long realtime = SystemClock.elapsedRealtime();
18344        final long[] tmpLong = new long[1];
18345
18346        if (procs == null) {
18347            // No Java processes.  Maybe they want to print a native process.
18348            String proc = "N/A";
18349            if (innerArgs.length > 0) {
18350                proc = innerArgs[0];
18351                if (proc.charAt(0) != '-') {
18352                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18353                            = new ArrayList<ProcessCpuTracker.Stats>();
18354                    updateCpuStatsNow();
18355                    int findPid = -1;
18356                    try {
18357                        findPid = Integer.parseInt(innerArgs[0]);
18358                    } catch (NumberFormatException e) {
18359                    }
18360                    synchronized (mProcessCpuTracker) {
18361                        final int N = mProcessCpuTracker.countStats();
18362                        for (int i=0; i<N; i++) {
18363                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18364                            if (st.pid == findPid || (st.baseName != null
18365                                    && st.baseName.equals(innerArgs[0]))) {
18366                                nativeProcs.add(st);
18367                            }
18368                        }
18369                    }
18370                    if (nativeProcs.size() > 0) {
18371                        dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
18372                                opts.isCheckinRequest, opts.isCompact);
18373                        Debug.MemoryInfo mi = null;
18374                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18375                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18376                            final int pid = r.pid;
18377                            if (!opts.isCheckinRequest && opts.dumpDetails) {
18378                                pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
18379                            }
18380                            if (mi == null) {
18381                                mi = new Debug.MemoryInfo();
18382                            }
18383                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18384                                Debug.getMemoryInfo(pid, mi);
18385                            } else {
18386                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18387                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18388                            }
18389                            ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
18390                                    opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18391                                    pid, r.baseName, 0, 0, 0, 0, 0, 0);
18392                            if (opts.isCheckinRequest) {
18393                                pw.println();
18394                            }
18395                        }
18396                        return;
18397                    }
18398                }
18399            }
18400            pw.println("No process found for: " + proc);
18401            return;
18402        }
18403
18404        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18405            opts.dumpDetails = true;
18406        }
18407
18408        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
18409
18410        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18411        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18412        long nativePss = 0;
18413        long nativeSwapPss = 0;
18414        long dalvikPss = 0;
18415        long dalvikSwapPss = 0;
18416        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18417                EmptyArray.LONG;
18418        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18419                EmptyArray.LONG;
18420        long otherPss = 0;
18421        long otherSwapPss = 0;
18422        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18423        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18424
18425        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18426        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18427        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18428                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18429
18430        long totalPss = 0;
18431        long totalSwapPss = 0;
18432        long cachedPss = 0;
18433        long cachedSwapPss = 0;
18434        boolean hasSwapPss = false;
18435
18436        Debug.MemoryInfo mi = null;
18437        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18438            final ProcessRecord r = procs.get(i);
18439            final IApplicationThread thread;
18440            final int pid;
18441            final int oomAdj;
18442            final boolean hasActivities;
18443            synchronized (this) {
18444                thread = r.thread;
18445                pid = r.pid;
18446                oomAdj = r.getSetAdjWithServices();
18447                hasActivities = r.activities.size() > 0;
18448            }
18449            if (thread != null) {
18450                if (!opts.isCheckinRequest && opts.dumpDetails) {
18451                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
18452                }
18453                if (mi == null) {
18454                    mi = new Debug.MemoryInfo();
18455                }
18456                final int reportType;
18457                final long startTime;
18458                final long endTime;
18459                if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18460                    reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18461                    startTime = SystemClock.currentThreadTimeMillis();
18462                    Debug.getMemoryInfo(pid, mi);
18463                    endTime = SystemClock.currentThreadTimeMillis();
18464                    hasSwapPss = mi.hasSwappedOutPss;
18465                } else {
18466                    reportType = ProcessStats.ADD_PSS_EXTERNAL;
18467                    startTime = SystemClock.currentThreadTimeMillis();
18468                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18469                    endTime = SystemClock.currentThreadTimeMillis();
18470                    mi.dalvikPrivateDirty = (int)tmpLong[0];
18471                }
18472                if (opts.dumpDetails) {
18473                    if (opts.localOnly) {
18474                        ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
18475                                opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
18476                        if (opts.isCheckinRequest) {
18477                            pw.println();
18478                        }
18479                    } else {
18480                        pw.flush();
18481                        try {
18482                            TransferPipe tp = new TransferPipe();
18483                            try {
18484                                thread.dumpMemInfo(tp.getWriteFd(),
18485                                        mi, opts.isCheckinRequest, opts.dumpFullDetails,
18486                                        opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
18487                                tp.go(fd);
18488                            } finally {
18489                                tp.kill();
18490                            }
18491                        } catch (IOException e) {
18492                            if (!opts.isCheckinRequest) {
18493                                pw.println("Got IoException! " + e);
18494                                pw.flush();
18495                            }
18496                        } catch (RemoteException e) {
18497                            if (!opts.isCheckinRequest) {
18498                                pw.println("Got RemoteException! " + e);
18499                                pw.flush();
18500                            }
18501                        }
18502                    }
18503                }
18504
18505                final long myTotalPss = mi.getTotalPss();
18506                final long myTotalUss = mi.getTotalUss();
18507                final long myTotalRss = mi.getTotalRss();
18508                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18509
18510                synchronized (this) {
18511                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18512                        // Record this for posterity if the process has been stable.
18513                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
18514                                reportType, endTime-startTime, r.pkgList);
18515                    }
18516                }
18517
18518                if (!opts.isCheckinRequest && mi != null) {
18519                    totalPss += myTotalPss;
18520                    totalSwapPss += myTotalSwapPss;
18521                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
18522                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
18523                            myTotalSwapPss, pid, hasActivities);
18524                    procMems.add(pssItem);
18525                    procMemsMap.put(pid, pssItem);
18526
18527                    nativePss += mi.nativePss;
18528                    nativeSwapPss += mi.nativeSwappedOutPss;
18529                    dalvikPss += mi.dalvikPss;
18530                    dalvikSwapPss += mi.dalvikSwappedOutPss;
18531                    for (int j=0; j<dalvikSubitemPss.length; j++) {
18532                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18533                        dalvikSubitemSwapPss[j] +=
18534                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18535                    }
18536                    otherPss += mi.otherPss;
18537                    otherSwapPss += mi.otherSwappedOutPss;
18538                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18539                        long mem = mi.getOtherPss(j);
18540                        miscPss[j] += mem;
18541                        otherPss -= mem;
18542                        mem = mi.getOtherSwappedOutPss(j);
18543                        miscSwapPss[j] += mem;
18544                        otherSwapPss -= mem;
18545                    }
18546
18547                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18548                        cachedPss += myTotalPss;
18549                        cachedSwapPss += myTotalSwapPss;
18550                    }
18551
18552                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
18553                        if (oomIndex == (oomPss.length - 1)
18554                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
18555                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
18556                            oomPss[oomIndex] += myTotalPss;
18557                            oomSwapPss[oomIndex] += myTotalSwapPss;
18558                            if (oomProcs[oomIndex] == null) {
18559                                oomProcs[oomIndex] = new ArrayList<MemItem>();
18560                            }
18561                            oomProcs[oomIndex].add(pssItem);
18562                            break;
18563                        }
18564                    }
18565                }
18566            }
18567        }
18568
18569        long nativeProcTotalPss = 0;
18570
18571        if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
18572            // If we are showing aggregations, also look for native processes to
18573            // include so that our aggregations are more accurate.
18574            updateCpuStatsNow();
18575            mi = null;
18576            synchronized (mProcessCpuTracker) {
18577                final int N = mProcessCpuTracker.countStats();
18578                for (int i=0; i<N; i++) {
18579                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18580                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
18581                        if (mi == null) {
18582                            mi = new Debug.MemoryInfo();
18583                        }
18584                        if (!brief && !opts.oomOnly) {
18585                            Debug.getMemoryInfo(st.pid, mi);
18586                        } else {
18587                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
18588                            mi.nativePrivateDirty = (int)tmpLong[0];
18589                        }
18590
18591                        final long myTotalPss = mi.getTotalPss();
18592                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18593                        totalPss += myTotalPss;
18594                        totalSwapPss += myTotalSwapPss;
18595                        nativeProcTotalPss += myTotalPss;
18596
18597                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
18598                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
18599                        procMems.add(pssItem);
18600
18601                        nativePss += mi.nativePss;
18602                        nativeSwapPss += mi.nativeSwappedOutPss;
18603                        dalvikPss += mi.dalvikPss;
18604                        dalvikSwapPss += mi.dalvikSwappedOutPss;
18605                        for (int j=0; j<dalvikSubitemPss.length; j++) {
18606                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18607                            dalvikSubitemSwapPss[j] +=
18608                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18609                        }
18610                        otherPss += mi.otherPss;
18611                        otherSwapPss += mi.otherSwappedOutPss;
18612                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18613                            long mem = mi.getOtherPss(j);
18614                            miscPss[j] += mem;
18615                            otherPss -= mem;
18616                            mem = mi.getOtherSwappedOutPss(j);
18617                            miscSwapPss[j] += mem;
18618                            otherSwapPss -= mem;
18619                        }
18620                        oomPss[0] += myTotalPss;
18621                        oomSwapPss[0] += myTotalSwapPss;
18622                        if (oomProcs[0] == null) {
18623                            oomProcs[0] = new ArrayList<MemItem>();
18624                        }
18625                        oomProcs[0].add(pssItem);
18626                    }
18627                }
18628            }
18629
18630            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
18631
18632            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
18633            final int dalvikId = -2;
18634            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
18635            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
18636            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18637                String label = Debug.MemoryInfo.getOtherLabel(j);
18638                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
18639            }
18640            if (dalvikSubitemPss.length > 0) {
18641                // Add dalvik subitems.
18642                for (MemItem memItem : catMems) {
18643                    int memItemStart = 0, memItemEnd = 0;
18644                    if (memItem.id == dalvikId) {
18645                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
18646                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
18647                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
18648                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
18649                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
18650                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
18651                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
18652                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
18653                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
18654                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
18655                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
18656                    } else {
18657                        continue;  // No subitems, continue.
18658                    }
18659                    memItem.subitems = new ArrayList<MemItem>();
18660                    for (int j=memItemStart; j<=memItemEnd; j++) {
18661                        final String name = Debug.MemoryInfo.getOtherLabel(
18662                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
18663                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
18664                                dalvikSubitemSwapPss[j], j));
18665                    }
18666                }
18667            }
18668
18669            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
18670            for (int j=0; j<oomPss.length; j++) {
18671                if (oomPss[j] != 0) {
18672                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
18673                            : DUMP_MEM_OOM_LABEL[j];
18674                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
18675                            DUMP_MEM_OOM_ADJ[j]);
18676                    item.subitems = oomProcs[j];
18677                    oomMems.add(item);
18678                }
18679            }
18680
18681            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
18682            if (!brief && !opts.oomOnly && !opts.isCompact) {
18683                pw.println();
18684                pw.println("Total PSS by process:");
18685                dumpMemItems(pw, "  ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
18686                pw.println();
18687            }
18688            if (!opts.isCompact) {
18689                pw.println("Total PSS by OOM adjustment:");
18690            }
18691            dumpMemItems(pw, "  ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
18692            if (!brief && !opts.oomOnly) {
18693                PrintWriter out = categoryPw != null ? categoryPw : pw;
18694                if (!opts.isCompact) {
18695                    out.println();
18696                    out.println("Total PSS by category:");
18697                }
18698                dumpMemItems(out, "  ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
18699            }
18700            if (!opts.isCompact) {
18701                pw.println();
18702            }
18703            MemInfoReader memInfo = new MemInfoReader();
18704            memInfo.readMemInfo();
18705            if (nativeProcTotalPss > 0) {
18706                synchronized (this) {
18707                    final long cachedKb = memInfo.getCachedSizeKb();
18708                    final long freeKb = memInfo.getFreeSizeKb();
18709                    final long zramKb = memInfo.getZramTotalSizeKb();
18710                    final long kernelKb = memInfo.getKernelUsedSizeKb();
18711                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
18712                            kernelKb*1024, nativeProcTotalPss*1024);
18713                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
18714                            nativeProcTotalPss);
18715                }
18716            }
18717            if (!brief) {
18718                if (!opts.isCompact) {
18719                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
18720                    pw.print(" (status ");
18721                    switch (mLastMemoryLevel) {
18722                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
18723                            pw.println("normal)");
18724                            break;
18725                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
18726                            pw.println("moderate)");
18727                            break;
18728                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
18729                            pw.println("low)");
18730                            break;
18731                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18732                            pw.println("critical)");
18733                            break;
18734                        default:
18735                            pw.print(mLastMemoryLevel);
18736                            pw.println(")");
18737                            break;
18738                    }
18739                    pw.print(" Free RAM: ");
18740                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
18741                            + memInfo.getFreeSizeKb()));
18742                    pw.print(" (");
18743                    pw.print(stringifyKBSize(cachedPss));
18744                    pw.print(" cached pss + ");
18745                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
18746                    pw.print(" cached kernel + ");
18747                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
18748                    pw.println(" free)");
18749                } else {
18750                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
18751                    pw.print(cachedPss + memInfo.getCachedSizeKb()
18752                            + memInfo.getFreeSizeKb()); pw.print(",");
18753                    pw.println(totalPss - cachedPss);
18754                }
18755            }
18756            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
18757                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
18758                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
18759            if (!opts.isCompact) {
18760                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
18761                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
18762                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
18763                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
18764                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
18765            } else {
18766                pw.print("lostram,"); pw.println(lostRAM);
18767            }
18768            if (!brief) {
18769                if (memInfo.getZramTotalSizeKb() != 0) {
18770                    if (!opts.isCompact) {
18771                        pw.print("     ZRAM: ");
18772                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
18773                                pw.print(" physical used for ");
18774                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
18775                                        - memInfo.getSwapFreeSizeKb()));
18776                                pw.print(" in swap (");
18777                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
18778                                pw.println(" total swap)");
18779                    } else {
18780                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
18781                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
18782                                pw.println(memInfo.getSwapFreeSizeKb());
18783                    }
18784                }
18785                final long[] ksm = getKsmInfo();
18786                if (!opts.isCompact) {
18787                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
18788                            || ksm[KSM_VOLATILE] != 0) {
18789                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
18790                                pw.print(" saved from shared ");
18791                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
18792                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
18793                                pw.print(" unshared; ");
18794                                pw.print(stringifyKBSize(
18795                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
18796                    }
18797                    pw.print("   Tuning: ");
18798                    pw.print(ActivityManager.staticGetMemoryClass());
18799                    pw.print(" (large ");
18800                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18801                    pw.print("), oom ");
18802                    pw.print(stringifySize(
18803                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
18804                    pw.print(", restore limit ");
18805                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
18806                    if (ActivityManager.isLowRamDeviceStatic()) {
18807                        pw.print(" (low-ram)");
18808                    }
18809                    if (ActivityManager.isHighEndGfx()) {
18810                        pw.print(" (high-end-gfx)");
18811                    }
18812                    pw.println();
18813                } else {
18814                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
18815                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
18816                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
18817                    pw.print("tuning,");
18818                    pw.print(ActivityManager.staticGetMemoryClass());
18819                    pw.print(',');
18820                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18821                    pw.print(',');
18822                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
18823                    if (ActivityManager.isLowRamDeviceStatic()) {
18824                        pw.print(",low-ram");
18825                    }
18826                    if (ActivityManager.isHighEndGfx()) {
18827                        pw.print(",high-end-gfx");
18828                    }
18829                    pw.println();
18830                }
18831            }
18832        }
18833    }
18834
18835    private final void dumpApplicationMemoryUsage(FileDescriptor fd,
18836            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18837            ArrayList<ProcessRecord> procs) {
18838        final long uptimeMs = SystemClock.uptimeMillis();
18839        final long realtimeMs = SystemClock.elapsedRealtime();
18840        final long[] tmpLong = new long[1];
18841
18842        if (procs == null) {
18843            // No Java processes.  Maybe they want to print a native process.
18844            String proc = "N/A";
18845            if (innerArgs.length > 0) {
18846                proc = innerArgs[0];
18847                if (proc.charAt(0) != '-') {
18848                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18849                            = new ArrayList<ProcessCpuTracker.Stats>();
18850                    updateCpuStatsNow();
18851                    int findPid = -1;
18852                    try {
18853                        findPid = Integer.parseInt(innerArgs[0]);
18854                    } catch (NumberFormatException e) {
18855                    }
18856                    synchronized (mProcessCpuTracker) {
18857                        final int N = mProcessCpuTracker.countStats();
18858                        for (int i=0; i<N; i++) {
18859                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18860                            if (st.pid == findPid || (st.baseName != null
18861                                    && st.baseName.equals(innerArgs[0]))) {
18862                                nativeProcs.add(st);
18863                            }
18864                        }
18865                    }
18866                    if (nativeProcs.size() > 0) {
18867                        ProtoOutputStream proto = new ProtoOutputStream(fd);
18868
18869                        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
18870                        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
18871                        Debug.MemoryInfo mi = null;
18872                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18873                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18874                            final int pid = r.pid;
18875                            final long nToken = proto.start(MemInfoProto.NATIVE_PROCESSES);
18876
18877                            proto.write(MemInfoProto.ProcessMemory.PID, pid);
18878                            proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.baseName);
18879
18880                            if (mi == null) {
18881                                mi = new Debug.MemoryInfo();
18882                            }
18883                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18884                                Debug.getMemoryInfo(pid, mi);
18885                            } else {
18886                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18887                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18888                            }
18889                            ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
18890                                    opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
18891
18892                            proto.end(nToken);
18893                        }
18894
18895                        proto.flush();
18896                        return;
18897                    }
18898                }
18899            }
18900            Log.d(TAG, "No process found for: " + innerArgs[0]);
18901            return;
18902        }
18903
18904        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18905            opts.dumpDetails = true;
18906        }
18907
18908        ProtoOutputStream proto = new ProtoOutputStream(fd);
18909
18910        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
18911        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
18912
18913        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18914        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18915        long nativePss = 0;
18916        long nativeSwapPss = 0;
18917        long dalvikPss = 0;
18918        long dalvikSwapPss = 0;
18919        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18920                EmptyArray.LONG;
18921        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18922                EmptyArray.LONG;
18923        long otherPss = 0;
18924        long otherSwapPss = 0;
18925        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18926        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18927
18928        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18929        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18930        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18931                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18932
18933        long totalPss = 0;
18934        long totalSwapPss = 0;
18935        long cachedPss = 0;
18936        long cachedSwapPss = 0;
18937        boolean hasSwapPss = false;
18938
18939        Debug.MemoryInfo mi = null;
18940        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18941            final ProcessRecord r = procs.get(i);
18942            final IApplicationThread thread;
18943            final int pid;
18944            final int oomAdj;
18945            final boolean hasActivities;
18946            synchronized (this) {
18947                thread = r.thread;
18948                pid = r.pid;
18949                oomAdj = r.getSetAdjWithServices();
18950                hasActivities = r.activities.size() > 0;
18951            }
18952            if (thread == null) {
18953                continue;
18954            }
18955            if (mi == null) {
18956                mi = new Debug.MemoryInfo();
18957            }
18958            final int reportType;
18959            final long startTime;
18960            final long endTime;
18961            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18962                reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18963                startTime = SystemClock.currentThreadTimeMillis();
18964                Debug.getMemoryInfo(pid, mi);
18965                endTime = SystemClock.currentThreadTimeMillis();
18966                hasSwapPss = mi.hasSwappedOutPss;
18967            } else {
18968                reportType = ProcessStats.ADD_PSS_EXTERNAL;
18969                startTime = SystemClock.currentThreadTimeMillis();
18970                mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
18971                endTime = SystemClock.currentThreadTimeMillis();
18972                mi.dalvikPrivateDirty = (int) tmpLong[0];
18973            }
18974            if (opts.dumpDetails) {
18975                if (opts.localOnly) {
18976                    final long aToken = proto.start(MemInfoProto.APP_PROCESSES);
18977                    final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
18978                    proto.write(MemInfoProto.ProcessMemory.PID, pid);
18979                    proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.processName);
18980                    ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
18981                            opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
18982                    proto.end(mToken);
18983                    proto.end(aToken);
18984                } else {
18985                    try {
18986                        ByteTransferPipe tp = new ByteTransferPipe();
18987                        try {
18988                            thread.dumpMemInfoProto(tp.getWriteFd(),
18989                                mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18990                                opts.dumpUnreachable, innerArgs);
18991                            proto.write(MemInfoProto.APP_PROCESSES, tp.get());
18992                        } finally {
18993                            tp.kill();
18994                        }
18995                    } catch (IOException e) {
18996                        Log.e(TAG, "Got IOException!", e);
18997                    } catch (RemoteException e) {
18998                        Log.e(TAG, "Got RemoteException!", e);
18999                    }
19000                }
19001            }
19002
19003            final long myTotalPss = mi.getTotalPss();
19004            final long myTotalUss = mi.getTotalUss();
19005            final long myTotalRss = mi.getTotalRss();
19006            final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19007
19008            synchronized (this) {
19009                if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
19010                    // Record this for posterity if the process has been stable.
19011                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
19012                            reportType, endTime-startTime, r.pkgList);
19013                }
19014            }
19015
19016            if (!opts.isCheckinRequest && mi != null) {
19017                totalPss += myTotalPss;
19018                totalSwapPss += myTotalSwapPss;
19019                MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19020                        (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19021                        myTotalSwapPss, pid, hasActivities);
19022                procMems.add(pssItem);
19023                procMemsMap.put(pid, pssItem);
19024
19025                nativePss += mi.nativePss;
19026                nativeSwapPss += mi.nativeSwappedOutPss;
19027                dalvikPss += mi.dalvikPss;
19028                dalvikSwapPss += mi.dalvikSwappedOutPss;
19029                for (int j=0; j<dalvikSubitemPss.length; j++) {
19030                    dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19031                    dalvikSubitemSwapPss[j] +=
19032                            mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19033                }
19034                otherPss += mi.otherPss;
19035                otherSwapPss += mi.otherSwappedOutPss;
19036                for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19037                    long mem = mi.getOtherPss(j);
19038                    miscPss[j] += mem;
19039                    otherPss -= mem;
19040                    mem = mi.getOtherSwappedOutPss(j);
19041                    miscSwapPss[j] += mem;
19042                    otherSwapPss -= mem;
19043                }
19044
19045                if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19046                    cachedPss += myTotalPss;
19047                    cachedSwapPss += myTotalSwapPss;
19048                }
19049
19050                for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19051                    if (oomIndex == (oomPss.length - 1)
19052                            || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19053                                    && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19054                        oomPss[oomIndex] += myTotalPss;
19055                        oomSwapPss[oomIndex] += myTotalSwapPss;
19056                        if (oomProcs[oomIndex] == null) {
19057                            oomProcs[oomIndex] = new ArrayList<MemItem>();
19058                        }
19059                        oomProcs[oomIndex].add(pssItem);
19060                        break;
19061                    }
19062                }
19063            }
19064        }
19065
19066        long nativeProcTotalPss = 0;
19067
19068        if (procs.size() > 1 && !opts.packages) {
19069            // If we are showing aggregations, also look for native processes to
19070            // include so that our aggregations are more accurate.
19071            updateCpuStatsNow();
19072            mi = null;
19073            synchronized (mProcessCpuTracker) {
19074                final int N = mProcessCpuTracker.countStats();
19075                for (int i=0; i<N; i++) {
19076                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19077                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19078                        if (mi == null) {
19079                            mi = new Debug.MemoryInfo();
19080                        }
19081                        if (!brief && !opts.oomOnly) {
19082                            Debug.getMemoryInfo(st.pid, mi);
19083                        } else {
19084                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19085                            mi.nativePrivateDirty = (int)tmpLong[0];
19086                        }
19087
19088                        final long myTotalPss = mi.getTotalPss();
19089                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19090                        totalPss += myTotalPss;
19091                        nativeProcTotalPss += myTotalPss;
19092
19093                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19094                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19095                        procMems.add(pssItem);
19096
19097                        nativePss += mi.nativePss;
19098                        nativeSwapPss += mi.nativeSwappedOutPss;
19099                        dalvikPss += mi.dalvikPss;
19100                        dalvikSwapPss += mi.dalvikSwappedOutPss;
19101                        for (int j=0; j<dalvikSubitemPss.length; j++) {
19102                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19103                            dalvikSubitemSwapPss[j] +=
19104                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19105                        }
19106                        otherPss += mi.otherPss;
19107                        otherSwapPss += mi.otherSwappedOutPss;
19108                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19109                            long mem = mi.getOtherPss(j);
19110                            miscPss[j] += mem;
19111                            otherPss -= mem;
19112                            mem = mi.getOtherSwappedOutPss(j);
19113                            miscSwapPss[j] += mem;
19114                            otherSwapPss -= mem;
19115                        }
19116                        oomPss[0] += myTotalPss;
19117                        oomSwapPss[0] += myTotalSwapPss;
19118                        if (oomProcs[0] == null) {
19119                            oomProcs[0] = new ArrayList<MemItem>();
19120                        }
19121                        oomProcs[0].add(pssItem);
19122                    }
19123                }
19124            }
19125
19126            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19127
19128            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19129            final int dalvikId = -2;
19130            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19131            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19132            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19133                String label = Debug.MemoryInfo.getOtherLabel(j);
19134                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19135            }
19136            if (dalvikSubitemPss.length > 0) {
19137                // Add dalvik subitems.
19138                for (MemItem memItem : catMems) {
19139                    int memItemStart = 0, memItemEnd = 0;
19140                    if (memItem.id == dalvikId) {
19141                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19142                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19143                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19144                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19145                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19146                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19147                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19148                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19149                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19150                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19151                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19152                    } else {
19153                        continue;  // No subitems, continue.
19154                    }
19155                    memItem.subitems = new ArrayList<MemItem>();
19156                    for (int j=memItemStart; j<=memItemEnd; j++) {
19157                        final String name = Debug.MemoryInfo.getOtherLabel(
19158                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
19159                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19160                                dalvikSubitemSwapPss[j], j));
19161                    }
19162                }
19163            }
19164
19165            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19166            for (int j=0; j<oomPss.length; j++) {
19167                if (oomPss[j] != 0) {
19168                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19169                            : DUMP_MEM_OOM_LABEL[j];
19170                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19171                            DUMP_MEM_OOM_ADJ[j]);
19172                    item.subitems = oomProcs[j];
19173                    oomMems.add(item);
19174                }
19175            }
19176
19177            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19178            if (!opts.oomOnly) {
19179                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_PROCESS, "proc",
19180                        procMems, true, opts.dumpSwapPss);
19181            }
19182            dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
19183                    oomMems, false, opts.dumpSwapPss);
19184            if (!brief && !opts.oomOnly) {
19185                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_CATEGORY, "cat",
19186                        catMems, true, opts.dumpSwapPss);
19187            }
19188            MemInfoReader memInfo = new MemInfoReader();
19189            memInfo.readMemInfo();
19190            if (nativeProcTotalPss > 0) {
19191                synchronized (this) {
19192                    final long cachedKb = memInfo.getCachedSizeKb();
19193                    final long freeKb = memInfo.getFreeSizeKb();
19194                    final long zramKb = memInfo.getZramTotalSizeKb();
19195                    final long kernelKb = memInfo.getKernelUsedSizeKb();
19196                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19197                            kernelKb*1024, nativeProcTotalPss*1024);
19198                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19199                            nativeProcTotalPss);
19200                }
19201            }
19202            if (!brief) {
19203                proto.write(MemInfoProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
19204                proto.write(MemInfoProto.STATUS, mLastMemoryLevel);
19205                proto.write(MemInfoProto.CACHED_PSS_KB, cachedPss);
19206                proto.write(MemInfoProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
19207                proto.write(MemInfoProto.FREE_KB, memInfo.getFreeSizeKb());
19208            }
19209            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19210                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19211                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19212            proto.write(MemInfoProto.USED_PSS_KB, totalPss - cachedPss);
19213            proto.write(MemInfoProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
19214            proto.write(MemInfoProto.LOST_RAM_KB, lostRAM);
19215            if (!brief) {
19216                if (memInfo.getZramTotalSizeKb() != 0) {
19217                    proto.write(MemInfoProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
19218                    proto.write(MemInfoProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
19219                            memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
19220                    proto.write(MemInfoProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
19221                }
19222                final long[] ksm = getKsmInfo();
19223                proto.write(MemInfoProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
19224                proto.write(MemInfoProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
19225                proto.write(MemInfoProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
19226                proto.write(MemInfoProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
19227
19228                proto.write(MemInfoProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
19229                proto.write(MemInfoProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
19230                proto.write(MemInfoProto.OOM_KB,
19231                        mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
19232                proto.write(MemInfoProto.RESTORE_LIMIT_KB,
19233                        mProcessList.getCachedRestoreThresholdKb());
19234
19235                proto.write(MemInfoProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
19236                proto.write(MemInfoProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
19237            }
19238        }
19239
19240        proto.flush();
19241    }
19242
19243    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
19244            long memtrack, String name) {
19245        sb.append("  ");
19246        sb.append(ProcessList.makeOomAdjString(oomAdj));
19247        sb.append(' ');
19248        sb.append(ProcessList.makeProcStateString(procState));
19249        sb.append(' ');
19250        ProcessList.appendRamKb(sb, pss);
19251        sb.append(": ");
19252        sb.append(name);
19253        if (memtrack > 0) {
19254            sb.append(" (");
19255            sb.append(stringifyKBSize(memtrack));
19256            sb.append(" memtrack)");
19257        }
19258    }
19259
19260    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
19261        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
19262        sb.append(" (pid ");
19263        sb.append(mi.pid);
19264        sb.append(") ");
19265        sb.append(mi.adjType);
19266        sb.append('\n');
19267        if (mi.adjReason != null) {
19268            sb.append("                      ");
19269            sb.append(mi.adjReason);
19270            sb.append('\n');
19271        }
19272    }
19273
19274    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
19275        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
19276        for (int i=0, N=memInfos.size(); i<N; i++) {
19277            ProcessMemInfo mi = memInfos.get(i);
19278            infoMap.put(mi.pid, mi);
19279        }
19280        updateCpuStatsNow();
19281        long[] memtrackTmp = new long[1];
19282        final List<ProcessCpuTracker.Stats> stats;
19283        // Get a list of Stats that have vsize > 0
19284        synchronized (mProcessCpuTracker) {
19285            stats = mProcessCpuTracker.getStats((st) -> {
19286                return st.vsize > 0;
19287            });
19288        }
19289        final int statsCount = stats.size();
19290        for (int i = 0; i < statsCount; i++) {
19291            ProcessCpuTracker.Stats st = stats.get(i);
19292            long pss = Debug.getPss(st.pid, null, memtrackTmp);
19293            if (pss > 0) {
19294                if (infoMap.indexOfKey(st.pid) < 0) {
19295                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19296                            ProcessList.NATIVE_ADJ, -1, "native", null);
19297                    mi.pss = pss;
19298                    mi.memtrack = memtrackTmp[0];
19299                    memInfos.add(mi);
19300                }
19301            }
19302        }
19303
19304        long totalPss = 0;
19305        long totalMemtrack = 0;
19306        for (int i=0, N=memInfos.size(); i<N; i++) {
19307            ProcessMemInfo mi = memInfos.get(i);
19308            if (mi.pss == 0) {
19309                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19310                mi.memtrack = memtrackTmp[0];
19311            }
19312            totalPss += mi.pss;
19313            totalMemtrack += mi.memtrack;
19314        }
19315        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
19316            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
19317                if (lhs.oomAdj != rhs.oomAdj) {
19318                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
19319                }
19320                if (lhs.pss != rhs.pss) {
19321                    return lhs.pss < rhs.pss ? 1 : -1;
19322                }
19323                return 0;
19324            }
19325        });
19326
19327        StringBuilder tag = new StringBuilder(128);
19328        StringBuilder stack = new StringBuilder(128);
19329        tag.append("Low on memory -- ");
19330        appendMemBucket(tag, totalPss, "total", false);
19331        appendMemBucket(stack, totalPss, "total", true);
19332
19333        StringBuilder fullNativeBuilder = new StringBuilder(1024);
19334        StringBuilder shortNativeBuilder = new StringBuilder(1024);
19335        StringBuilder fullJavaBuilder = new StringBuilder(1024);
19336
19337        boolean firstLine = true;
19338        int lastOomAdj = Integer.MIN_VALUE;
19339        long extraNativeRam = 0;
19340        long extraNativeMemtrack = 0;
19341        long cachedPss = 0;
19342        for (int i=0, N=memInfos.size(); i<N; i++) {
19343            ProcessMemInfo mi = memInfos.get(i);
19344
19345            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19346                cachedPss += mi.pss;
19347            }
19348
19349            if (mi.oomAdj != ProcessList.NATIVE_ADJ
19350                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
19351                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
19352                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
19353                if (lastOomAdj != mi.oomAdj) {
19354                    lastOomAdj = mi.oomAdj;
19355                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19356                        tag.append(" / ");
19357                    }
19358                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19359                        if (firstLine) {
19360                            stack.append(":");
19361                            firstLine = false;
19362                        }
19363                        stack.append("\n\t at ");
19364                    } else {
19365                        stack.append("$");
19366                    }
19367                } else {
19368                    tag.append(" ");
19369                    stack.append("$");
19370                }
19371                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19372                    appendMemBucket(tag, mi.pss, mi.name, false);
19373                }
19374                appendMemBucket(stack, mi.pss, mi.name, true);
19375                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
19376                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
19377                    stack.append("(");
19378                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
19379                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
19380                            stack.append(DUMP_MEM_OOM_LABEL[k]);
19381                            stack.append(":");
19382                            stack.append(DUMP_MEM_OOM_ADJ[k]);
19383                        }
19384                    }
19385                    stack.append(")");
19386                }
19387            }
19388
19389            appendMemInfo(fullNativeBuilder, mi);
19390            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
19391                // The short form only has native processes that are >= 512K.
19392                if (mi.pss >= 512) {
19393                    appendMemInfo(shortNativeBuilder, mi);
19394                } else {
19395                    extraNativeRam += mi.pss;
19396                    extraNativeMemtrack += mi.memtrack;
19397                }
19398            } else {
19399                // Short form has all other details, but if we have collected RAM
19400                // from smaller native processes let's dump a summary of that.
19401                if (extraNativeRam > 0) {
19402                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
19403                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
19404                    shortNativeBuilder.append('\n');
19405                    extraNativeRam = 0;
19406                }
19407                appendMemInfo(fullJavaBuilder, mi);
19408            }
19409        }
19410
19411        fullJavaBuilder.append("           ");
19412        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
19413        fullJavaBuilder.append(": TOTAL");
19414        if (totalMemtrack > 0) {
19415            fullJavaBuilder.append(" (");
19416            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
19417            fullJavaBuilder.append(" memtrack)");
19418        } else {
19419        }
19420        fullJavaBuilder.append("\n");
19421
19422        MemInfoReader memInfo = new MemInfoReader();
19423        memInfo.readMemInfo();
19424        final long[] infos = memInfo.getRawInfo();
19425
19426        StringBuilder memInfoBuilder = new StringBuilder(1024);
19427        Debug.getMemInfo(infos);
19428        memInfoBuilder.append("  MemInfo: ");
19429        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
19430        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
19431        memInfoBuilder.append(stringifyKBSize(
19432                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
19433        memInfoBuilder.append(stringifyKBSize(
19434                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
19435        memInfoBuilder.append(stringifyKBSize(
19436                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
19437        memInfoBuilder.append("           ");
19438        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
19439        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
19440        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
19441        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
19442        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
19443            memInfoBuilder.append("  ZRAM: ");
19444            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
19445            memInfoBuilder.append(" RAM, ");
19446            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
19447            memInfoBuilder.append(" swap total, ");
19448            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
19449            memInfoBuilder.append(" swap free\n");
19450        }
19451        final long[] ksm = getKsmInfo();
19452        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19453                || ksm[KSM_VOLATILE] != 0) {
19454            memInfoBuilder.append("  KSM: ");
19455            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
19456            memInfoBuilder.append(" saved from shared ");
19457            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
19458            memInfoBuilder.append("\n       ");
19459            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
19460            memInfoBuilder.append(" unshared; ");
19461            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
19462            memInfoBuilder.append(" volatile\n");
19463        }
19464        memInfoBuilder.append("  Free RAM: ");
19465        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19466                + memInfo.getFreeSizeKb()));
19467        memInfoBuilder.append("\n");
19468        memInfoBuilder.append("  Used RAM: ");
19469        memInfoBuilder.append(stringifyKBSize(
19470                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
19471        memInfoBuilder.append("\n");
19472        memInfoBuilder.append("  Lost RAM: ");
19473        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
19474                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19475                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
19476        memInfoBuilder.append("\n");
19477        Slog.i(TAG, "Low on memory:");
19478        Slog.i(TAG, shortNativeBuilder.toString());
19479        Slog.i(TAG, fullJavaBuilder.toString());
19480        Slog.i(TAG, memInfoBuilder.toString());
19481
19482        StringBuilder dropBuilder = new StringBuilder(1024);
19483        /*
19484        StringWriter oomSw = new StringWriter();
19485        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
19486        StringWriter catSw = new StringWriter();
19487        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19488        String[] emptyArgs = new String[] { };
19489        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
19490        oomPw.flush();
19491        String oomString = oomSw.toString();
19492        */
19493        dropBuilder.append("Low on memory:");
19494        dropBuilder.append(stack);
19495        dropBuilder.append('\n');
19496        dropBuilder.append(fullNativeBuilder);
19497        dropBuilder.append(fullJavaBuilder);
19498        dropBuilder.append('\n');
19499        dropBuilder.append(memInfoBuilder);
19500        dropBuilder.append('\n');
19501        /*
19502        dropBuilder.append(oomString);
19503        dropBuilder.append('\n');
19504        */
19505        StringWriter catSw = new StringWriter();
19506        synchronized (ActivityManagerService.this) {
19507            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19508            String[] emptyArgs = new String[] { };
19509            catPw.println();
19510            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
19511            catPw.println();
19512            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
19513                    false, null).dumpLocked();
19514            catPw.println();
19515            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
19516            catPw.flush();
19517        }
19518        dropBuilder.append(catSw.toString());
19519        addErrorToDropBox("lowmem", null, "system_server", null,
19520                null, tag.toString(), dropBuilder.toString(), null, null);
19521        //Slog.i(TAG, "Sent to dropbox:");
19522        //Slog.i(TAG, dropBuilder.toString());
19523        synchronized (ActivityManagerService.this) {
19524            long now = SystemClock.uptimeMillis();
19525            if (mLastMemUsageReportTime < now) {
19526                mLastMemUsageReportTime = now;
19527            }
19528        }
19529    }
19530
19531    /**
19532     * Searches array of arguments for the specified string
19533     * @param args array of argument strings
19534     * @param value value to search for
19535     * @return true if the value is contained in the array
19536     */
19537    private static boolean scanArgs(String[] args, String value) {
19538        if (args != null) {
19539            for (String arg : args) {
19540                if (value.equals(arg)) {
19541                    return true;
19542                }
19543            }
19544        }
19545        return false;
19546    }
19547
19548    private final boolean removeDyingProviderLocked(ProcessRecord proc,
19549            ContentProviderRecord cpr, boolean always) {
19550        final boolean inLaunching = mLaunchingProviders.contains(cpr);
19551
19552        if (!inLaunching || always) {
19553            synchronized (cpr) {
19554                cpr.launchingApp = null;
19555                cpr.notifyAll();
19556            }
19557            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
19558            String names[] = cpr.info.authority.split(";");
19559            for (int j = 0; j < names.length; j++) {
19560                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
19561            }
19562        }
19563
19564        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
19565            ContentProviderConnection conn = cpr.connections.get(i);
19566            if (conn.waiting) {
19567                // If this connection is waiting for the provider, then we don't
19568                // need to mess with its process unless we are always removing
19569                // or for some reason the provider is not currently launching.
19570                if (inLaunching && !always) {
19571                    continue;
19572                }
19573            }
19574            ProcessRecord capp = conn.client;
19575            conn.dead = true;
19576            if (conn.stableCount > 0) {
19577                if (!capp.persistent && capp.thread != null
19578                        && capp.pid != 0
19579                        && capp.pid != MY_PID) {
19580                    capp.kill("depends on provider "
19581                            + cpr.name.flattenToShortString()
19582                            + " in dying proc " + (proc != null ? proc.processName : "??")
19583                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
19584                }
19585            } else if (capp.thread != null && conn.provider.provider != null) {
19586                try {
19587                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
19588                } catch (RemoteException e) {
19589                }
19590                // In the protocol here, we don't expect the client to correctly
19591                // clean up this connection, we'll just remove it.
19592                cpr.connections.remove(i);
19593                if (conn.client.conProviders.remove(conn)) {
19594                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
19595                }
19596            }
19597        }
19598
19599        if (inLaunching && always) {
19600            mLaunchingProviders.remove(cpr);
19601        }
19602        return inLaunching;
19603    }
19604
19605    /**
19606     * Main code for cleaning up a process when it has gone away.  This is
19607     * called both as a result of the process dying, or directly when stopping
19608     * a process when running in single process mode.
19609     *
19610     * @return Returns true if the given process has been restarted, so the
19611     * app that was passed in must remain on the process lists.
19612     */
19613    @GuardedBy("this")
19614    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
19615            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
19616        if (index >= 0) {
19617            removeLruProcessLocked(app);
19618            ProcessList.remove(app.pid);
19619        }
19620
19621        mProcessesToGc.remove(app);
19622        mPendingPssProcesses.remove(app);
19623        ProcessList.abortNextPssTime(app.procStateMemTracker);
19624
19625        // Dismiss any open dialogs.
19626        if (app.crashDialog != null && !app.forceCrashReport) {
19627            app.crashDialog.dismiss();
19628            app.crashDialog = null;
19629        }
19630        if (app.anrDialog != null) {
19631            app.anrDialog.dismiss();
19632            app.anrDialog = null;
19633        }
19634        if (app.waitDialog != null) {
19635            app.waitDialog.dismiss();
19636            app.waitDialog = null;
19637        }
19638
19639        app.crashing = false;
19640        app.notResponding = false;
19641
19642        app.resetPackageList(mProcessStats);
19643        app.unlinkDeathRecipient();
19644        app.makeInactive(mProcessStats);
19645        app.waitingToKill = null;
19646        app.forcingToImportant = null;
19647        updateProcessForegroundLocked(app, false, false);
19648        app.foregroundActivities = false;
19649        app.hasShownUi = false;
19650        app.treatLikeActivity = false;
19651        app.hasAboveClient = false;
19652        app.hasClientActivities = false;
19653
19654        mServices.killServicesLocked(app, allowRestart);
19655
19656        boolean restart = false;
19657
19658        // Remove published content providers.
19659        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
19660            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
19661            final boolean always = app.bad || !allowRestart;
19662            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
19663            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
19664                // We left the provider in the launching list, need to
19665                // restart it.
19666                restart = true;
19667            }
19668
19669            cpr.provider = null;
19670            cpr.proc = null;
19671        }
19672        app.pubProviders.clear();
19673
19674        // Take care of any launching providers waiting for this process.
19675        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
19676            restart = true;
19677        }
19678
19679        // Unregister from connected content providers.
19680        if (!app.conProviders.isEmpty()) {
19681            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
19682                ContentProviderConnection conn = app.conProviders.get(i);
19683                conn.provider.connections.remove(conn);
19684                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
19685                        conn.provider.name);
19686            }
19687            app.conProviders.clear();
19688        }
19689
19690        // At this point there may be remaining entries in mLaunchingProviders
19691        // where we were the only one waiting, so they are no longer of use.
19692        // Look for these and clean up if found.
19693        // XXX Commented out for now.  Trying to figure out a way to reproduce
19694        // the actual situation to identify what is actually going on.
19695        if (false) {
19696            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19697                ContentProviderRecord cpr = mLaunchingProviders.get(i);
19698                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
19699                    synchronized (cpr) {
19700                        cpr.launchingApp = null;
19701                        cpr.notifyAll();
19702                    }
19703                }
19704            }
19705        }
19706
19707        skipCurrentReceiverLocked(app);
19708
19709        // Unregister any receivers.
19710        for (int i = app.receivers.size() - 1; i >= 0; i--) {
19711            removeReceiverLocked(app.receivers.valueAt(i));
19712        }
19713        app.receivers.clear();
19714
19715        // If the app is undergoing backup, tell the backup manager about it
19716        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
19717            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
19718                    + mBackupTarget.appInfo + " died during backup");
19719            mHandler.post(new Runnable() {
19720                @Override
19721                public void run(){
19722                    try {
19723                        IBackupManager bm = IBackupManager.Stub.asInterface(
19724                                ServiceManager.getService(Context.BACKUP_SERVICE));
19725                        bm.agentDisconnected(app.info.packageName);
19726                    } catch (RemoteException e) {
19727                        // can't happen; backup manager is local
19728                    }
19729                }
19730            });
19731        }
19732
19733        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
19734            ProcessChangeItem item = mPendingProcessChanges.get(i);
19735            if (app.pid > 0 && item.pid == app.pid) {
19736                mPendingProcessChanges.remove(i);
19737                mAvailProcessChanges.add(item);
19738            }
19739        }
19740        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
19741                null).sendToTarget();
19742
19743        // If the caller is restarting this app, then leave it in its
19744        // current lists and let the caller take care of it.
19745        if (restarting) {
19746            return false;
19747        }
19748
19749        if (!app.persistent || app.isolated) {
19750            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
19751                    "Removing non-persistent process during cleanup: " + app);
19752            if (!replacingPid) {
19753                removeProcessNameLocked(app.processName, app.uid, app);
19754            }
19755            if (mHeavyWeightProcess == app) {
19756                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
19757                        mHeavyWeightProcess.userId, 0));
19758                mHeavyWeightProcess = null;
19759            }
19760        } else if (!app.removed) {
19761            // This app is persistent, so we need to keep its record around.
19762            // If it is not already on the pending app list, add it there
19763            // and start a new process for it.
19764            if (mPersistentStartingProcesses.indexOf(app) < 0) {
19765                mPersistentStartingProcesses.add(app);
19766                restart = true;
19767            }
19768        }
19769        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
19770                TAG_CLEANUP, "Clean-up removing on hold: " + app);
19771        mProcessesOnHold.remove(app);
19772
19773        if (app == mHomeProcess) {
19774            mHomeProcess = null;
19775        }
19776        if (app == mPreviousProcess) {
19777            mPreviousProcess = null;
19778        }
19779
19780        if (restart && !app.isolated) {
19781            // We have components that still need to be running in the
19782            // process, so re-launch it.
19783            if (index < 0) {
19784                ProcessList.remove(app.pid);
19785            }
19786            addProcessNameLocked(app);
19787            app.pendingStart = false;
19788            startProcessLocked(app, "restart", app.processName);
19789            return true;
19790        } else if (app.pid > 0 && app.pid != MY_PID) {
19791            // Goodbye!
19792            boolean removed;
19793            synchronized (mPidsSelfLocked) {
19794                mPidsSelfLocked.remove(app.pid);
19795                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
19796            }
19797            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
19798            if (app.isolated) {
19799                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
19800            }
19801            app.setPid(0);
19802        }
19803        return false;
19804    }
19805
19806    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
19807        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19808            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19809            if (cpr.launchingApp == app) {
19810                return true;
19811            }
19812        }
19813        return false;
19814    }
19815
19816    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
19817        // Look through the content providers we are waiting to have launched,
19818        // and if any run in this process then either schedule a restart of
19819        // the process or kill the client waiting for it if this process has
19820        // gone bad.
19821        boolean restart = false;
19822        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19823            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19824            if (cpr.launchingApp == app) {
19825                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
19826                    restart = true;
19827                } else {
19828                    removeDyingProviderLocked(app, cpr, true);
19829                }
19830            }
19831        }
19832        return restart;
19833    }
19834
19835    // =========================================================
19836    // SERVICES
19837    // =========================================================
19838
19839    @Override
19840    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
19841        enforceNotIsolatedCaller("getServices");
19842
19843        final int callingUid = Binder.getCallingUid();
19844        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
19845            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
19846        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
19847            callingUid);
19848        synchronized (this) {
19849            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
19850                allowed, canInteractAcrossUsers);
19851        }
19852    }
19853
19854    @Override
19855    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
19856        enforceNotIsolatedCaller("getRunningServiceControlPanel");
19857        synchronized (this) {
19858            return mServices.getRunningServiceControlPanelLocked(name);
19859        }
19860    }
19861
19862    @Override
19863    public ComponentName startService(IApplicationThread caller, Intent service,
19864            String resolvedType, boolean requireForeground, String callingPackage, int userId)
19865            throws TransactionTooLargeException {
19866        enforceNotIsolatedCaller("startService");
19867        // Refuse possible leaked file descriptors
19868        if (service != null && service.hasFileDescriptors() == true) {
19869            throw new IllegalArgumentException("File descriptors passed in Intent");
19870        }
19871
19872        if (callingPackage == null) {
19873            throw new IllegalArgumentException("callingPackage cannot be null");
19874        }
19875
19876        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
19877                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
19878        synchronized(this) {
19879            final int callingPid = Binder.getCallingPid();
19880            final int callingUid = Binder.getCallingUid();
19881            final long origId = Binder.clearCallingIdentity();
19882            ComponentName res;
19883            try {
19884                res = mServices.startServiceLocked(caller, service,
19885                        resolvedType, callingPid, callingUid,
19886                        requireForeground, callingPackage, userId);
19887            } finally {
19888                Binder.restoreCallingIdentity(origId);
19889            }
19890            return res;
19891        }
19892    }
19893
19894    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
19895            boolean fgRequired, String callingPackage, int userId)
19896            throws TransactionTooLargeException {
19897        synchronized(this) {
19898            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
19899                    "startServiceInPackage: " + service + " type=" + resolvedType);
19900            final long origId = Binder.clearCallingIdentity();
19901            ComponentName res;
19902            try {
19903                res = mServices.startServiceLocked(null, service,
19904                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
19905            } finally {
19906                Binder.restoreCallingIdentity(origId);
19907            }
19908            return res;
19909        }
19910    }
19911
19912    @Override
19913    public int stopService(IApplicationThread caller, Intent service,
19914            String resolvedType, int userId) {
19915        enforceNotIsolatedCaller("stopService");
19916        // Refuse possible leaked file descriptors
19917        if (service != null && service.hasFileDescriptors() == true) {
19918            throw new IllegalArgumentException("File descriptors passed in Intent");
19919        }
19920
19921        synchronized(this) {
19922            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
19923        }
19924    }
19925
19926    @Override
19927    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
19928        enforceNotIsolatedCaller("peekService");
19929        // Refuse possible leaked file descriptors
19930        if (service != null && service.hasFileDescriptors() == true) {
19931            throw new IllegalArgumentException("File descriptors passed in Intent");
19932        }
19933
19934        if (callingPackage == null) {
19935            throw new IllegalArgumentException("callingPackage cannot be null");
19936        }
19937
19938        synchronized(this) {
19939            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
19940        }
19941    }
19942
19943    @Override
19944    public boolean stopServiceToken(ComponentName className, IBinder token,
19945            int startId) {
19946        synchronized(this) {
19947            return mServices.stopServiceTokenLocked(className, token, startId);
19948        }
19949    }
19950
19951    @Override
19952    public void setServiceForeground(ComponentName className, IBinder token,
19953            int id, Notification notification, int flags) {
19954        synchronized(this) {
19955            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
19956        }
19957    }
19958
19959    @Override
19960    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
19961            boolean requireFull, String name, String callerPackage) {
19962        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
19963                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
19964    }
19965
19966    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
19967            String className, int flags) {
19968        boolean result = false;
19969        // For apps that don't have pre-defined UIDs, check for permission
19970        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
19971            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
19972                if (ActivityManager.checkUidPermission(
19973                        INTERACT_ACROSS_USERS,
19974                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
19975                    ComponentName comp = new ComponentName(aInfo.packageName, className);
19976                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
19977                            + " requests FLAG_SINGLE_USER, but app does not hold "
19978                            + INTERACT_ACROSS_USERS;
19979                    Slog.w(TAG, msg);
19980                    throw new SecurityException(msg);
19981                }
19982                // Permission passed
19983                result = true;
19984            }
19985        } else if ("system".equals(componentProcessName)) {
19986            result = true;
19987        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
19988            // Phone app and persistent apps are allowed to export singleuser providers.
19989            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
19990                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
19991        }
19992        if (DEBUG_MU) Slog.v(TAG_MU,
19993                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
19994                + Integer.toHexString(flags) + ") = " + result);
19995        return result;
19996    }
19997
19998    /**
19999     * Checks to see if the caller is in the same app as the singleton
20000     * component, or the component is in a special app. It allows special apps
20001     * to export singleton components but prevents exporting singleton
20002     * components for regular apps.
20003     */
20004    boolean isValidSingletonCall(int callingUid, int componentUid) {
20005        int componentAppId = UserHandle.getAppId(componentUid);
20006        return UserHandle.isSameApp(callingUid, componentUid)
20007                || componentAppId == SYSTEM_UID
20008                || componentAppId == PHONE_UID
20009                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
20010                        == PackageManager.PERMISSION_GRANTED;
20011    }
20012
20013    public int bindService(IApplicationThread caller, IBinder token, Intent service,
20014            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
20015            int userId) throws TransactionTooLargeException {
20016        enforceNotIsolatedCaller("bindService");
20017
20018        // Refuse possible leaked file descriptors
20019        if (service != null && service.hasFileDescriptors() == true) {
20020            throw new IllegalArgumentException("File descriptors passed in Intent");
20021        }
20022
20023        if (callingPackage == null) {
20024            throw new IllegalArgumentException("callingPackage cannot be null");
20025        }
20026
20027        synchronized(this) {
20028            return mServices.bindServiceLocked(caller, token, service,
20029                    resolvedType, connection, flags, callingPackage, userId);
20030        }
20031    }
20032
20033    public boolean unbindService(IServiceConnection connection) {
20034        synchronized (this) {
20035            return mServices.unbindServiceLocked(connection);
20036        }
20037    }
20038
20039    public void publishService(IBinder token, Intent intent, IBinder service) {
20040        // Refuse possible leaked file descriptors
20041        if (intent != null && intent.hasFileDescriptors() == true) {
20042            throw new IllegalArgumentException("File descriptors passed in Intent");
20043        }
20044
20045        synchronized(this) {
20046            if (!(token instanceof ServiceRecord)) {
20047                throw new IllegalArgumentException("Invalid service token");
20048            }
20049            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
20050        }
20051    }
20052
20053    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
20054        // Refuse possible leaked file descriptors
20055        if (intent != null && intent.hasFileDescriptors() == true) {
20056            throw new IllegalArgumentException("File descriptors passed in Intent");
20057        }
20058
20059        synchronized(this) {
20060            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
20061        }
20062    }
20063
20064    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
20065        synchronized(this) {
20066            if (!(token instanceof ServiceRecord)) {
20067                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
20068                throw new IllegalArgumentException("Invalid service token");
20069            }
20070            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
20071        }
20072    }
20073
20074    // =========================================================
20075    // BACKUP AND RESTORE
20076    // =========================================================
20077
20078    // Cause the target app to be launched if necessary and its backup agent
20079    // instantiated.  The backup agent will invoke backupAgentCreated() on the
20080    // activity manager to announce its creation.
20081    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
20082        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
20083        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
20084
20085        IPackageManager pm = AppGlobals.getPackageManager();
20086        ApplicationInfo app = null;
20087        try {
20088            app = pm.getApplicationInfo(packageName, 0, userId);
20089        } catch (RemoteException e) {
20090            // can't happen; package manager is process-local
20091        }
20092        if (app == null) {
20093            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
20094            return false;
20095        }
20096
20097        int oldBackupUid;
20098        int newBackupUid;
20099
20100        synchronized(this) {
20101            // !!! TODO: currently no check here that we're already bound
20102            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
20103            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20104            synchronized (stats) {
20105                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
20106            }
20107
20108            // Backup agent is now in use, its package can't be stopped.
20109            try {
20110                AppGlobals.getPackageManager().setPackageStoppedState(
20111                        app.packageName, false, UserHandle.getUserId(app.uid));
20112            } catch (RemoteException e) {
20113            } catch (IllegalArgumentException e) {
20114                Slog.w(TAG, "Failed trying to unstop package "
20115                        + app.packageName + ": " + e);
20116            }
20117
20118            BackupRecord r = new BackupRecord(ss, app, backupMode);
20119            ComponentName hostingName =
20120                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
20121                            ? new ComponentName(app.packageName, app.backupAgentName)
20122                            : new ComponentName("android", "FullBackupAgent");
20123            // startProcessLocked() returns existing proc's record if it's already running
20124            ProcessRecord proc = startProcessLocked(app.processName, app,
20125                    false, 0, "backup", hostingName, false, false, false);
20126            if (proc == null) {
20127                Slog.e(TAG, "Unable to start backup agent process " + r);
20128                return false;
20129            }
20130
20131            // If the app is a regular app (uid >= 10000) and not the system server or phone
20132            // process, etc, then mark it as being in full backup so that certain calls to the
20133            // process can be blocked. This is not reset to false anywhere because we kill the
20134            // process after the full backup is done and the ProcessRecord will vaporize anyway.
20135            if (UserHandle.isApp(app.uid) &&
20136                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
20137                proc.inFullBackup = true;
20138            }
20139            r.app = proc;
20140            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20141            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
20142            mBackupTarget = r;
20143            mBackupAppName = app.packageName;
20144
20145            // Try not to kill the process during backup
20146            updateOomAdjLocked(proc, true);
20147
20148            // If the process is already attached, schedule the creation of the backup agent now.
20149            // If it is not yet live, this will be done when it attaches to the framework.
20150            if (proc.thread != null) {
20151                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
20152                try {
20153                    proc.thread.scheduleCreateBackupAgent(app,
20154                            compatibilityInfoForPackageLocked(app), backupMode);
20155                } catch (RemoteException e) {
20156                    // Will time out on the backup manager side
20157                }
20158            } else {
20159                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
20160            }
20161            // Invariants: at this point, the target app process exists and the application
20162            // is either already running or in the process of coming up.  mBackupTarget and
20163            // mBackupAppName describe the app, so that when it binds back to the AM we
20164            // know that it's scheduled for a backup-agent operation.
20165        }
20166
20167        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20168        if (oldBackupUid != -1) {
20169            js.removeBackingUpUid(oldBackupUid);
20170        }
20171        if (newBackupUid != -1) {
20172            js.addBackingUpUid(newBackupUid);
20173        }
20174
20175        return true;
20176    }
20177
20178    @Override
20179    public void clearPendingBackup() {
20180        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
20181        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
20182
20183        synchronized (this) {
20184            mBackupTarget = null;
20185            mBackupAppName = null;
20186        }
20187
20188        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20189        js.clearAllBackingUpUids();
20190    }
20191
20192    // A backup agent has just come up
20193    public void backupAgentCreated(String agentPackageName, IBinder agent) {
20194        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
20195                + " = " + agent);
20196
20197        synchronized(this) {
20198            if (!agentPackageName.equals(mBackupAppName)) {
20199                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
20200                return;
20201            }
20202        }
20203
20204        long oldIdent = Binder.clearCallingIdentity();
20205        try {
20206            IBackupManager bm = IBackupManager.Stub.asInterface(
20207                    ServiceManager.getService(Context.BACKUP_SERVICE));
20208            bm.agentConnected(agentPackageName, agent);
20209        } catch (RemoteException e) {
20210            // can't happen; the backup manager service is local
20211        } catch (Exception e) {
20212            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
20213            e.printStackTrace();
20214        } finally {
20215            Binder.restoreCallingIdentity(oldIdent);
20216        }
20217    }
20218
20219    // done with this agent
20220    public void unbindBackupAgent(ApplicationInfo appInfo) {
20221        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
20222        if (appInfo == null) {
20223            Slog.w(TAG, "unbind backup agent for null app");
20224            return;
20225        }
20226
20227        int oldBackupUid;
20228
20229        synchronized(this) {
20230            try {
20231                if (mBackupAppName == null) {
20232                    Slog.w(TAG, "Unbinding backup agent with no active backup");
20233                    return;
20234                }
20235
20236                if (!mBackupAppName.equals(appInfo.packageName)) {
20237                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
20238                    return;
20239                }
20240
20241                // Not backing this app up any more; reset its OOM adjustment
20242                final ProcessRecord proc = mBackupTarget.app;
20243                updateOomAdjLocked(proc, true);
20244                proc.inFullBackup = false;
20245
20246                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20247
20248                // If the app crashed during backup, 'thread' will be null here
20249                if (proc.thread != null) {
20250                    try {
20251                        proc.thread.scheduleDestroyBackupAgent(appInfo,
20252                                compatibilityInfoForPackageLocked(appInfo));
20253                    } catch (Exception e) {
20254                        Slog.e(TAG, "Exception when unbinding backup agent:");
20255                        e.printStackTrace();
20256                    }
20257                }
20258            } finally {
20259                mBackupTarget = null;
20260                mBackupAppName = null;
20261            }
20262        }
20263
20264        if (oldBackupUid != -1) {
20265            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20266            js.removeBackingUpUid(oldBackupUid);
20267        }
20268    }
20269
20270    // =========================================================
20271    // BROADCASTS
20272    // =========================================================
20273
20274    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
20275        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
20276            return false;
20277        }
20278        // Easy case -- we have the app's ProcessRecord.
20279        if (record != null) {
20280            return record.info.isInstantApp();
20281        }
20282        // Otherwise check with PackageManager.
20283        if (callerPackage == null) {
20284            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
20285            throw new IllegalArgumentException("Calling application did not provide package name");
20286        }
20287        mAppOpsService.checkPackage(uid, callerPackage);
20288        try {
20289            IPackageManager pm = AppGlobals.getPackageManager();
20290            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
20291        } catch (RemoteException e) {
20292            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
20293            return true;
20294        }
20295    }
20296
20297    boolean isPendingBroadcastProcessLocked(int pid) {
20298        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20299                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
20300    }
20301
20302    void skipPendingBroadcastLocked(int pid) {
20303            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
20304            for (BroadcastQueue queue : mBroadcastQueues) {
20305                queue.skipPendingBroadcastLocked(pid);
20306            }
20307    }
20308
20309    // The app just attached; send any pending broadcasts that it should receive
20310    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
20311        boolean didSomething = false;
20312        for (BroadcastQueue queue : mBroadcastQueues) {
20313            didSomething |= queue.sendPendingBroadcastsLocked(app);
20314        }
20315        return didSomething;
20316    }
20317
20318    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20319            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
20320            int flags) {
20321        enforceNotIsolatedCaller("registerReceiver");
20322        ArrayList<Intent> stickyIntents = null;
20323        ProcessRecord callerApp = null;
20324        final boolean visibleToInstantApps
20325                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
20326        int callingUid;
20327        int callingPid;
20328        boolean instantApp;
20329        synchronized(this) {
20330            if (caller != null) {
20331                callerApp = getRecordForAppLocked(caller);
20332                if (callerApp == null) {
20333                    throw new SecurityException(
20334                            "Unable to find app for caller " + caller
20335                            + " (pid=" + Binder.getCallingPid()
20336                            + ") when registering receiver " + receiver);
20337                }
20338                if (callerApp.info.uid != SYSTEM_UID &&
20339                        !callerApp.pkgList.containsKey(callerPackage) &&
20340                        !"android".equals(callerPackage)) {
20341                    throw new SecurityException("Given caller package " + callerPackage
20342                            + " is not running in process " + callerApp);
20343                }
20344                callingUid = callerApp.info.uid;
20345                callingPid = callerApp.pid;
20346            } else {
20347                callerPackage = null;
20348                callingUid = Binder.getCallingUid();
20349                callingPid = Binder.getCallingPid();
20350            }
20351
20352            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20353            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20354                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
20355
20356            Iterator<String> actions = filter.actionsIterator();
20357            if (actions == null) {
20358                ArrayList<String> noAction = new ArrayList<String>(1);
20359                noAction.add(null);
20360                actions = noAction.iterator();
20361            }
20362
20363            // Collect stickies of users
20364            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
20365            while (actions.hasNext()) {
20366                String action = actions.next();
20367                for (int id : userIds) {
20368                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
20369                    if (stickies != null) {
20370                        ArrayList<Intent> intents = stickies.get(action);
20371                        if (intents != null) {
20372                            if (stickyIntents == null) {
20373                                stickyIntents = new ArrayList<Intent>();
20374                            }
20375                            stickyIntents.addAll(intents);
20376                        }
20377                    }
20378                }
20379            }
20380        }
20381
20382        ArrayList<Intent> allSticky = null;
20383        if (stickyIntents != null) {
20384            final ContentResolver resolver = mContext.getContentResolver();
20385            // Look for any matching sticky broadcasts...
20386            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
20387                Intent intent = stickyIntents.get(i);
20388                // Don't provided intents that aren't available to instant apps.
20389                if (instantApp &&
20390                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
20391                    continue;
20392                }
20393                // If intent has scheme "content", it will need to acccess
20394                // provider that needs to lock mProviderMap in ActivityThread
20395                // and also it may need to wait application response, so we
20396                // cannot lock ActivityManagerService here.
20397                if (filter.match(resolver, intent, true, TAG) >= 0) {
20398                    if (allSticky == null) {
20399                        allSticky = new ArrayList<Intent>();
20400                    }
20401                    allSticky.add(intent);
20402                }
20403            }
20404        }
20405
20406        // The first sticky in the list is returned directly back to the client.
20407        Intent sticky = allSticky != null ? allSticky.get(0) : null;
20408        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
20409        if (receiver == null) {
20410            return sticky;
20411        }
20412
20413        synchronized (this) {
20414            if (callerApp != null && (callerApp.thread == null
20415                    || callerApp.thread.asBinder() != caller.asBinder())) {
20416                // Original caller already died
20417                return null;
20418            }
20419            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20420            if (rl == null) {
20421                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
20422                        userId, receiver);
20423                if (rl.app != null) {
20424                    rl.app.receivers.add(rl);
20425                } else {
20426                    try {
20427                        receiver.asBinder().linkToDeath(rl, 0);
20428                    } catch (RemoteException e) {
20429                        return sticky;
20430                    }
20431                    rl.linkedToDeath = true;
20432                }
20433                mRegisteredReceivers.put(receiver.asBinder(), rl);
20434            } else if (rl.uid != callingUid) {
20435                throw new IllegalArgumentException(
20436                        "Receiver requested to register for uid " + callingUid
20437                        + " was previously registered for uid " + rl.uid
20438                        + " callerPackage is " + callerPackage);
20439            } else if (rl.pid != callingPid) {
20440                throw new IllegalArgumentException(
20441                        "Receiver requested to register for pid " + callingPid
20442                        + " was previously registered for pid " + rl.pid
20443                        + " callerPackage is " + callerPackage);
20444            } else if (rl.userId != userId) {
20445                throw new IllegalArgumentException(
20446                        "Receiver requested to register for user " + userId
20447                        + " was previously registered for user " + rl.userId
20448                        + " callerPackage is " + callerPackage);
20449            }
20450            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
20451                    permission, callingUid, userId, instantApp, visibleToInstantApps);
20452            rl.add(bf);
20453            if (!bf.debugCheck()) {
20454                Slog.w(TAG, "==> For Dynamic broadcast");
20455            }
20456            mReceiverResolver.addFilter(bf);
20457
20458            // Enqueue broadcasts for all existing stickies that match
20459            // this filter.
20460            if (allSticky != null) {
20461                ArrayList receivers = new ArrayList();
20462                receivers.add(bf);
20463
20464                final int stickyCount = allSticky.size();
20465                for (int i = 0; i < stickyCount; i++) {
20466                    Intent intent = allSticky.get(i);
20467                    BroadcastQueue queue = broadcastQueueForIntent(intent);
20468                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
20469                            null, -1, -1, false, null, null, OP_NONE, null, receivers,
20470                            null, 0, null, null, false, true, true, -1);
20471                    queue.enqueueParallelBroadcastLocked(r);
20472                    queue.scheduleBroadcastsLocked();
20473                }
20474            }
20475
20476            return sticky;
20477        }
20478    }
20479
20480    public void unregisterReceiver(IIntentReceiver receiver) {
20481        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
20482
20483        final long origId = Binder.clearCallingIdentity();
20484        try {
20485            boolean doTrim = false;
20486
20487            synchronized(this) {
20488                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20489                if (rl != null) {
20490                    final BroadcastRecord r = rl.curBroadcast;
20491                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
20492                        final boolean doNext = r.queue.finishReceiverLocked(
20493                                r, r.resultCode, r.resultData, r.resultExtras,
20494                                r.resultAbort, false);
20495                        if (doNext) {
20496                            doTrim = true;
20497                            r.queue.processNextBroadcast(false);
20498                        }
20499                    }
20500
20501                    if (rl.app != null) {
20502                        rl.app.receivers.remove(rl);
20503                    }
20504                    removeReceiverLocked(rl);
20505                    if (rl.linkedToDeath) {
20506                        rl.linkedToDeath = false;
20507                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
20508                    }
20509                }
20510            }
20511
20512            // If we actually concluded any broadcasts, we might now be able
20513            // to trim the recipients' apps from our working set
20514            if (doTrim) {
20515                trimApplications();
20516                return;
20517            }
20518
20519        } finally {
20520            Binder.restoreCallingIdentity(origId);
20521        }
20522    }
20523
20524    void removeReceiverLocked(ReceiverList rl) {
20525        mRegisteredReceivers.remove(rl.receiver.asBinder());
20526        for (int i = rl.size() - 1; i >= 0; i--) {
20527            mReceiverResolver.removeFilter(rl.get(i));
20528        }
20529    }
20530
20531    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
20532        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20533            ProcessRecord r = mLruProcesses.get(i);
20534            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
20535                try {
20536                    r.thread.dispatchPackageBroadcast(cmd, packages);
20537                } catch (RemoteException ex) {
20538                }
20539            }
20540        }
20541    }
20542
20543    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
20544            int callingUid, int[] users) {
20545        // TODO: come back and remove this assumption to triage all broadcasts
20546        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
20547
20548        List<ResolveInfo> receivers = null;
20549        try {
20550            HashSet<ComponentName> singleUserReceivers = null;
20551            boolean scannedFirstReceivers = false;
20552            for (int user : users) {
20553                // Skip users that have Shell restrictions, with exception of always permitted
20554                // Shell broadcasts
20555                if (callingUid == SHELL_UID
20556                        && mUserController.hasUserRestriction(
20557                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
20558                        && !isPermittedShellBroadcast(intent)) {
20559                    continue;
20560                }
20561                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
20562                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
20563                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
20564                    // If this is not the system user, we need to check for
20565                    // any receivers that should be filtered out.
20566                    for (int i=0; i<newReceivers.size(); i++) {
20567                        ResolveInfo ri = newReceivers.get(i);
20568                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
20569                            newReceivers.remove(i);
20570                            i--;
20571                        }
20572                    }
20573                }
20574                if (newReceivers != null && newReceivers.size() == 0) {
20575                    newReceivers = null;
20576                }
20577                if (receivers == null) {
20578                    receivers = newReceivers;
20579                } else if (newReceivers != null) {
20580                    // We need to concatenate the additional receivers
20581                    // found with what we have do far.  This would be easy,
20582                    // but we also need to de-dup any receivers that are
20583                    // singleUser.
20584                    if (!scannedFirstReceivers) {
20585                        // Collect any single user receivers we had already retrieved.
20586                        scannedFirstReceivers = true;
20587                        for (int i=0; i<receivers.size(); i++) {
20588                            ResolveInfo ri = receivers.get(i);
20589                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20590                                ComponentName cn = new ComponentName(
20591                                        ri.activityInfo.packageName, ri.activityInfo.name);
20592                                if (singleUserReceivers == null) {
20593                                    singleUserReceivers = new HashSet<ComponentName>();
20594                                }
20595                                singleUserReceivers.add(cn);
20596                            }
20597                        }
20598                    }
20599                    // Add the new results to the existing results, tracking
20600                    // and de-dupping single user receivers.
20601                    for (int i=0; i<newReceivers.size(); i++) {
20602                        ResolveInfo ri = newReceivers.get(i);
20603                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20604                            ComponentName cn = new ComponentName(
20605                                    ri.activityInfo.packageName, ri.activityInfo.name);
20606                            if (singleUserReceivers == null) {
20607                                singleUserReceivers = new HashSet<ComponentName>();
20608                            }
20609                            if (!singleUserReceivers.contains(cn)) {
20610                                singleUserReceivers.add(cn);
20611                                receivers.add(ri);
20612                            }
20613                        } else {
20614                            receivers.add(ri);
20615                        }
20616                    }
20617                }
20618            }
20619        } catch (RemoteException ex) {
20620            // pm is in same process, this will never happen.
20621        }
20622        return receivers;
20623    }
20624
20625    private boolean isPermittedShellBroadcast(Intent intent) {
20626        // remote bugreport should always be allowed to be taken
20627        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
20628    }
20629
20630    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
20631            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
20632        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
20633            // Don't yell about broadcasts sent via shell
20634            return;
20635        }
20636
20637        final String action = intent.getAction();
20638        if (isProtectedBroadcast
20639                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
20640                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
20641                || Intent.ACTION_MEDIA_BUTTON.equals(action)
20642                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
20643                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
20644                || Intent.ACTION_MASTER_CLEAR.equals(action)
20645                || Intent.ACTION_FACTORY_RESET.equals(action)
20646                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20647                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
20648                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
20649                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
20650                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
20651                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
20652                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
20653            // Broadcast is either protected, or it's a public action that
20654            // we've relaxed, so it's fine for system internals to send.
20655            return;
20656        }
20657
20658        // This broadcast may be a problem...  but there are often system components that
20659        // want to send an internal broadcast to themselves, which is annoying to have to
20660        // explicitly list each action as a protected broadcast, so we will check for that
20661        // one safe case and allow it: an explicit broadcast, only being received by something
20662        // that has protected itself.
20663        if (receivers != null && receivers.size() > 0
20664                && (intent.getPackage() != null || intent.getComponent() != null)) {
20665            boolean allProtected = true;
20666            for (int i = receivers.size()-1; i >= 0; i--) {
20667                Object target = receivers.get(i);
20668                if (target instanceof ResolveInfo) {
20669                    ResolveInfo ri = (ResolveInfo)target;
20670                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
20671                        allProtected = false;
20672                        break;
20673                    }
20674                } else {
20675                    BroadcastFilter bf = (BroadcastFilter)target;
20676                    if (bf.requiredPermission == null) {
20677                        allProtected = false;
20678                        break;
20679                    }
20680                }
20681            }
20682            if (allProtected) {
20683                // All safe!
20684                return;
20685            }
20686        }
20687
20688        // The vast majority of broadcasts sent from system internals
20689        // should be protected to avoid security holes, so yell loudly
20690        // to ensure we examine these cases.
20691        if (callerApp != null) {
20692            Log.wtf(TAG, "Sending non-protected broadcast " + action
20693                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
20694                    new Throwable());
20695        } else {
20696            Log.wtf(TAG, "Sending non-protected broadcast " + action
20697                            + " from system uid " + UserHandle.formatUid(callingUid)
20698                            + " pkg " + callerPackage,
20699                    new Throwable());
20700        }
20701    }
20702
20703    @GuardedBy("this")
20704    final int broadcastIntentLocked(ProcessRecord callerApp,
20705            String callerPackage, Intent intent, String resolvedType,
20706            IIntentReceiver resultTo, int resultCode, String resultData,
20707            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
20708            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
20709        intent = new Intent(intent);
20710
20711        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
20712        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
20713        if (callerInstantApp) {
20714            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20715        }
20716
20717        // By default broadcasts do not go to stopped apps.
20718        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
20719
20720        // If we have not finished booting, don't allow this to launch new processes.
20721        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
20722            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20723        }
20724
20725        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
20726                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
20727                + " ordered=" + ordered + " userid=" + userId);
20728        if ((resultTo != null) && !ordered) {
20729            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
20730        }
20731
20732        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20733                ALLOW_NON_FULL, "broadcast", callerPackage);
20734
20735        // Make sure that the user who is receiving this broadcast or its parent is running.
20736        // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
20737        if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
20738            if ((callingUid != SYSTEM_UID
20739                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
20740                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
20741                Slog.w(TAG, "Skipping broadcast of " + intent
20742                        + ": user " + userId + " and its parent (if any) are stopped");
20743                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
20744            }
20745        }
20746
20747        BroadcastOptions brOptions = null;
20748        if (bOptions != null) {
20749            brOptions = new BroadcastOptions(bOptions);
20750            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
20751                // See if the caller is allowed to do this.  Note we are checking against
20752                // the actual real caller (not whoever provided the operation as say a
20753                // PendingIntent), because that who is actually supplied the arguments.
20754                if (checkComponentPermission(
20755                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
20756                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
20757                        != PackageManager.PERMISSION_GRANTED) {
20758                    String msg = "Permission Denial: " + intent.getAction()
20759                            + " broadcast from " + callerPackage + " (pid=" + callingPid
20760                            + ", uid=" + callingUid + ")"
20761                            + " requires "
20762                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
20763                    Slog.w(TAG, msg);
20764                    throw new SecurityException(msg);
20765                }
20766            }
20767        }
20768
20769        // Verify that protected broadcasts are only being sent by system code,
20770        // and that system code is only sending protected broadcasts.
20771        final String action = intent.getAction();
20772        final boolean isProtectedBroadcast;
20773        try {
20774            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
20775        } catch (RemoteException e) {
20776            Slog.w(TAG, "Remote exception", e);
20777            return ActivityManager.BROADCAST_SUCCESS;
20778        }
20779
20780        final boolean isCallerSystem;
20781        switch (UserHandle.getAppId(callingUid)) {
20782            case ROOT_UID:
20783            case SYSTEM_UID:
20784            case PHONE_UID:
20785            case BLUETOOTH_UID:
20786            case NFC_UID:
20787            case SE_UID:
20788                isCallerSystem = true;
20789                break;
20790            default:
20791                isCallerSystem = (callerApp != null) && callerApp.persistent;
20792                break;
20793        }
20794
20795        // First line security check before anything else: stop non-system apps from
20796        // sending protected broadcasts.
20797        if (!isCallerSystem) {
20798            if (isProtectedBroadcast) {
20799                String msg = "Permission Denial: not allowed to send broadcast "
20800                        + action + " from pid="
20801                        + callingPid + ", uid=" + callingUid;
20802                Slog.w(TAG, msg);
20803                throw new SecurityException(msg);
20804
20805            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20806                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
20807                // Special case for compatibility: we don't want apps to send this,
20808                // but historically it has not been protected and apps may be using it
20809                // to poke their own app widget.  So, instead of making it protected,
20810                // just limit it to the caller.
20811                if (callerPackage == null) {
20812                    String msg = "Permission Denial: not allowed to send broadcast "
20813                            + action + " from unknown caller.";
20814                    Slog.w(TAG, msg);
20815                    throw new SecurityException(msg);
20816                } else if (intent.getComponent() != null) {
20817                    // They are good enough to send to an explicit component...  verify
20818                    // it is being sent to the calling app.
20819                    if (!intent.getComponent().getPackageName().equals(
20820                            callerPackage)) {
20821                        String msg = "Permission Denial: not allowed to send broadcast "
20822                                + action + " to "
20823                                + intent.getComponent().getPackageName() + " from "
20824                                + callerPackage;
20825                        Slog.w(TAG, msg);
20826                        throw new SecurityException(msg);
20827                    }
20828                } else {
20829                    // Limit broadcast to their own package.
20830                    intent.setPackage(callerPackage);
20831                }
20832            }
20833        }
20834
20835        if (action != null) {
20836            if (getBackgroundLaunchBroadcasts().contains(action)) {
20837                if (DEBUG_BACKGROUND_CHECK) {
20838                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
20839                }
20840                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
20841            }
20842
20843            switch (action) {
20844                case Intent.ACTION_UID_REMOVED:
20845                case Intent.ACTION_PACKAGE_REMOVED:
20846                case Intent.ACTION_PACKAGE_CHANGED:
20847                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
20848                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
20849                case Intent.ACTION_PACKAGES_SUSPENDED:
20850                case Intent.ACTION_PACKAGES_UNSUSPENDED:
20851                    // Handle special intents: if this broadcast is from the package
20852                    // manager about a package being removed, we need to remove all of
20853                    // its activities from the history stack.
20854                    if (checkComponentPermission(
20855                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
20856                            callingPid, callingUid, -1, true)
20857                            != PackageManager.PERMISSION_GRANTED) {
20858                        String msg = "Permission Denial: " + intent.getAction()
20859                                + " broadcast from " + callerPackage + " (pid=" + callingPid
20860                                + ", uid=" + callingUid + ")"
20861                                + " requires "
20862                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
20863                        Slog.w(TAG, msg);
20864                        throw new SecurityException(msg);
20865                    }
20866                    switch (action) {
20867                        case Intent.ACTION_UID_REMOVED:
20868                            final int uid = getUidFromIntent(intent);
20869                            if (uid >= 0) {
20870                                mBatteryStatsService.removeUid(uid);
20871                                mAppOpsService.uidRemoved(uid);
20872                            }
20873                            break;
20874                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
20875                            // If resources are unavailable just force stop all those packages
20876                            // and flush the attribute cache as well.
20877                            String list[] =
20878                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
20879                            if (list != null && list.length > 0) {
20880                                for (int i = 0; i < list.length; i++) {
20881                                    forceStopPackageLocked(list[i], -1, false, true, true,
20882                                            false, false, userId, "storage unmount");
20883                                }
20884                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
20885                                sendPackageBroadcastLocked(
20886                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
20887                                        list, userId);
20888                            }
20889                            break;
20890                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
20891                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
20892                            break;
20893                        case Intent.ACTION_PACKAGE_REMOVED:
20894                        case Intent.ACTION_PACKAGE_CHANGED:
20895                            Uri data = intent.getData();
20896                            String ssp;
20897                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
20898                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
20899                                final boolean replacing =
20900                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
20901                                final boolean killProcess =
20902                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
20903                                final boolean fullUninstall = removed && !replacing;
20904                                if (removed) {
20905                                    if (killProcess) {
20906                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
20907                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
20908                                                false, true, true, false, fullUninstall, userId,
20909                                                removed ? "pkg removed" : "pkg changed");
20910                                    }
20911                                    final int cmd = killProcess
20912                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
20913                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
20914                                    sendPackageBroadcastLocked(cmd,
20915                                            new String[] {ssp}, userId);
20916                                    if (fullUninstall) {
20917                                        mAppOpsService.packageRemoved(
20918                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
20919
20920                                        // Remove all permissions granted from/to this package
20921                                        removeUriPermissionsForPackageLocked(ssp, userId, true,
20922                                                false);
20923
20924                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
20925
20926                                        mServices.forceStopPackageLocked(ssp, userId);
20927                                        mAppWarnings.onPackageUninstalled(ssp);
20928                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
20929                                        mBatteryStatsService.notePackageUninstalled(ssp);
20930                                    }
20931                                } else {
20932                                    if (killProcess) {
20933                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
20934                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
20935                                                userId, ProcessList.INVALID_ADJ,
20936                                                false, true, true, false, "change " + ssp);
20937                                    }
20938                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
20939                                            intent.getStringArrayExtra(
20940                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
20941                                }
20942                            }
20943                            break;
20944                        case Intent.ACTION_PACKAGES_SUSPENDED:
20945                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
20946                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
20947                                    intent.getAction());
20948                            final String[] packageNames = intent.getStringArrayExtra(
20949                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
20950                            final int userHandle = intent.getIntExtra(
20951                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
20952
20953                            synchronized(ActivityManagerService.this) {
20954                                mRecentTasks.onPackagesSuspendedChanged(
20955                                        packageNames, suspended, userHandle);
20956                            }
20957                            break;
20958                    }
20959                    break;
20960                case Intent.ACTION_PACKAGE_REPLACED:
20961                {
20962                    final Uri data = intent.getData();
20963                    final String ssp;
20964                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20965                        ApplicationInfo aInfo = null;
20966                        try {
20967                            aInfo = AppGlobals.getPackageManager()
20968                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
20969                        } catch (RemoteException ignore) {}
20970                        if (aInfo == null) {
20971                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
20972                                    + " ssp=" + ssp + " data=" + data);
20973                            return ActivityManager.BROADCAST_SUCCESS;
20974                        }
20975                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
20976                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
20977                                new String[] {ssp}, userId);
20978                    }
20979                    break;
20980                }
20981                case Intent.ACTION_PACKAGE_ADDED:
20982                {
20983                    // Special case for adding a package: by default turn on compatibility mode.
20984                    Uri data = intent.getData();
20985                    String ssp;
20986                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20987                        final boolean replacing =
20988                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
20989                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
20990
20991                        try {
20992                            ApplicationInfo ai = AppGlobals.getPackageManager().
20993                                    getApplicationInfo(ssp, 0, 0);
20994                            mBatteryStatsService.notePackageInstalled(ssp,
20995                                    ai != null ? ai.versionCode : 0);
20996                        } catch (RemoteException e) {
20997                        }
20998                    }
20999                    break;
21000                }
21001                case Intent.ACTION_PACKAGE_DATA_CLEARED:
21002                {
21003                    Uri data = intent.getData();
21004                    String ssp;
21005                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21006                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
21007                        mAppWarnings.onPackageDataCleared(ssp);
21008                    }
21009                    break;
21010                }
21011                case Intent.ACTION_TIMEZONE_CHANGED:
21012                    // If this is the time zone changed action, queue up a message that will reset
21013                    // the timezone of all currently running processes. This message will get
21014                    // queued up before the broadcast happens.
21015                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
21016                    break;
21017                case Intent.ACTION_TIME_CHANGED:
21018                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
21019                    // the tri-state value it may contain and "unknown".
21020                    // For convenience we re-use the Intent extra values.
21021                    final int NO_EXTRA_VALUE_FOUND = -1;
21022                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
21023                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
21024                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
21025                    // Only send a message if the time preference is available.
21026                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
21027                        Message updateTimePreferenceMsg =
21028                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
21029                                        timeFormatPreferenceMsgValue, 0);
21030                        mHandler.sendMessage(updateTimePreferenceMsg);
21031                    }
21032                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21033                    synchronized (stats) {
21034                        stats.noteCurrentTimeChangedLocked();
21035                    }
21036                    break;
21037                case Intent.ACTION_CLEAR_DNS_CACHE:
21038                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
21039                    break;
21040                case Proxy.PROXY_CHANGE_ACTION:
21041                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
21042                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
21043                    break;
21044                case android.hardware.Camera.ACTION_NEW_PICTURE:
21045                case android.hardware.Camera.ACTION_NEW_VIDEO:
21046                    // In N we just turned these off; in O we are turing them back on partly,
21047                    // only for registered receivers.  This will still address the main problem
21048                    // (a spam of apps waking up when a picture is taken putting significant
21049                    // memory pressure on the system at a bad point), while still allowing apps
21050                    // that are already actively running to know about this happening.
21051                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21052                    break;
21053                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
21054                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
21055                    break;
21056                case "com.android.launcher.action.INSTALL_SHORTCUT":
21057                    // As of O, we no longer support this broadcasts, even for pre-O apps.
21058                    // Apps should now be using ShortcutManager.pinRequestShortcut().
21059                    Log.w(TAG, "Broadcast " + action
21060                            + " no longer supported. It will not be delivered.");
21061                    return ActivityManager.BROADCAST_SUCCESS;
21062            }
21063
21064            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
21065                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
21066                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
21067                final int uid = getUidFromIntent(intent);
21068                if (uid != -1) {
21069                    final UidRecord uidRec = mActiveUids.get(uid);
21070                    if (uidRec != null) {
21071                        uidRec.updateHasInternetPermission();
21072                    }
21073                }
21074            }
21075        }
21076
21077        // Add to the sticky list if requested.
21078        if (sticky) {
21079            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
21080                    callingPid, callingUid)
21081                    != PackageManager.PERMISSION_GRANTED) {
21082                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
21083                        + callingPid + ", uid=" + callingUid
21084                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21085                Slog.w(TAG, msg);
21086                throw new SecurityException(msg);
21087            }
21088            if (requiredPermissions != null && requiredPermissions.length > 0) {
21089                Slog.w(TAG, "Can't broadcast sticky intent " + intent
21090                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
21091                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
21092            }
21093            if (intent.getComponent() != null) {
21094                throw new SecurityException(
21095                        "Sticky broadcasts can't target a specific component");
21096            }
21097            // We use userId directly here, since the "all" target is maintained
21098            // as a separate set of sticky broadcasts.
21099            if (userId != UserHandle.USER_ALL) {
21100                // But first, if this is not a broadcast to all users, then
21101                // make sure it doesn't conflict with an existing broadcast to
21102                // all users.
21103                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
21104                        UserHandle.USER_ALL);
21105                if (stickies != null) {
21106                    ArrayList<Intent> list = stickies.get(intent.getAction());
21107                    if (list != null) {
21108                        int N = list.size();
21109                        int i;
21110                        for (i=0; i<N; i++) {
21111                            if (intent.filterEquals(list.get(i))) {
21112                                throw new IllegalArgumentException(
21113                                        "Sticky broadcast " + intent + " for user "
21114                                        + userId + " conflicts with existing global broadcast");
21115                            }
21116                        }
21117                    }
21118                }
21119            }
21120            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21121            if (stickies == null) {
21122                stickies = new ArrayMap<>();
21123                mStickyBroadcasts.put(userId, stickies);
21124            }
21125            ArrayList<Intent> list = stickies.get(intent.getAction());
21126            if (list == null) {
21127                list = new ArrayList<>();
21128                stickies.put(intent.getAction(), list);
21129            }
21130            final int stickiesCount = list.size();
21131            int i;
21132            for (i = 0; i < stickiesCount; i++) {
21133                if (intent.filterEquals(list.get(i))) {
21134                    // This sticky already exists, replace it.
21135                    list.set(i, new Intent(intent));
21136                    break;
21137                }
21138            }
21139            if (i >= stickiesCount) {
21140                list.add(new Intent(intent));
21141            }
21142        }
21143
21144        int[] users;
21145        if (userId == UserHandle.USER_ALL) {
21146            // Caller wants broadcast to go to all started users.
21147            users = mUserController.getStartedUserArray();
21148        } else {
21149            // Caller wants broadcast to go to one specific user.
21150            users = new int[] {userId};
21151        }
21152
21153        // Figure out who all will receive this broadcast.
21154        List receivers = null;
21155        List<BroadcastFilter> registeredReceivers = null;
21156        // Need to resolve the intent to interested receivers...
21157        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
21158                 == 0) {
21159            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
21160        }
21161        if (intent.getComponent() == null) {
21162            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
21163                // Query one target user at a time, excluding shell-restricted users
21164                for (int i = 0; i < users.length; i++) {
21165                    if (mUserController.hasUserRestriction(
21166                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
21167                        continue;
21168                    }
21169                    List<BroadcastFilter> registeredReceiversForUser =
21170                            mReceiverResolver.queryIntent(intent,
21171                                    resolvedType, false /*defaultOnly*/, users[i]);
21172                    if (registeredReceivers == null) {
21173                        registeredReceivers = registeredReceiversForUser;
21174                    } else if (registeredReceiversForUser != null) {
21175                        registeredReceivers.addAll(registeredReceiversForUser);
21176                    }
21177                }
21178            } else {
21179                registeredReceivers = mReceiverResolver.queryIntent(intent,
21180                        resolvedType, false /*defaultOnly*/, userId);
21181            }
21182        }
21183
21184        final boolean replacePending =
21185                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
21186
21187        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
21188                + " replacePending=" + replacePending);
21189
21190        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
21191        if (!ordered && NR > 0) {
21192            // If we are not serializing this broadcast, then send the
21193            // registered receivers separately so they don't wait for the
21194            // components to be launched.
21195            if (isCallerSystem) {
21196                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21197                        isProtectedBroadcast, registeredReceivers);
21198            }
21199            final BroadcastQueue queue = broadcastQueueForIntent(intent);
21200            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21201                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21202                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
21203                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
21204            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
21205            final boolean replaced = replacePending
21206                    && (queue.replaceParallelBroadcastLocked(r) != null);
21207            // Note: We assume resultTo is null for non-ordered broadcasts.
21208            if (!replaced) {
21209                queue.enqueueParallelBroadcastLocked(r);
21210                queue.scheduleBroadcastsLocked();
21211            }
21212            registeredReceivers = null;
21213            NR = 0;
21214        }
21215
21216        // Merge into one list.
21217        int ir = 0;
21218        if (receivers != null) {
21219            // A special case for PACKAGE_ADDED: do not allow the package
21220            // being added to see this broadcast.  This prevents them from
21221            // using this as a back door to get run as soon as they are
21222            // installed.  Maybe in the future we want to have a special install
21223            // broadcast or such for apps, but we'd like to deliberately make
21224            // this decision.
21225            String skipPackages[] = null;
21226            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
21227                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
21228                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
21229                Uri data = intent.getData();
21230                if (data != null) {
21231                    String pkgName = data.getSchemeSpecificPart();
21232                    if (pkgName != null) {
21233                        skipPackages = new String[] { pkgName };
21234                    }
21235                }
21236            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
21237                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21238            }
21239            if (skipPackages != null && (skipPackages.length > 0)) {
21240                for (String skipPackage : skipPackages) {
21241                    if (skipPackage != null) {
21242                        int NT = receivers.size();
21243                        for (int it=0; it<NT; it++) {
21244                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
21245                            if (curt.activityInfo.packageName.equals(skipPackage)) {
21246                                receivers.remove(it);
21247                                it--;
21248                                NT--;
21249                            }
21250                        }
21251                    }
21252                }
21253            }
21254
21255            int NT = receivers != null ? receivers.size() : 0;
21256            int it = 0;
21257            ResolveInfo curt = null;
21258            BroadcastFilter curr = null;
21259            while (it < NT && ir < NR) {
21260                if (curt == null) {
21261                    curt = (ResolveInfo)receivers.get(it);
21262                }
21263                if (curr == null) {
21264                    curr = registeredReceivers.get(ir);
21265                }
21266                if (curr.getPriority() >= curt.priority) {
21267                    // Insert this broadcast record into the final list.
21268                    receivers.add(it, curr);
21269                    ir++;
21270                    curr = null;
21271                    it++;
21272                    NT++;
21273                } else {
21274                    // Skip to the next ResolveInfo in the final list.
21275                    it++;
21276                    curt = null;
21277                }
21278            }
21279        }
21280        while (ir < NR) {
21281            if (receivers == null) {
21282                receivers = new ArrayList();
21283            }
21284            receivers.add(registeredReceivers.get(ir));
21285            ir++;
21286        }
21287
21288        if (isCallerSystem) {
21289            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21290                    isProtectedBroadcast, receivers);
21291        }
21292
21293        if ((receivers != null && receivers.size() > 0)
21294                || resultTo != null) {
21295            BroadcastQueue queue = broadcastQueueForIntent(intent);
21296            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21297                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21298                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
21299                    resultData, resultExtras, ordered, sticky, false, userId);
21300
21301            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
21302                    + ": prev had " + queue.mOrderedBroadcasts.size());
21303            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
21304                    "Enqueueing broadcast " + r.intent.getAction());
21305
21306            final BroadcastRecord oldRecord =
21307                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
21308            if (oldRecord != null) {
21309                // Replaced, fire the result-to receiver.
21310                if (oldRecord.resultTo != null) {
21311                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
21312                    try {
21313                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
21314                                oldRecord.intent,
21315                                Activity.RESULT_CANCELED, null, null,
21316                                false, false, oldRecord.userId);
21317                    } catch (RemoteException e) {
21318                        Slog.w(TAG, "Failure ["
21319                                + queue.mQueueName + "] sending broadcast result of "
21320                                + intent, e);
21321
21322                    }
21323                }
21324            } else {
21325                queue.enqueueOrderedBroadcastLocked(r);
21326                queue.scheduleBroadcastsLocked();
21327            }
21328        } else {
21329            // There was nobody interested in the broadcast, but we still want to record
21330            // that it happened.
21331            if (intent.getComponent() == null && intent.getPackage() == null
21332                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21333                // This was an implicit broadcast... let's record it for posterity.
21334                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
21335            }
21336        }
21337
21338        return ActivityManager.BROADCAST_SUCCESS;
21339    }
21340
21341    /**
21342     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21343     */
21344    private int getUidFromIntent(Intent intent) {
21345        if (intent == null) {
21346            return -1;
21347        }
21348        final Bundle intentExtras = intent.getExtras();
21349        return intent.hasExtra(Intent.EXTRA_UID)
21350                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
21351    }
21352
21353    final void rotateBroadcastStatsIfNeededLocked() {
21354        final long now = SystemClock.elapsedRealtime();
21355        if (mCurBroadcastStats == null ||
21356                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
21357            mLastBroadcastStats = mCurBroadcastStats;
21358            if (mLastBroadcastStats != null) {
21359                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
21360                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
21361            }
21362            mCurBroadcastStats = new BroadcastStats();
21363        }
21364    }
21365
21366    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
21367            int skipCount, long dispatchTime) {
21368        rotateBroadcastStatsIfNeededLocked();
21369        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
21370    }
21371
21372    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21373        rotateBroadcastStatsIfNeededLocked();
21374        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
21375    }
21376
21377    final Intent verifyBroadcastLocked(Intent intent) {
21378        // Refuse possible leaked file descriptors
21379        if (intent != null && intent.hasFileDescriptors() == true) {
21380            throw new IllegalArgumentException("File descriptors passed in Intent");
21381        }
21382
21383        int flags = intent.getFlags();
21384
21385        if (!mProcessesReady) {
21386            // if the caller really truly claims to know what they're doing, go
21387            // ahead and allow the broadcast without launching any receivers
21388            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
21389                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
21390            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21391                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
21392                        + " before boot completion");
21393                throw new IllegalStateException("Cannot broadcast before boot completed");
21394            }
21395        }
21396
21397        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
21398            throw new IllegalArgumentException(
21399                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
21400        }
21401
21402        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21403            switch (Binder.getCallingUid()) {
21404                case ROOT_UID:
21405                case SHELL_UID:
21406                    break;
21407                default:
21408                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
21409                            + Binder.getCallingUid());
21410                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
21411                    break;
21412            }
21413        }
21414
21415        return intent;
21416    }
21417
21418    public final int broadcastIntent(IApplicationThread caller,
21419            Intent intent, String resolvedType, IIntentReceiver resultTo,
21420            int resultCode, String resultData, Bundle resultExtras,
21421            String[] requiredPermissions, int appOp, Bundle bOptions,
21422            boolean serialized, boolean sticky, int userId) {
21423        enforceNotIsolatedCaller("broadcastIntent");
21424        synchronized(this) {
21425            intent = verifyBroadcastLocked(intent);
21426
21427            final ProcessRecord callerApp = getRecordForAppLocked(caller);
21428            final int callingPid = Binder.getCallingPid();
21429            final int callingUid = Binder.getCallingUid();
21430            final long origId = Binder.clearCallingIdentity();
21431            int res = broadcastIntentLocked(callerApp,
21432                    callerApp != null ? callerApp.info.packageName : null,
21433                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
21434                    requiredPermissions, appOp, bOptions, serialized, sticky,
21435                    callingPid, callingUid, userId);
21436            Binder.restoreCallingIdentity(origId);
21437            return res;
21438        }
21439    }
21440
21441
21442    int broadcastIntentInPackage(String packageName, int uid,
21443            Intent intent, String resolvedType, IIntentReceiver resultTo,
21444            int resultCode, String resultData, Bundle resultExtras,
21445            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
21446            int userId) {
21447        synchronized(this) {
21448            intent = verifyBroadcastLocked(intent);
21449
21450            final long origId = Binder.clearCallingIdentity();
21451            String[] requiredPermissions = requiredPermission == null ? null
21452                    : new String[] {requiredPermission};
21453            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
21454                    resultTo, resultCode, resultData, resultExtras,
21455                    requiredPermissions, OP_NONE, bOptions, serialized,
21456                    sticky, -1, uid, userId);
21457            Binder.restoreCallingIdentity(origId);
21458            return res;
21459        }
21460    }
21461
21462    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
21463        // Refuse possible leaked file descriptors
21464        if (intent != null && intent.hasFileDescriptors() == true) {
21465            throw new IllegalArgumentException("File descriptors passed in Intent");
21466        }
21467
21468        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21469                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
21470
21471        synchronized(this) {
21472            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
21473                    != PackageManager.PERMISSION_GRANTED) {
21474                String msg = "Permission Denial: unbroadcastIntent() from pid="
21475                        + Binder.getCallingPid()
21476                        + ", uid=" + Binder.getCallingUid()
21477                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21478                Slog.w(TAG, msg);
21479                throw new SecurityException(msg);
21480            }
21481            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21482            if (stickies != null) {
21483                ArrayList<Intent> list = stickies.get(intent.getAction());
21484                if (list != null) {
21485                    int N = list.size();
21486                    int i;
21487                    for (i=0; i<N; i++) {
21488                        if (intent.filterEquals(list.get(i))) {
21489                            list.remove(i);
21490                            break;
21491                        }
21492                    }
21493                    if (list.size() <= 0) {
21494                        stickies.remove(intent.getAction());
21495                    }
21496                }
21497                if (stickies.size() <= 0) {
21498                    mStickyBroadcasts.remove(userId);
21499                }
21500            }
21501        }
21502    }
21503
21504    void backgroundServicesFinishedLocked(int userId) {
21505        for (BroadcastQueue queue : mBroadcastQueues) {
21506            queue.backgroundServicesFinishedLocked(userId);
21507        }
21508    }
21509
21510    public void finishReceiver(IBinder who, int resultCode, String resultData,
21511            Bundle resultExtras, boolean resultAbort, int flags) {
21512        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
21513
21514        // Refuse possible leaked file descriptors
21515        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
21516            throw new IllegalArgumentException("File descriptors passed in Bundle");
21517        }
21518
21519        final long origId = Binder.clearCallingIdentity();
21520        try {
21521            boolean doNext = false;
21522            BroadcastRecord r;
21523
21524            synchronized(this) {
21525                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
21526                        ? mFgBroadcastQueue : mBgBroadcastQueue;
21527                r = queue.getMatchingOrderedReceiver(who);
21528                if (r != null) {
21529                    doNext = r.queue.finishReceiverLocked(r, resultCode,
21530                        resultData, resultExtras, resultAbort, true);
21531                }
21532            }
21533
21534            if (doNext) {
21535                r.queue.processNextBroadcast(false);
21536            }
21537            trimApplications();
21538        } finally {
21539            Binder.restoreCallingIdentity(origId);
21540        }
21541    }
21542
21543    // =========================================================
21544    // INSTRUMENTATION
21545    // =========================================================
21546
21547    public boolean startInstrumentation(ComponentName className,
21548            String profileFile, int flags, Bundle arguments,
21549            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
21550            int userId, String abiOverride) {
21551        enforceNotIsolatedCaller("startInstrumentation");
21552        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21553                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
21554        // Refuse possible leaked file descriptors
21555        if (arguments != null && arguments.hasFileDescriptors()) {
21556            throw new IllegalArgumentException("File descriptors passed in Bundle");
21557        }
21558
21559        synchronized(this) {
21560            InstrumentationInfo ii = null;
21561            ApplicationInfo ai = null;
21562            try {
21563                ii = mContext.getPackageManager().getInstrumentationInfo(
21564                    className, STOCK_PM_FLAGS);
21565                ai = AppGlobals.getPackageManager().getApplicationInfo(
21566                        ii.targetPackage, STOCK_PM_FLAGS, userId);
21567            } catch (PackageManager.NameNotFoundException e) {
21568            } catch (RemoteException e) {
21569            }
21570            if (ii == null) {
21571                reportStartInstrumentationFailureLocked(watcher, className,
21572                        "Unable to find instrumentation info for: " + className);
21573                return false;
21574            }
21575            if (ai == null) {
21576                reportStartInstrumentationFailureLocked(watcher, className,
21577                        "Unable to find instrumentation target package: " + ii.targetPackage);
21578                return false;
21579            }
21580            if (!ai.hasCode()) {
21581                reportStartInstrumentationFailureLocked(watcher, className,
21582                        "Instrumentation target has no code: " + ii.targetPackage);
21583                return false;
21584            }
21585
21586            int match = mContext.getPackageManager().checkSignatures(
21587                    ii.targetPackage, ii.packageName);
21588            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
21589                String msg = "Permission Denial: starting instrumentation "
21590                        + className + " from pid="
21591                        + Binder.getCallingPid()
21592                        + ", uid=" + Binder.getCallingPid()
21593                        + " not allowed because package " + ii.packageName
21594                        + " does not have a signature matching the target "
21595                        + ii.targetPackage;
21596                reportStartInstrumentationFailureLocked(watcher, className, msg);
21597                throw new SecurityException(msg);
21598            }
21599
21600            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
21601            activeInstr.mClass = className;
21602            String defProcess = ai.processName;;
21603            if (ii.targetProcesses == null) {
21604                activeInstr.mTargetProcesses = new String[]{ai.processName};
21605            } else if (ii.targetProcesses.equals("*")) {
21606                activeInstr.mTargetProcesses = new String[0];
21607            } else {
21608                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
21609                defProcess = activeInstr.mTargetProcesses[0];
21610            }
21611            activeInstr.mTargetInfo = ai;
21612            activeInstr.mProfileFile = profileFile;
21613            activeInstr.mArguments = arguments;
21614            activeInstr.mWatcher = watcher;
21615            activeInstr.mUiAutomationConnection = uiAutomationConnection;
21616            activeInstr.mResultClass = className;
21617
21618            final long origId = Binder.clearCallingIdentity();
21619            // Instrumentation can kill and relaunch even persistent processes
21620            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
21621                    "start instr");
21622            // Inform usage stats to make the target package active
21623            if (mUsageStatsService != null) {
21624                mUsageStatsService.reportEvent(ii.targetPackage, userId,
21625                        UsageEvents.Event.SYSTEM_INTERACTION);
21626            }
21627            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
21628            app.instr = activeInstr;
21629            activeInstr.mFinished = false;
21630            activeInstr.mRunningProcesses.add(app);
21631            if (!mActiveInstrumentation.contains(activeInstr)) {
21632                mActiveInstrumentation.add(activeInstr);
21633            }
21634            Binder.restoreCallingIdentity(origId);
21635        }
21636
21637        return true;
21638    }
21639
21640    /**
21641     * Report errors that occur while attempting to start Instrumentation.  Always writes the
21642     * error to the logs, but if somebody is watching, send the report there too.  This enables
21643     * the "am" command to report errors with more information.
21644     *
21645     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
21646     * @param cn The component name of the instrumentation.
21647     * @param report The error report.
21648     */
21649    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
21650            ComponentName cn, String report) {
21651        Slog.w(TAG, report);
21652        if (watcher != null) {
21653            Bundle results = new Bundle();
21654            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
21655            results.putString("Error", report);
21656            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
21657        }
21658    }
21659
21660    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
21661        if (app.instr == null) {
21662            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21663            return;
21664        }
21665
21666        if (!app.instr.mFinished && results != null) {
21667            if (app.instr.mCurResults == null) {
21668                app.instr.mCurResults = new Bundle(results);
21669            } else {
21670                app.instr.mCurResults.putAll(results);
21671            }
21672        }
21673    }
21674
21675    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
21676        int userId = UserHandle.getCallingUserId();
21677        // Refuse possible leaked file descriptors
21678        if (results != null && results.hasFileDescriptors()) {
21679            throw new IllegalArgumentException("File descriptors passed in Intent");
21680        }
21681
21682        synchronized(this) {
21683            ProcessRecord app = getRecordForAppLocked(target);
21684            if (app == null) {
21685                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
21686                return;
21687            }
21688            final long origId = Binder.clearCallingIdentity();
21689            addInstrumentationResultsLocked(app, results);
21690            Binder.restoreCallingIdentity(origId);
21691        }
21692    }
21693
21694    @GuardedBy("this")
21695    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
21696        if (app.instr == null) {
21697            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21698            return;
21699        }
21700
21701        if (!app.instr.mFinished) {
21702            if (app.instr.mWatcher != null) {
21703                Bundle finalResults = app.instr.mCurResults;
21704                if (finalResults != null) {
21705                    if (app.instr.mCurResults != null && results != null) {
21706                        finalResults.putAll(results);
21707                    }
21708                } else {
21709                    finalResults = results;
21710                }
21711                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
21712                        app.instr.mClass, resultCode, finalResults);
21713            }
21714
21715            // Can't call out of the system process with a lock held, so post a message.
21716            if (app.instr.mUiAutomationConnection != null) {
21717                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
21718                        app.instr.mUiAutomationConnection).sendToTarget();
21719            }
21720            app.instr.mFinished = true;
21721        }
21722
21723        app.instr.removeProcess(app);
21724        app.instr = null;
21725
21726        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
21727                "finished inst");
21728    }
21729
21730    public void finishInstrumentation(IApplicationThread target,
21731            int resultCode, Bundle results) {
21732        int userId = UserHandle.getCallingUserId();
21733        // Refuse possible leaked file descriptors
21734        if (results != null && results.hasFileDescriptors()) {
21735            throw new IllegalArgumentException("File descriptors passed in Intent");
21736        }
21737
21738        synchronized(this) {
21739            ProcessRecord app = getRecordForAppLocked(target);
21740            if (app == null) {
21741                Slog.w(TAG, "finishInstrumentation: no app for " + target);
21742                return;
21743            }
21744            final long origId = Binder.clearCallingIdentity();
21745            finishInstrumentationLocked(app, resultCode, results);
21746            Binder.restoreCallingIdentity(origId);
21747        }
21748    }
21749
21750    // =========================================================
21751    // CONFIGURATION
21752    // =========================================================
21753
21754    public ConfigurationInfo getDeviceConfigurationInfo() {
21755        ConfigurationInfo config = new ConfigurationInfo();
21756        synchronized (this) {
21757            final Configuration globalConfig = getGlobalConfiguration();
21758            config.reqTouchScreen = globalConfig.touchscreen;
21759            config.reqKeyboardType = globalConfig.keyboard;
21760            config.reqNavigation = globalConfig.navigation;
21761            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
21762                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
21763                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
21764            }
21765            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
21766                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
21767                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
21768            }
21769            config.reqGlEsVersion = GL_ES_VERSION;
21770        }
21771        return config;
21772    }
21773
21774    ActivityStack getFocusedStack() {
21775        return mStackSupervisor.getFocusedStack();
21776    }
21777
21778    @Override
21779    public StackInfo getFocusedStackInfo() throws RemoteException {
21780        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
21781        long ident = Binder.clearCallingIdentity();
21782        try {
21783            synchronized (this) {
21784                ActivityStack focusedStack = getFocusedStack();
21785                if (focusedStack != null) {
21786                    return mStackSupervisor.getStackInfo(focusedStack.mStackId);
21787                }
21788                return null;
21789            }
21790        } finally {
21791            Binder.restoreCallingIdentity(ident);
21792        }
21793    }
21794
21795    public Configuration getConfiguration() {
21796        Configuration ci;
21797        synchronized(this) {
21798            ci = new Configuration(getGlobalConfiguration());
21799            ci.userSetLocale = false;
21800        }
21801        return ci;
21802    }
21803
21804    @Override
21805    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
21806        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
21807        synchronized (this) {
21808            mSuppressResizeConfigChanges = suppress;
21809        }
21810    }
21811
21812    /**
21813     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
21814     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
21815     *       activity and clearing the task at the same time.
21816     */
21817    @Override
21818    // TODO: API should just be about changing windowing modes...
21819    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
21820        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
21821                "moveTasksToFullscreenStack()");
21822        synchronized (this) {
21823            final long origId = Binder.clearCallingIdentity();
21824            try {
21825                final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
21826                if (stack != null){
21827                    if (!stack.isActivityTypeStandardOrUndefined()) {
21828                        throw new IllegalArgumentException(
21829                                "You can't move tasks from non-standard stacks.");
21830                    }
21831                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
21832                }
21833            } finally {
21834                Binder.restoreCallingIdentity(origId);
21835            }
21836        }
21837    }
21838
21839    @Override
21840    public void updatePersistentConfiguration(Configuration values) {
21841        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
21842        enforceWriteSettingsPermission("updatePersistentConfiguration()");
21843        if (values == null) {
21844            throw new NullPointerException("Configuration must not be null");
21845        }
21846
21847        int userId = UserHandle.getCallingUserId();
21848
21849        synchronized(this) {
21850            updatePersistentConfigurationLocked(values, userId);
21851        }
21852    }
21853
21854    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
21855        final long origId = Binder.clearCallingIdentity();
21856        try {
21857            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
21858        } finally {
21859            Binder.restoreCallingIdentity(origId);
21860        }
21861    }
21862
21863    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
21864        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
21865                FONT_SCALE, 1.0f, userId);
21866
21867        synchronized (this) {
21868            if (getGlobalConfiguration().fontScale == scaleFactor) {
21869                return;
21870            }
21871
21872            final Configuration configuration
21873                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
21874            configuration.fontScale = scaleFactor;
21875            updatePersistentConfigurationLocked(configuration, userId);
21876        }
21877    }
21878
21879    private void enforceWriteSettingsPermission(String func) {
21880        int uid = Binder.getCallingUid();
21881        if (uid == ROOT_UID) {
21882            return;
21883        }
21884
21885        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
21886                Settings.getPackageNameForUid(mContext, uid), false)) {
21887            return;
21888        }
21889
21890        String msg = "Permission Denial: " + func + " from pid="
21891                + Binder.getCallingPid()
21892                + ", uid=" + uid
21893                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
21894        Slog.w(TAG, msg);
21895        throw new SecurityException(msg);
21896    }
21897
21898    @Override
21899    public boolean updateConfiguration(Configuration values) {
21900        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
21901
21902        synchronized(this) {
21903            if (values == null && mWindowManager != null) {
21904                // sentinel: fetch the current configuration from the window manager
21905                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
21906            }
21907
21908            if (mWindowManager != null) {
21909                // Update OOM levels based on display size.
21910                mProcessList.applyDisplaySize(mWindowManager);
21911            }
21912
21913            final long origId = Binder.clearCallingIdentity();
21914            try {
21915                if (values != null) {
21916                    Settings.System.clearConfiguration(values);
21917                }
21918                updateConfigurationLocked(values, null, false, false /* persistent */,
21919                        UserHandle.USER_NULL, false /* deferResume */,
21920                        mTmpUpdateConfigurationResult);
21921                return mTmpUpdateConfigurationResult.changes != 0;
21922            } finally {
21923                Binder.restoreCallingIdentity(origId);
21924            }
21925        }
21926    }
21927
21928    void updateUserConfigurationLocked() {
21929        final Configuration configuration = new Configuration(getGlobalConfiguration());
21930        final int currentUserId = mUserController.getCurrentUserId();
21931        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
21932                currentUserId, Settings.System.canWrite(mContext));
21933        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
21934                false /* persistent */, currentUserId, false /* deferResume */);
21935    }
21936
21937    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21938            boolean initLocale) {
21939        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
21940    }
21941
21942    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21943            boolean initLocale, boolean deferResume) {
21944        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
21945        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
21946                UserHandle.USER_NULL, deferResume);
21947    }
21948
21949    // To cache the list of supported system locales
21950    private String[] mSupportedSystemLocales = null;
21951
21952    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21953            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
21954        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
21955                deferResume, null /* result */);
21956    }
21957
21958    /**
21959     * Do either or both things: (1) change the current configuration, and (2)
21960     * make sure the given activity is running with the (now) current
21961     * configuration.  Returns true if the activity has been left running, or
21962     * false if <var>starting</var> is being destroyed to match the new
21963     * configuration.
21964     *
21965     * @param userId is only used when persistent parameter is set to true to persist configuration
21966     *               for that particular user
21967     */
21968    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21969            boolean initLocale, boolean persistent, int userId, boolean deferResume,
21970            UpdateConfigurationResult result) {
21971        int changes = 0;
21972        boolean kept = true;
21973
21974        if (mWindowManager != null) {
21975            mWindowManager.deferSurfaceLayout();
21976        }
21977        try {
21978            if (values != null) {
21979                changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
21980                        deferResume);
21981            }
21982
21983            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
21984        } finally {
21985            if (mWindowManager != null) {
21986                mWindowManager.continueSurfaceLayout();
21987            }
21988        }
21989
21990        if (result != null) {
21991            result.changes = changes;
21992            result.activityRelaunched = !kept;
21993        }
21994        return kept;
21995    }
21996
21997    /**
21998     * Returns true if this configuration change is interesting enough to send an
21999     * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
22000     */
22001    private static boolean isSplitConfigurationChange(int configDiff) {
22002        return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
22003    }
22004
22005    /** Update default (global) configuration and notify listeners about changes. */
22006    private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
22007            boolean persistent, int userId, boolean deferResume) {
22008        mTempConfig.setTo(getGlobalConfiguration());
22009        final int changes = mTempConfig.updateFrom(values);
22010        if (changes == 0) {
22011            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
22012            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
22013            // performDisplayOverrideConfigUpdate in order to send the new display configuration
22014            // (even if there are no actual changes) to unfreeze the window.
22015            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
22016            return 0;
22017        }
22018
22019        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
22020                "Updating global configuration to: " + values);
22021
22022        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
22023
22024        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
22025            final LocaleList locales = values.getLocales();
22026            int bestLocaleIndex = 0;
22027            if (locales.size() > 1) {
22028                if (mSupportedSystemLocales == null) {
22029                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
22030                }
22031                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
22032            }
22033            SystemProperties.set("persist.sys.locale",
22034                    locales.get(bestLocaleIndex).toLanguageTag());
22035            LocaleList.setDefault(locales, bestLocaleIndex);
22036            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
22037                    locales.get(bestLocaleIndex)));
22038        }
22039
22040        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
22041        mTempConfig.seq = mConfigurationSeq;
22042
22043        // Update stored global config and notify everyone about the change.
22044        mStackSupervisor.onConfigurationChanged(mTempConfig);
22045
22046        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
22047        // TODO(multi-display): Update UsageEvents#Event to include displayId.
22048        mUsageStatsService.reportConfigurationChange(mTempConfig,
22049                mUserController.getCurrentUserId());
22050
22051        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
22052        mShowDialogs = shouldShowDialogs(mTempConfig);
22053
22054        AttributeCache ac = AttributeCache.instance();
22055        if (ac != null) {
22056            ac.updateConfiguration(mTempConfig);
22057        }
22058
22059        // Make sure all resources in our process are updated right now, so that anyone who is going
22060        // to retrieve resource values after we return will be sure to get the new ones. This is
22061        // especially important during boot, where the first config change needs to guarantee all
22062        // resources have that config before following boot code is executed.
22063        mSystemThread.applyConfigurationToResources(mTempConfig);
22064
22065        // We need another copy of global config because we're scheduling some calls instead of
22066        // running them in place. We need to be sure that object we send will be handled unchanged.
22067        final Configuration configCopy = new Configuration(mTempConfig);
22068        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
22069            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
22070            msg.obj = configCopy;
22071            msg.arg1 = userId;
22072            mHandler.sendMessage(msg);
22073        }
22074
22075        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22076            ProcessRecord app = mLruProcesses.get(i);
22077            try {
22078                if (app.thread != null) {
22079                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
22080                            + app.processName + " new config " + configCopy);
22081                    mLifecycleManager.scheduleTransaction(app.thread,
22082                            ConfigurationChangeItem.obtain(configCopy));
22083                }
22084            } catch (Exception e) {
22085                Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
22086            }
22087        }
22088
22089        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
22090        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
22091                | Intent.FLAG_RECEIVER_FOREGROUND
22092                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22093        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22094                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22095                UserHandle.USER_ALL);
22096        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
22097            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
22098            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
22099                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
22100                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22101            if (initLocale || !mProcessesReady) {
22102                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
22103            }
22104            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22105                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22106                    UserHandle.USER_ALL);
22107        }
22108
22109        // Send a broadcast to PackageInstallers if the configuration change is interesting
22110        // for the purposes of installing additional splits.
22111        if (!initLocale && isSplitConfigurationChange(changes)) {
22112            intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
22113            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
22114                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
22115
22116            // Typically only app stores will have this permission.
22117            String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
22118            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
22119                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
22120        }
22121
22122        // Override configuration of the default display duplicates global config, so we need to
22123        // update it also. This will also notify WindowManager about changes.
22124        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
22125                DEFAULT_DISPLAY);
22126
22127        return changes;
22128    }
22129
22130    @Override
22131    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
22132        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
22133
22134        synchronized (this) {
22135            // Check if display is initialized in AM.
22136            if (!mStackSupervisor.isDisplayAdded(displayId)) {
22137                // Call might come when display is not yet added or has already been removed.
22138                if (DEBUG_CONFIGURATION) {
22139                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
22140                            + displayId);
22141                }
22142                return false;
22143            }
22144
22145            if (values == null && mWindowManager != null) {
22146                // sentinel: fetch the current configuration from the window manager
22147                values = mWindowManager.computeNewConfiguration(displayId);
22148            }
22149
22150            if (mWindowManager != null) {
22151                // Update OOM levels based on display size.
22152                mProcessList.applyDisplaySize(mWindowManager);
22153            }
22154
22155            final long origId = Binder.clearCallingIdentity();
22156            try {
22157                if (values != null) {
22158                    Settings.System.clearConfiguration(values);
22159                }
22160                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
22161                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
22162                return mTmpUpdateConfigurationResult.changes != 0;
22163            } finally {
22164                Binder.restoreCallingIdentity(origId);
22165            }
22166        }
22167    }
22168
22169    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
22170            boolean deferResume, int displayId) {
22171        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
22172                displayId, null /* result */);
22173    }
22174
22175    /**
22176     * Updates override configuration specific for the selected display. If no config is provided,
22177     * new one will be computed in WM based on current display info.
22178     */
22179    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
22180            ActivityRecord starting, boolean deferResume, int displayId,
22181            UpdateConfigurationResult result) {
22182        int changes = 0;
22183        boolean kept = true;
22184
22185        if (mWindowManager != null) {
22186            mWindowManager.deferSurfaceLayout();
22187        }
22188        try {
22189            if (values != null) {
22190                if (displayId == DEFAULT_DISPLAY) {
22191                    // Override configuration of the default display duplicates global config, so
22192                    // we're calling global config update instead for default display. It will also
22193                    // apply the correct override config.
22194                    changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
22195                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
22196                } else {
22197                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
22198                }
22199            }
22200
22201            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22202        } finally {
22203            if (mWindowManager != null) {
22204                mWindowManager.continueSurfaceLayout();
22205            }
22206        }
22207
22208        if (result != null) {
22209            result.changes = changes;
22210            result.activityRelaunched = !kept;
22211        }
22212        return kept;
22213    }
22214
22215    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
22216            int displayId) {
22217        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
22218        final int changes = mTempConfig.updateFrom(values);
22219        if (changes != 0) {
22220            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
22221                    + mTempConfig + " for displayId=" + displayId);
22222            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
22223
22224            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
22225            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
22226                mAppWarnings.onDensityChanged();
22227
22228                killAllBackgroundProcessesExcept(N,
22229                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
22230            }
22231        }
22232
22233        // Update the configuration with WM first and check if any of the stacks need to be resized
22234        // due to the configuration change. If so, resize the stacks now and do any relaunches if
22235        // necessary. This way we don't need to relaunch again afterwards in
22236        // ensureActivityConfigurationLocked().
22237        if (mWindowManager != null) {
22238            final int[] resizedStacks =
22239                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
22240            if (resizedStacks != null) {
22241                for (int stackId : resizedStacks) {
22242                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
22243                }
22244            }
22245        }
22246
22247        return changes;
22248    }
22249
22250    /** Applies latest configuration and/or visibility updates if needed. */
22251    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
22252        boolean kept = true;
22253        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
22254        // mainStack is null during startup.
22255        if (mainStack != null) {
22256            if (changes != 0 && starting == null) {
22257                // If the configuration changed, and the caller is not already
22258                // in the process of starting an activity, then find the top
22259                // activity to check if its configuration needs to change.
22260                starting = mainStack.topRunningActivityLocked();
22261            }
22262
22263            if (starting != null) {
22264                kept = starting.ensureActivityConfigurationLocked(changes,
22265                        false /* preserveWindow */);
22266                // And we need to make sure at this point that all other activities
22267                // are made visible with the correct configuration.
22268                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
22269                        !PRESERVE_WINDOWS);
22270            }
22271        }
22272
22273        return kept;
22274    }
22275
22276    /** Helper method that requests bounds from WM and applies them to stack. */
22277    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
22278        final Rect newStackBounds = new Rect();
22279        final ActivityStack stack = mStackSupervisor.getStack(stackId);
22280
22281        // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
22282        if (stack == null) {
22283            final StringWriter writer = new StringWriter();
22284            final PrintWriter printWriter = new PrintWriter(writer);
22285            mStackSupervisor.dumpDisplays(printWriter);
22286            printWriter.flush();
22287
22288            Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
22289        }
22290
22291        stack.getBoundsForNewConfiguration(newStackBounds);
22292        mStackSupervisor.resizeStackLocked(
22293                stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
22294                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
22295                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
22296    }
22297
22298    /**
22299     * Decide based on the configuration whether we should show the ANR,
22300     * crash, etc dialogs.  The idea is that if there is no affordance to
22301     * press the on-screen buttons, or the user experience would be more
22302     * greatly impacted than the crash itself, we shouldn't show the dialog.
22303     *
22304     * A thought: SystemUI might also want to get told about this, the Power
22305     * dialog / global actions also might want different behaviors.
22306     */
22307    private static boolean shouldShowDialogs(Configuration config) {
22308        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
22309                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
22310                                   && config.navigation == Configuration.NAVIGATION_NONAV);
22311        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
22312        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
22313                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
22314                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
22315                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
22316        return inputMethodExists && uiModeSupportsDialogs;
22317    }
22318
22319    @Override
22320    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
22321        synchronized (this) {
22322            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
22323            if (srec != null) {
22324                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
22325            }
22326        }
22327        return false;
22328    }
22329
22330    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22331            Intent resultData) {
22332
22333        synchronized (this) {
22334            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22335            if (r != null) {
22336                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22337            }
22338            return false;
22339        }
22340    }
22341
22342    public int getLaunchedFromUid(IBinder activityToken) {
22343        ActivityRecord srec;
22344        synchronized (this) {
22345            srec = ActivityRecord.forTokenLocked(activityToken);
22346        }
22347        if (srec == null) {
22348            return -1;
22349        }
22350        return srec.launchedFromUid;
22351    }
22352
22353    public String getLaunchedFromPackage(IBinder activityToken) {
22354        ActivityRecord srec;
22355        synchronized (this) {
22356            srec = ActivityRecord.forTokenLocked(activityToken);
22357        }
22358        if (srec == null) {
22359            return null;
22360        }
22361        return srec.launchedFromPackage;
22362    }
22363
22364    // =========================================================
22365    // LIFETIME MANAGEMENT
22366    // =========================================================
22367
22368    // Returns whether the app is receiving broadcast.
22369    // If receiving, fetch all broadcast queues which the app is
22370    // the current [or imminent] receiver on.
22371    private boolean isReceivingBroadcastLocked(ProcessRecord app,
22372            ArraySet<BroadcastQueue> receivingQueues) {
22373        final int N = app.curReceivers.size();
22374        if (N > 0) {
22375            for (int i = 0; i < N; i++) {
22376                receivingQueues.add(app.curReceivers.valueAt(i).queue);
22377            }
22378            return true;
22379        }
22380
22381        // It's not the current receiver, but it might be starting up to become one
22382        for (BroadcastQueue queue : mBroadcastQueues) {
22383            final BroadcastRecord r = queue.mPendingBroadcast;
22384            if (r != null && r.curApp == app) {
22385                // found it; report which queue it's in
22386                receivingQueues.add(queue);
22387            }
22388        }
22389
22390        return !receivingQueues.isEmpty();
22391    }
22392
22393    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
22394            int targetUid, ComponentName targetComponent, String targetProcess) {
22395        if (!mTrackingAssociations) {
22396            return null;
22397        }
22398        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22399                = mAssociations.get(targetUid);
22400        if (components == null) {
22401            components = new ArrayMap<>();
22402            mAssociations.put(targetUid, components);
22403        }
22404        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22405        if (sourceUids == null) {
22406            sourceUids = new SparseArray<>();
22407            components.put(targetComponent, sourceUids);
22408        }
22409        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22410        if (sourceProcesses == null) {
22411            sourceProcesses = new ArrayMap<>();
22412            sourceUids.put(sourceUid, sourceProcesses);
22413        }
22414        Association ass = sourceProcesses.get(sourceProcess);
22415        if (ass == null) {
22416            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
22417                    targetProcess);
22418            sourceProcesses.put(sourceProcess, ass);
22419        }
22420        ass.mCount++;
22421        ass.mNesting++;
22422        if (ass.mNesting == 1) {
22423            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
22424            ass.mLastState = sourceState;
22425        }
22426        return ass;
22427    }
22428
22429    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
22430            ComponentName targetComponent) {
22431        if (!mTrackingAssociations) {
22432            return;
22433        }
22434        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22435                = mAssociations.get(targetUid);
22436        if (components == null) {
22437            return;
22438        }
22439        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22440        if (sourceUids == null) {
22441            return;
22442        }
22443        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22444        if (sourceProcesses == null) {
22445            return;
22446        }
22447        Association ass = sourceProcesses.get(sourceProcess);
22448        if (ass == null || ass.mNesting <= 0) {
22449            return;
22450        }
22451        ass.mNesting--;
22452        if (ass.mNesting == 0) {
22453            long uptime = SystemClock.uptimeMillis();
22454            ass.mTime += uptime - ass.mStartTime;
22455            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22456                    += uptime - ass.mLastStateUptime;
22457            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
22458        }
22459    }
22460
22461    private void noteUidProcessState(final int uid, final int state) {
22462        mBatteryStatsService.noteUidProcessState(uid, state);
22463        if (mTrackingAssociations) {
22464            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
22465                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
22466                        = mAssociations.valueAt(i1);
22467                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
22468                    SparseArray<ArrayMap<String, Association>> sourceUids
22469                            = targetComponents.valueAt(i2);
22470                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
22471                    if (sourceProcesses != null) {
22472                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
22473                            Association ass = sourceProcesses.valueAt(i4);
22474                            if (ass.mNesting >= 1) {
22475                                // currently associated
22476                                long uptime = SystemClock.uptimeMillis();
22477                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22478                                        += uptime - ass.mLastStateUptime;
22479                                ass.mLastState = state;
22480                                ass.mLastStateUptime = uptime;
22481                            }
22482                        }
22483                    }
22484                }
22485            }
22486        }
22487    }
22488
22489    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
22490            boolean doingAll, long now) {
22491        if (mAdjSeq == app.adjSeq) {
22492            // This adjustment has already been computed.
22493            return app.curRawAdj;
22494        }
22495
22496        if (app.thread == null) {
22497            app.adjSeq = mAdjSeq;
22498            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22499            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22500            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
22501        }
22502
22503        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
22504        app.adjSource = null;
22505        app.adjTarget = null;
22506        app.empty = false;
22507        app.cached = false;
22508
22509        final int activitiesSize = app.activities.size();
22510
22511        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
22512            // The max adjustment doesn't allow this app to be anything
22513            // below foreground, so it is not worth doing work for it.
22514            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
22515            app.adjType = "fixed";
22516            app.adjSeq = mAdjSeq;
22517            app.curRawAdj = app.maxAdj;
22518            app.foregroundActivities = false;
22519            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22520            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
22521            // System processes can do UI, and when they do we want to have
22522            // them trim their memory after the user leaves the UI.  To
22523            // facilitate this, here we need to determine whether or not it
22524            // is currently showing UI.
22525            app.systemNoUi = true;
22526            if (app == TOP_APP) {
22527                app.systemNoUi = false;
22528                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22529                app.adjType = "pers-top-activity";
22530            } else if (app.hasTopUi) {
22531                app.systemNoUi = false;
22532                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22533                app.adjType = "pers-top-ui";
22534            } else if (activitiesSize > 0) {
22535                for (int j = 0; j < activitiesSize; j++) {
22536                    final ActivityRecord r = app.activities.get(j);
22537                    if (r.visible) {
22538                        app.systemNoUi = false;
22539                    }
22540                }
22541            }
22542            if (!app.systemNoUi) {
22543                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
22544            }
22545            return (app.curAdj=app.maxAdj);
22546        }
22547
22548        app.systemNoUi = false;
22549
22550        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
22551
22552        // Determine the importance of the process, starting with most
22553        // important to least, and assign an appropriate OOM adjustment.
22554        int adj;
22555        int schedGroup;
22556        int procState;
22557        boolean foregroundActivities = false;
22558        mTmpBroadcastQueue.clear();
22559        if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
22560            // The last app on the list is the foreground app.
22561            adj = ProcessList.FOREGROUND_APP_ADJ;
22562            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22563            app.adjType = "top-activity";
22564            foregroundActivities = true;
22565            procState = PROCESS_STATE_CUR_TOP;
22566            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22567        } else if (app.instr != null) {
22568            // Don't want to kill running instrumentation.
22569            adj = ProcessList.FOREGROUND_APP_ADJ;
22570            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22571            app.adjType = "instrumentation";
22572            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22573            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
22574        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
22575            // An app that is currently receiving a broadcast also
22576            // counts as being in the foreground for OOM killer purposes.
22577            // It's placed in a sched group based on the nature of the
22578            // broadcast as reflected by which queue it's active in.
22579            adj = ProcessList.FOREGROUND_APP_ADJ;
22580            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
22581                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22582            app.adjType = "broadcast";
22583            procState = ActivityManager.PROCESS_STATE_RECEIVER;
22584            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
22585        } else if (app.executingServices.size() > 0) {
22586            // An app that is currently executing a service callback also
22587            // counts as being in the foreground.
22588            adj = ProcessList.FOREGROUND_APP_ADJ;
22589            schedGroup = app.execServicesFg ?
22590                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22591            app.adjType = "exec-service";
22592            procState = ActivityManager.PROCESS_STATE_SERVICE;
22593            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
22594            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
22595        } else if (app == TOP_APP) {
22596            adj = ProcessList.FOREGROUND_APP_ADJ;
22597            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22598            app.adjType = "top-sleeping";
22599            foregroundActivities = true;
22600            procState = PROCESS_STATE_CUR_TOP;
22601            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22602        } else {
22603            // As far as we know the process is empty.  We may change our mind later.
22604            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22605            // At this point we don't actually know the adjustment.  Use the cached adj
22606            // value that the caller wants us to.
22607            adj = cachedAdj;
22608            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22609            app.cached = true;
22610            app.empty = true;
22611            app.adjType = "cch-empty";
22612            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
22613        }
22614
22615        // Examine all activities if not already foreground.
22616        if (!foregroundActivities && activitiesSize > 0) {
22617            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
22618            for (int j = 0; j < activitiesSize; j++) {
22619                final ActivityRecord r = app.activities.get(j);
22620                if (r.app != app) {
22621                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
22622                            + " instead of expected " + app);
22623                    if (r.app == null || (r.app.uid == app.uid)) {
22624                        // Only fix things up when they look sane
22625                        r.setProcess(app);
22626                    } else {
22627                        continue;
22628                    }
22629                }
22630                if (r.visible) {
22631                    // App has a visible activity; only upgrade adjustment.
22632                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
22633                        adj = ProcessList.VISIBLE_APP_ADJ;
22634                        app.adjType = "vis-activity";
22635                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22636                    }
22637                    if (procState > PROCESS_STATE_CUR_TOP) {
22638                        procState = PROCESS_STATE_CUR_TOP;
22639                        app.adjType = "vis-activity";
22640                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22641                    }
22642                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22643                    app.cached = false;
22644                    app.empty = false;
22645                    foregroundActivities = true;
22646                    final TaskRecord task = r.getTask();
22647                    if (task != null && minLayer > 0) {
22648                        final int layer = task.mLayerRank;
22649                        if (layer >= 0 && minLayer > layer) {
22650                            minLayer = layer;
22651                        }
22652                    }
22653                    break;
22654                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
22655                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22656                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22657                        app.adjType = "pause-activity";
22658                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22659                    }
22660                    if (procState > PROCESS_STATE_CUR_TOP) {
22661                        procState = PROCESS_STATE_CUR_TOP;
22662                        app.adjType = "pause-activity";
22663                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22664                    }
22665                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22666                    app.cached = false;
22667                    app.empty = false;
22668                    foregroundActivities = true;
22669                } else if (r.state == ActivityState.STOPPING) {
22670                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22671                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22672                        app.adjType = "stop-activity";
22673                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22674                    }
22675                    // For the process state, we will at this point consider the
22676                    // process to be cached.  It will be cached either as an activity
22677                    // or empty depending on whether the activity is finishing.  We do
22678                    // this so that we can treat the process as cached for purposes of
22679                    // memory trimming (determing current memory level, trim command to
22680                    // send to process) since there can be an arbitrary number of stopping
22681                    // processes and they should soon all go into the cached state.
22682                    if (!r.finishing) {
22683                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22684                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22685                            app.adjType = "stop-activity";
22686                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22687                        }
22688                    }
22689                    app.cached = false;
22690                    app.empty = false;
22691                    foregroundActivities = true;
22692                } else {
22693                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22694                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
22695                        app.adjType = "cch-act";
22696                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
22697                    }
22698                }
22699            }
22700            if (adj == ProcessList.VISIBLE_APP_ADJ) {
22701                adj += minLayer;
22702            }
22703        }
22704        if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
22705            procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
22706            app.adjType = "cch-rec";
22707            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached recent: " + app);
22708        }
22709
22710        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22711                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
22712            if (app.foregroundServices) {
22713                // The user is aware of this app, so make it visible.
22714                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22715                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22716                app.cached = false;
22717                app.adjType = "fg-service";
22718                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22719                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
22720            } else if (app.hasOverlayUi) {
22721                // The process is display an overlay UI.
22722                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22723                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22724                app.cached = false;
22725                app.adjType = "has-overlay-ui";
22726                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22727                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
22728            }
22729        }
22730
22731        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22732                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22733            if (app.forcingToImportant != null) {
22734                // This is currently used for toasts...  they are not interactive, and
22735                // we don't want them to cause the app to become fully foreground (and
22736                // thus out of background check), so we yes the best background level we can.
22737                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22738                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22739                app.cached = false;
22740                app.adjType = "force-imp";
22741                app.adjSource = app.forcingToImportant;
22742                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22743                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
22744            }
22745        }
22746
22747        if (app == mHeavyWeightProcess) {
22748            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
22749                // We don't want to kill the current heavy-weight process.
22750                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
22751                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22752                app.cached = false;
22753                app.adjType = "heavy";
22754                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22755            }
22756            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22757                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
22758                app.adjType = "heavy";
22759                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22760            }
22761        }
22762
22763        if (app == mHomeProcess) {
22764            if (adj > ProcessList.HOME_APP_ADJ) {
22765                // This process is hosting what we currently consider to be the
22766                // home app, so we don't want to let it go into the background.
22767                adj = ProcessList.HOME_APP_ADJ;
22768                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22769                app.cached = false;
22770                app.adjType = "home";
22771                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22772            }
22773            if (procState > ActivityManager.PROCESS_STATE_HOME) {
22774                procState = ActivityManager.PROCESS_STATE_HOME;
22775                app.adjType = "home";
22776                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22777            }
22778        }
22779
22780        if (app == mPreviousProcess && app.activities.size() > 0) {
22781            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
22782                // This was the previous process that showed UI to the user.
22783                // We want to try to keep it around more aggressively, to give
22784                // a good experience around switching between two apps.
22785                adj = ProcessList.PREVIOUS_APP_ADJ;
22786                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22787                app.cached = false;
22788                app.adjType = "previous";
22789                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
22790            }
22791            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22792                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22793                app.adjType = "previous";
22794                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
22795            }
22796        }
22797
22798        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
22799                + " reason=" + app.adjType);
22800
22801        // By default, we use the computed adjustment.  It may be changed if
22802        // there are applications dependent on our services or providers, but
22803        // this gives us a baseline and makes sure we don't get into an
22804        // infinite recursion.
22805        app.adjSeq = mAdjSeq;
22806        app.curRawAdj = adj;
22807        app.hasStartedServices = false;
22808
22809        if (mBackupTarget != null && app == mBackupTarget.app) {
22810            // If possible we want to avoid killing apps while they're being backed up
22811            if (adj > ProcessList.BACKUP_APP_ADJ) {
22812                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
22813                adj = ProcessList.BACKUP_APP_ADJ;
22814                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22815                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22816                }
22817                app.adjType = "backup";
22818                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22819                app.cached = false;
22820            }
22821            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
22822                procState = ActivityManager.PROCESS_STATE_BACKUP;
22823                app.adjType = "backup";
22824                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22825            }
22826        }
22827
22828        boolean mayBeTop = false;
22829        String mayBeTopType = null;
22830        Object mayBeTopSource = null;
22831        Object mayBeTopTarget = null;
22832
22833        for (int is = app.services.size()-1;
22834                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22835                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22836                        || procState > ActivityManager.PROCESS_STATE_TOP);
22837                is--) {
22838            ServiceRecord s = app.services.valueAt(is);
22839            if (s.startRequested) {
22840                app.hasStartedServices = true;
22841                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
22842                    procState = ActivityManager.PROCESS_STATE_SERVICE;
22843                    app.adjType = "started-services";
22844                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
22845                }
22846                if (app.hasShownUi && app != mHomeProcess) {
22847                    // If this process has shown some UI, let it immediately
22848                    // go to the LRU list because it may be pretty heavy with
22849                    // UI stuff.  We'll tag it with a label just to help
22850                    // debug and understand what is going on.
22851                    if (adj > ProcessList.SERVICE_ADJ) {
22852                        app.adjType = "cch-started-ui-services";
22853                    }
22854                } else {
22855                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
22856                        // This service has seen some activity within
22857                        // recent memory, so we will keep its process ahead
22858                        // of the background processes.
22859                        if (adj > ProcessList.SERVICE_ADJ) {
22860                            adj = ProcessList.SERVICE_ADJ;
22861                            app.adjType = "started-services";
22862                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
22863                            app.cached = false;
22864                        }
22865                    }
22866                    // If we have let the service slide into the background
22867                    // state, still have some text describing what it is doing
22868                    // even though the service no longer has an impact.
22869                    if (adj > ProcessList.SERVICE_ADJ) {
22870                        app.adjType = "cch-started-services";
22871                    }
22872                }
22873            }
22874
22875            for (int conni = s.connections.size()-1;
22876                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22877                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22878                            || procState > ActivityManager.PROCESS_STATE_TOP);
22879                    conni--) {
22880                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
22881                for (int i = 0;
22882                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
22883                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22884                                || procState > ActivityManager.PROCESS_STATE_TOP);
22885                        i++) {
22886                    // XXX should compute this based on the max of
22887                    // all connected clients.
22888                    ConnectionRecord cr = clist.get(i);
22889                    if (cr.binding.client == app) {
22890                        // Binding to ourself is not interesting.
22891                        continue;
22892                    }
22893
22894                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
22895                        ProcessRecord client = cr.binding.client;
22896                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
22897                                TOP_APP, doingAll, now);
22898                        int clientProcState = client.curProcState;
22899                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22900                            // If the other app is cached for any reason, for purposes here
22901                            // we are going to consider it empty.  The specific cached state
22902                            // doesn't propagate except under certain conditions.
22903                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22904                        }
22905                        String adjType = null;
22906                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
22907                            // Not doing bind OOM management, so treat
22908                            // this guy more like a started service.
22909                            if (app.hasShownUi && app != mHomeProcess) {
22910                                // If this process has shown some UI, let it immediately
22911                                // go to the LRU list because it may be pretty heavy with
22912                                // UI stuff.  We'll tag it with a label just to help
22913                                // debug and understand what is going on.
22914                                if (adj > clientAdj) {
22915                                    adjType = "cch-bound-ui-services";
22916                                }
22917                                app.cached = false;
22918                                clientAdj = adj;
22919                                clientProcState = procState;
22920                            } else {
22921                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
22922                                    // This service has not seen activity within
22923                                    // recent memory, so allow it to drop to the
22924                                    // LRU list if there is no other reason to keep
22925                                    // it around.  We'll also tag it with a label just
22926                                    // to help debug and undertand what is going on.
22927                                    if (adj > clientAdj) {
22928                                        adjType = "cch-bound-services";
22929                                    }
22930                                    clientAdj = adj;
22931                                }
22932                            }
22933                        }
22934                        if (adj > clientAdj) {
22935                            // If this process has recently shown UI, and
22936                            // the process that is binding to it is less
22937                            // important than being visible, then we don't
22938                            // care about the binding as much as we care
22939                            // about letting this process get into the LRU
22940                            // list to be killed and restarted if needed for
22941                            // memory.
22942                            if (app.hasShownUi && app != mHomeProcess
22943                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22944                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
22945                                    adjType = "cch-bound-ui-services";
22946                                }
22947                            } else {
22948                                int newAdj;
22949                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
22950                                        |Context.BIND_IMPORTANT)) != 0) {
22951                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
22952                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
22953                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
22954                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
22955                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22956                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
22957                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
22958                                    newAdj = clientAdj;
22959                                } else {
22960                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
22961                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
22962                                    } else {
22963                                        newAdj = adj;
22964                                    }
22965                                }
22966                                if (!client.cached) {
22967                                    app.cached = false;
22968                                }
22969                                if (adj >  newAdj) {
22970                                    adj = newAdj;
22971                                    adjType = "service";
22972                                }
22973                            }
22974                        }
22975                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
22976                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
22977                            // This will treat important bound services identically to
22978                            // the top app, which may behave differently than generic
22979                            // foreground work.
22980                            if (client.curSchedGroup > schedGroup) {
22981                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
22982                                    schedGroup = client.curSchedGroup;
22983                                } else {
22984                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22985                                }
22986                            }
22987                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
22988                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
22989                                    // Special handling of clients who are in the top state.
22990                                    // We *may* want to consider this process to be in the
22991                                    // top state as well, but only if there is not another
22992                                    // reason for it to be running.  Being on the top is a
22993                                    // special state, meaning you are specifically running
22994                                    // for the current top app.  If the process is already
22995                                    // running in the background for some other reason, it
22996                                    // is more important to continue considering it to be
22997                                    // in the background state.
22998                                    mayBeTop = true;
22999                                    mayBeTopType = "service";
23000                                    mayBeTopSource = cr.binding.client;
23001                                    mayBeTopTarget = s.name;
23002                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23003                                } else {
23004                                    // Special handling for above-top states (persistent
23005                                    // processes).  These should not bring the current process
23006                                    // into the top state, since they are not on top.  Instead
23007                                    // give them the best state after that.
23008                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
23009                                        clientProcState =
23010                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23011                                    } else if (mWakefulness
23012                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
23013                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
23014                                                    != 0) {
23015                                        clientProcState =
23016                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23017                                    } else {
23018                                        clientProcState =
23019                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23020                                    }
23021                                }
23022                            }
23023                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
23024                            if (clientProcState <
23025                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23026                                clientProcState =
23027                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23028                            }
23029                        } else {
23030                            if (clientProcState <
23031                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
23032                                clientProcState =
23033                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
23034                            }
23035                        }
23036                        if (procState > clientProcState) {
23037                            procState = clientProcState;
23038                            if (adjType == null) {
23039                                adjType = "service";
23040                            }
23041                        }
23042                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
23043                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
23044                            app.pendingUiClean = true;
23045                        }
23046                        if (adjType != null) {
23047                            app.adjType = adjType;
23048                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23049                                    .REASON_SERVICE_IN_USE;
23050                            app.adjSource = cr.binding.client;
23051                            app.adjSourceProcState = clientProcState;
23052                            app.adjTarget = s.name;
23053                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
23054                                    + ": " + app + ", due to " + cr.binding.client
23055                                    + " adj=" + adj + " procState=" + procState);
23056                        }
23057                    }
23058                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
23059                        app.treatLikeActivity = true;
23060                    }
23061                    final ActivityRecord a = cr.activity;
23062                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
23063                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
23064                            (a.visible || a.state == ActivityState.RESUMED ||
23065                             a.state == ActivityState.PAUSING)) {
23066                            adj = ProcessList.FOREGROUND_APP_ADJ;
23067                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
23068                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23069                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
23070                                } else {
23071                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23072                                }
23073                            }
23074                            app.cached = false;
23075                            app.adjType = "service";
23076                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23077                                    .REASON_SERVICE_IN_USE;
23078                            app.adjSource = a;
23079                            app.adjSourceProcState = procState;
23080                            app.adjTarget = s.name;
23081                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
23082                                    + app);
23083                        }
23084                    }
23085                }
23086            }
23087        }
23088
23089        for (int provi = app.pubProviders.size()-1;
23090                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23091                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23092                        || procState > ActivityManager.PROCESS_STATE_TOP);
23093                provi--) {
23094            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
23095            for (int i = cpr.connections.size()-1;
23096                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23097                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23098                            || procState > ActivityManager.PROCESS_STATE_TOP);
23099                    i--) {
23100                ContentProviderConnection conn = cpr.connections.get(i);
23101                ProcessRecord client = conn.client;
23102                if (client == app) {
23103                    // Being our own client is not interesting.
23104                    continue;
23105                }
23106                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23107                int clientProcState = client.curProcState;
23108                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23109                    // If the other app is cached for any reason, for purposes here
23110                    // we are going to consider it empty.
23111                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23112                }
23113                String adjType = null;
23114                if (adj > clientAdj) {
23115                    if (app.hasShownUi && app != mHomeProcess
23116                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23117                        adjType = "cch-ui-provider";
23118                    } else {
23119                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
23120                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
23121                        adjType = "provider";
23122                    }
23123                    app.cached &= client.cached;
23124                }
23125                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23126                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23127                        // Special handling of clients who are in the top state.
23128                        // We *may* want to consider this process to be in the
23129                        // top state as well, but only if there is not another
23130                        // reason for it to be running.  Being on the top is a
23131                        // special state, meaning you are specifically running
23132                        // for the current top app.  If the process is already
23133                        // running in the background for some other reason, it
23134                        // is more important to continue considering it to be
23135                        // in the background state.
23136                        mayBeTop = true;
23137                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23138                        mayBeTopType = adjType = "provider-top";
23139                        mayBeTopSource = client;
23140                        mayBeTopTarget = cpr.name;
23141                    } else {
23142                        // Special handling for above-top states (persistent
23143                        // processes).  These should not bring the current process
23144                        // into the top state, since they are not on top.  Instead
23145                        // give them the best state after that.
23146                        clientProcState =
23147                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23148                        if (adjType == null) {
23149                            adjType = "provider";
23150                        }
23151                    }
23152                }
23153                if (procState > clientProcState) {
23154                    procState = clientProcState;
23155                }
23156                if (client.curSchedGroup > schedGroup) {
23157                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23158                }
23159                if (adjType != null) {
23160                    app.adjType = adjType;
23161                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23162                            .REASON_PROVIDER_IN_USE;
23163                    app.adjSource = client;
23164                    app.adjSourceProcState = clientProcState;
23165                    app.adjTarget = cpr.name;
23166                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
23167                            + ": " + app + ", due to " + client
23168                            + " adj=" + adj + " procState=" + procState);
23169                }
23170            }
23171            // If the provider has external (non-framework) process
23172            // dependencies, ensure that its adjustment is at least
23173            // FOREGROUND_APP_ADJ.
23174            if (cpr.hasExternalProcessHandles()) {
23175                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
23176                    adj = ProcessList.FOREGROUND_APP_ADJ;
23177                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23178                    app.cached = false;
23179                    app.adjType = "ext-provider";
23180                    app.adjTarget = cpr.name;
23181                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
23182                }
23183                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23184                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23185                }
23186            }
23187        }
23188
23189        if (app.lastProviderTime > 0 &&
23190                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
23191            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23192                adj = ProcessList.PREVIOUS_APP_ADJ;
23193                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23194                app.cached = false;
23195                app.adjType = "recent-provider";
23196                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
23197            }
23198            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23199                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23200                app.adjType = "recent-provider";
23201                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
23202            }
23203        }
23204
23205        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
23206            // A client of one of our services or providers is in the top state.  We
23207            // *may* want to be in the top state, but not if we are already running in
23208            // the background for some other reason.  For the decision here, we are going
23209            // to pick out a few specific states that we want to remain in when a client
23210            // is top (states that tend to be longer-term) and otherwise allow it to go
23211            // to the top state.
23212            switch (procState) {
23213                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
23214                case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
23215                    // Something else is keeping it at this level, just leave it.
23216                    break;
23217                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
23218                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
23219                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
23220                case ActivityManager.PROCESS_STATE_SERVICE:
23221                    // These all are longer-term states, so pull them up to the top
23222                    // of the background states, but not all the way to the top state.
23223                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23224                    app.adjType = mayBeTopType;
23225                    app.adjSource = mayBeTopSource;
23226                    app.adjTarget = mayBeTopTarget;
23227                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
23228                            + ": " + app + ", due to " + mayBeTopSource
23229                            + " adj=" + adj + " procState=" + procState);
23230                    break;
23231                default:
23232                    // Otherwise, top is a better choice, so take it.
23233                    procState = ActivityManager.PROCESS_STATE_TOP;
23234                    app.adjType = mayBeTopType;
23235                    app.adjSource = mayBeTopSource;
23236                    app.adjTarget = mayBeTopTarget;
23237                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
23238                            + ": " + app + ", due to " + mayBeTopSource
23239                            + " adj=" + adj + " procState=" + procState);
23240                    break;
23241            }
23242        }
23243
23244        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
23245            if (app.hasClientActivities) {
23246                // This is a cached process, but with client activities.  Mark it so.
23247                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
23248                app.adjType = "cch-client-act";
23249            } else if (app.treatLikeActivity) {
23250                // This is a cached process, but somebody wants us to treat it like it has
23251                // an activity, okay!
23252                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23253                app.adjType = "cch-as-act";
23254            }
23255        }
23256
23257        if (adj == ProcessList.SERVICE_ADJ) {
23258            if (doingAll) {
23259                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
23260                mNewNumServiceProcs++;
23261                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
23262                if (!app.serviceb) {
23263                    // This service isn't far enough down on the LRU list to
23264                    // normally be a B service, but if we are low on RAM and it
23265                    // is large we want to force it down since we would prefer to
23266                    // keep launcher over it.
23267                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
23268                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
23269                        app.serviceHighRam = true;
23270                        app.serviceb = true;
23271                        //Slog.i(TAG, "ADJ " + app + " high ram!");
23272                    } else {
23273                        mNewNumAServiceProcs++;
23274                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
23275                    }
23276                } else {
23277                    app.serviceHighRam = false;
23278                }
23279            }
23280            if (app.serviceb) {
23281                adj = ProcessList.SERVICE_B_ADJ;
23282            }
23283        }
23284
23285        app.curRawAdj = adj;
23286
23287        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
23288        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
23289        if (adj > app.maxAdj) {
23290            adj = app.maxAdj;
23291            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
23292                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23293            }
23294        }
23295
23296        // Do final modification to adj.  Everything we do between here and applying
23297        // the final setAdj must be done in this function, because we will also use
23298        // it when computing the final cached adj later.  Note that we don't need to
23299        // worry about this for max adj above, since max adj will always be used to
23300        // keep it out of the cached vaues.
23301        app.curAdj = app.modifyRawOomAdj(adj);
23302        app.curSchedGroup = schedGroup;
23303        app.curProcState = procState;
23304        app.foregroundActivities = foregroundActivities;
23305
23306        return app.curRawAdj;
23307    }
23308
23309    /**
23310     * Record new PSS sample for a process.
23311     */
23312    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
23313            long rss, int statType, long pssDuration, long now) {
23314        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
23315                swapPss * 1024, rss * 1024, statType, procState, pssDuration);
23316        proc.lastPssTime = now;
23317        proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
23318        if (DEBUG_PSS) Slog.d(TAG_PSS,
23319                "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
23320                + " state=" + ProcessList.makeProcStateString(procState));
23321        if (proc.initialIdlePss == 0) {
23322            proc.initialIdlePss = pss;
23323        }
23324        proc.lastPss = pss;
23325        proc.lastSwapPss = swapPss;
23326        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
23327            proc.lastCachedPss = pss;
23328            proc.lastCachedSwapPss = swapPss;
23329        }
23330
23331        final SparseArray<Pair<Long, String>> watchUids
23332                = mMemWatchProcesses.getMap().get(proc.processName);
23333        Long check = null;
23334        if (watchUids != null) {
23335            Pair<Long, String> val = watchUids.get(proc.uid);
23336            if (val == null) {
23337                val = watchUids.get(0);
23338            }
23339            if (val != null) {
23340                check = val.first;
23341            }
23342        }
23343        if (check != null) {
23344            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
23345                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23346                if (!isDebuggable) {
23347                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
23348                        isDebuggable = true;
23349                    }
23350                }
23351                if (isDebuggable) {
23352                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
23353                    final ProcessRecord myProc = proc;
23354                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
23355                    mMemWatchDumpProcName = proc.processName;
23356                    mMemWatchDumpFile = heapdumpFile.toString();
23357                    mMemWatchDumpPid = proc.pid;
23358                    mMemWatchDumpUid = proc.uid;
23359                    BackgroundThread.getHandler().post(new Runnable() {
23360                        @Override
23361                        public void run() {
23362                            revokeUriPermission(ActivityThread.currentActivityThread()
23363                                            .getApplicationThread(),
23364                                    null, DumpHeapActivity.JAVA_URI,
23365                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
23366                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
23367                                    UserHandle.myUserId());
23368                            ParcelFileDescriptor fd = null;
23369                            try {
23370                                heapdumpFile.delete();
23371                                fd = ParcelFileDescriptor.open(heapdumpFile,
23372                                        ParcelFileDescriptor.MODE_CREATE |
23373                                                ParcelFileDescriptor.MODE_TRUNCATE |
23374                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
23375                                                ParcelFileDescriptor.MODE_APPEND);
23376                                IApplicationThread thread = myProc.thread;
23377                                if (thread != null) {
23378                                    try {
23379                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
23380                                                "Requesting dump heap from "
23381                                                + myProc + " to " + heapdumpFile);
23382                                        thread.dumpHeap(/* managed= */ true,
23383                                                /* mallocInfo= */ false, /* runGc= */ false,
23384                                                heapdumpFile.toString(), fd);
23385                                    } catch (RemoteException e) {
23386                                    }
23387                                }
23388                            } catch (FileNotFoundException e) {
23389                                e.printStackTrace();
23390                            } finally {
23391                                if (fd != null) {
23392                                    try {
23393                                        fd.close();
23394                                    } catch (IOException e) {
23395                                    }
23396                                }
23397                            }
23398                        }
23399                    });
23400                } else {
23401                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
23402                            + ", but debugging not enabled");
23403                }
23404            }
23405        }
23406    }
23407
23408    /**
23409     * Schedule PSS collection of a process.
23410     */
23411    boolean requestPssLocked(ProcessRecord proc, int procState) {
23412        if (mPendingPssProcesses.contains(proc)) {
23413            return false;
23414        }
23415        if (mPendingPssProcesses.size() == 0) {
23416            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23417        }
23418        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
23419        proc.pssProcState = procState;
23420        proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
23421        mPendingPssProcesses.add(proc);
23422        return true;
23423    }
23424
23425    /**
23426     * Schedule PSS collection of all processes.
23427     */
23428    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
23429        if (!always) {
23430            if (now < (mLastFullPssTime +
23431                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
23432                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
23433                return;
23434            }
23435        }
23436        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs!  memLowered=" + memLowered);
23437        mLastFullPssTime = now;
23438        mFullPssPending = true;
23439        for (int i = mPendingPssProcesses.size() - 1; i >= 0; i--) {
23440            ProcessList.abortNextPssTime(mPendingPssProcesses.get(i).procStateMemTracker);;
23441        }
23442        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
23443        mPendingPssProcesses.clear();
23444        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23445            ProcessRecord app = mLruProcesses.get(i);
23446            if (app.thread == null
23447                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
23448                continue;
23449            }
23450            if (memLowered || (always && now >
23451                            app.lastStateTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
23452                    || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
23453                app.pssProcState = app.setProcState;
23454                app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
23455                        : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
23456                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
23457                        app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
23458                mPendingPssProcesses.add(app);
23459            }
23460        }
23461        if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) {
23462            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23463        }
23464    }
23465
23466    public void setTestPssMode(boolean enabled) {
23467        synchronized (this) {
23468            mTestPssMode = enabled;
23469            if (enabled) {
23470                // Whenever we enable the mode, we want to take a snapshot all of current
23471                // process mem use.
23472                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
23473            }
23474        }
23475    }
23476
23477    /**
23478     * Ask a given process to GC right now.
23479     */
23480    final void performAppGcLocked(ProcessRecord app) {
23481        try {
23482            app.lastRequestedGc = SystemClock.uptimeMillis();
23483            if (app.thread != null) {
23484                if (app.reportLowMemory) {
23485                    app.reportLowMemory = false;
23486                    app.thread.scheduleLowMemory();
23487                } else {
23488                    app.thread.processInBackground();
23489                }
23490            }
23491        } catch (Exception e) {
23492            // whatever.
23493        }
23494    }
23495
23496    /**
23497     * Returns true if things are idle enough to perform GCs.
23498     */
23499    private final boolean canGcNowLocked() {
23500        boolean processingBroadcasts = false;
23501        for (BroadcastQueue q : mBroadcastQueues) {
23502            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
23503                processingBroadcasts = true;
23504            }
23505        }
23506        return !processingBroadcasts
23507                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
23508    }
23509
23510    /**
23511     * Perform GCs on all processes that are waiting for it, but only
23512     * if things are idle.
23513     */
23514    final void performAppGcsLocked() {
23515        final int N = mProcessesToGc.size();
23516        if (N <= 0) {
23517            return;
23518        }
23519        if (canGcNowLocked()) {
23520            while (mProcessesToGc.size() > 0) {
23521                ProcessRecord proc = mProcessesToGc.remove(0);
23522                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
23523                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
23524                            <= SystemClock.uptimeMillis()) {
23525                        // To avoid spamming the system, we will GC processes one
23526                        // at a time, waiting a few seconds between each.
23527                        performAppGcLocked(proc);
23528                        scheduleAppGcsLocked();
23529                        return;
23530                    } else {
23531                        // It hasn't been long enough since we last GCed this
23532                        // process...  put it in the list to wait for its time.
23533                        addProcessToGcListLocked(proc);
23534                        break;
23535                    }
23536                }
23537            }
23538
23539            scheduleAppGcsLocked();
23540        }
23541    }
23542
23543    /**
23544     * If all looks good, perform GCs on all processes waiting for them.
23545     */
23546    final void performAppGcsIfAppropriateLocked() {
23547        if (canGcNowLocked()) {
23548            performAppGcsLocked();
23549            return;
23550        }
23551        // Still not idle, wait some more.
23552        scheduleAppGcsLocked();
23553    }
23554
23555    /**
23556     * Schedule the execution of all pending app GCs.
23557     */
23558    final void scheduleAppGcsLocked() {
23559        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
23560
23561        if (mProcessesToGc.size() > 0) {
23562            // Schedule a GC for the time to the next process.
23563            ProcessRecord proc = mProcessesToGc.get(0);
23564            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
23565
23566            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
23567            long now = SystemClock.uptimeMillis();
23568            if (when < (now+mConstants.GC_TIMEOUT)) {
23569                when = now + mConstants.GC_TIMEOUT;
23570            }
23571            mHandler.sendMessageAtTime(msg, when);
23572        }
23573    }
23574
23575    /**
23576     * Add a process to the array of processes waiting to be GCed.  Keeps the
23577     * list in sorted order by the last GC time.  The process can't already be
23578     * on the list.
23579     */
23580    final void addProcessToGcListLocked(ProcessRecord proc) {
23581        boolean added = false;
23582        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
23583            if (mProcessesToGc.get(i).lastRequestedGc <
23584                    proc.lastRequestedGc) {
23585                added = true;
23586                mProcessesToGc.add(i+1, proc);
23587                break;
23588            }
23589        }
23590        if (!added) {
23591            mProcessesToGc.add(0, proc);
23592        }
23593    }
23594
23595    /**
23596     * Set up to ask a process to GC itself.  This will either do it
23597     * immediately, or put it on the list of processes to gc the next
23598     * time things are idle.
23599     */
23600    final void scheduleAppGcLocked(ProcessRecord app) {
23601        long now = SystemClock.uptimeMillis();
23602        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
23603            return;
23604        }
23605        if (!mProcessesToGc.contains(app)) {
23606            addProcessToGcListLocked(app);
23607            scheduleAppGcsLocked();
23608        }
23609    }
23610
23611    final void checkExcessivePowerUsageLocked() {
23612        updateCpuStatsNow();
23613
23614        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
23615        boolean doCpuKills = true;
23616        if (mLastPowerCheckUptime == 0) {
23617            doCpuKills = false;
23618        }
23619        final long curUptime = SystemClock.uptimeMillis();
23620        final long uptimeSince = curUptime - mLastPowerCheckUptime;
23621        mLastPowerCheckUptime = curUptime;
23622        int i = mLruProcesses.size();
23623        while (i > 0) {
23624            i--;
23625            ProcessRecord app = mLruProcesses.get(i);
23626            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
23627                if (app.lastCpuTime <= 0) {
23628                    continue;
23629                }
23630                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
23631                if (DEBUG_POWER) {
23632                    StringBuilder sb = new StringBuilder(128);
23633                    sb.append("CPU for ");
23634                    app.toShortString(sb);
23635                    sb.append(": over ");
23636                    TimeUtils.formatDuration(uptimeSince, sb);
23637                    sb.append(" used ");
23638                    TimeUtils.formatDuration(cputimeUsed, sb);
23639                    sb.append(" (");
23640                    sb.append((cputimeUsed*100)/uptimeSince);
23641                    sb.append("%)");
23642                    Slog.i(TAG_POWER, sb.toString());
23643                }
23644                // If the process has used too much CPU over the last duration, the
23645                // user probably doesn't want this, so kill!
23646                if (doCpuKills && uptimeSince > 0) {
23647                    // What is the limit for this process?
23648                    int cpuLimit;
23649                    long checkDur = curUptime - app.whenUnimportant;
23650                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
23651                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
23652                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
23653                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
23654                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
23655                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
23656                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
23657                    } else {
23658                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
23659                    }
23660                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
23661                        synchronized (stats) {
23662                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
23663                                    uptimeSince, cputimeUsed);
23664                        }
23665                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
23666                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
23667                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
23668                    }
23669                }
23670                app.lastCpuTime = app.curCpuTime;
23671            }
23672        }
23673    }
23674
23675    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
23676            long nowElapsed) {
23677        boolean success = true;
23678
23679        if (app.curRawAdj != app.setRawAdj) {
23680            app.setRawAdj = app.curRawAdj;
23681        }
23682
23683        int changes = 0;
23684
23685        if (app.curAdj != app.setAdj) {
23686            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
23687            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
23688                String msg = "Set " + app.pid + " " + app.processName + " adj "
23689                        + app.curAdj + ": " + app.adjType;
23690                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23691            }
23692            app.setAdj = app.curAdj;
23693            app.verifiedAdj = ProcessList.INVALID_ADJ;
23694        }
23695
23696        if (app.setSchedGroup != app.curSchedGroup) {
23697            int oldSchedGroup = app.setSchedGroup;
23698            app.setSchedGroup = app.curSchedGroup;
23699            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
23700                String msg = "Setting sched group of " + app.processName
23701                        + " to " + app.curSchedGroup;
23702                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23703            }
23704            if (app.waitingToKill != null && app.curReceivers.isEmpty()
23705                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
23706                app.kill(app.waitingToKill, true);
23707                success = false;
23708            } else {
23709                int processGroup;
23710                switch (app.curSchedGroup) {
23711                    case ProcessList.SCHED_GROUP_BACKGROUND:
23712                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
23713                        break;
23714                    case ProcessList.SCHED_GROUP_TOP_APP:
23715                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
23716                        processGroup = THREAD_GROUP_TOP_APP;
23717                        break;
23718                    default:
23719                        processGroup = THREAD_GROUP_DEFAULT;
23720                        break;
23721                }
23722                long oldId = Binder.clearCallingIdentity();
23723                try {
23724                    setProcessGroup(app.pid, processGroup);
23725                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
23726                        // do nothing if we already switched to RT
23727                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23728                            mVrController.onTopProcChangedLocked(app);
23729                            if (mUseFifoUiScheduling) {
23730                                // Switch UI pipeline for app to SCHED_FIFO
23731                                app.savedPriority = Process.getThreadPriority(app.pid);
23732                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
23733                                if (app.renderThreadTid != 0) {
23734                                    scheduleAsFifoPriority(app.renderThreadTid,
23735                                        /* suppressLogs */true);
23736                                    if (DEBUG_OOM_ADJ) {
23737                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
23738                                            app.renderThreadTid + ") to FIFO");
23739                                    }
23740                                } else {
23741                                    if (DEBUG_OOM_ADJ) {
23742                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
23743                                    }
23744                                }
23745                            } else {
23746                                // Boost priority for top app UI and render threads
23747                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
23748                                if (app.renderThreadTid != 0) {
23749                                    try {
23750                                        setThreadPriority(app.renderThreadTid,
23751                                                TOP_APP_PRIORITY_BOOST);
23752                                    } catch (IllegalArgumentException e) {
23753                                        // thread died, ignore
23754                                    }
23755                                }
23756                            }
23757                        }
23758                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
23759                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23760                        mVrController.onTopProcChangedLocked(app);
23761                        if (mUseFifoUiScheduling) {
23762                            try {
23763                                // Reset UI pipeline to SCHED_OTHER
23764                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
23765                                setThreadPriority(app.pid, app.savedPriority);
23766                                if (app.renderThreadTid != 0) {
23767                                    setThreadScheduler(app.renderThreadTid,
23768                                        SCHED_OTHER, 0);
23769                                    setThreadPriority(app.renderThreadTid, -4);
23770                                }
23771                            } catch (IllegalArgumentException e) {
23772                                Slog.w(TAG,
23773                                        "Failed to set scheduling policy, thread does not exist:\n"
23774                                                + e);
23775                            } catch (SecurityException e) {
23776                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
23777                            }
23778                        } else {
23779                            // Reset priority for top app UI and render threads
23780                            setThreadPriority(app.pid, 0);
23781                            if (app.renderThreadTid != 0) {
23782                                setThreadPriority(app.renderThreadTid, 0);
23783                            }
23784                        }
23785                    }
23786                } catch (Exception e) {
23787                    if (false) {
23788                        Slog.w(TAG, "Failed setting process group of " + app.pid
23789                                + " to " + app.curSchedGroup);
23790                        Slog.w(TAG, "at location", e);
23791                    }
23792                } finally {
23793                    Binder.restoreCallingIdentity(oldId);
23794                }
23795            }
23796        }
23797        if (app.repForegroundActivities != app.foregroundActivities) {
23798            app.repForegroundActivities = app.foregroundActivities;
23799            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
23800        }
23801        if (app.repProcState != app.curProcState) {
23802            app.repProcState = app.curProcState;
23803            if (app.thread != null) {
23804                try {
23805                    if (false) {
23806                        //RuntimeException h = new RuntimeException("here");
23807                        Slog.i(TAG, "Sending new process state " + app.repProcState
23808                                + " to " + app /*, h*/);
23809                    }
23810                    app.thread.setProcessState(app.repProcState);
23811                } catch (RemoteException e) {
23812                }
23813            }
23814        }
23815        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
23816                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
23817            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
23818                // Experimental code to more aggressively collect pss while
23819                // running test...  the problem is that this tends to collect
23820                // the data right when a process is transitioning between process
23821                // states, which will tend to give noisy data.
23822                long start = SystemClock.uptimeMillis();
23823                long startTime = SystemClock.currentThreadTimeMillis();
23824                long pss = Debug.getPss(app.pid, mTmpLong, null);
23825                long endTime = SystemClock.currentThreadTimeMillis();
23826                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
23827                        mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
23828                mPendingPssProcesses.remove(app);
23829                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
23830                        + " to " + app.curProcState + ": "
23831                        + (SystemClock.uptimeMillis()-start) + "ms");
23832            }
23833            app.lastStateTime = now;
23834            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
23835                    app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
23836            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
23837                    + ProcessList.makeProcStateString(app.setProcState) + " to "
23838                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
23839                    + (app.nextPssTime-now) + ": " + app);
23840        } else {
23841            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
23842                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
23843                    mTestPssMode)))) {
23844                if (requestPssLocked(app, app.setProcState)) {
23845                    app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
23846                            app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
23847                }
23848            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
23849                    "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
23850        }
23851        if (app.setProcState != app.curProcState) {
23852            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
23853                String msg = "Proc state change of " + app.processName
23854                        + " to " + app.curProcState;
23855                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23856            }
23857            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
23858            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
23859            if (setImportant && !curImportant) {
23860                // This app is no longer something we consider important enough to allow to
23861                // use arbitrary amounts of battery power.  Note
23862                // its current CPU time to later know to kill it if
23863                // it is not behaving well.
23864                app.whenUnimportant = now;
23865                app.lastCpuTime = 0;
23866            }
23867            // Inform UsageStats of important process state change
23868            // Must be called before updating setProcState
23869            maybeUpdateUsageStatsLocked(app, nowElapsed);
23870
23871            app.setProcState = app.curProcState;
23872            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
23873                app.notCachedSinceIdle = false;
23874            }
23875            if (!doingAll) {
23876                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
23877            } else {
23878                app.procStateChanged = true;
23879            }
23880        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
23881                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
23882            // For apps that sit around for a long time in the interactive state, we need
23883            // to report this at least once a day so they don't go idle.
23884            maybeUpdateUsageStatsLocked(app, nowElapsed);
23885        }
23886
23887        if (changes != 0) {
23888            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23889                    "Changes in " + app + ": " + changes);
23890            int i = mPendingProcessChanges.size()-1;
23891            ProcessChangeItem item = null;
23892            while (i >= 0) {
23893                item = mPendingProcessChanges.get(i);
23894                if (item.pid == app.pid) {
23895                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23896                            "Re-using existing item: " + item);
23897                    break;
23898                }
23899                i--;
23900            }
23901            if (i < 0) {
23902                // No existing item in pending changes; need a new one.
23903                final int NA = mAvailProcessChanges.size();
23904                if (NA > 0) {
23905                    item = mAvailProcessChanges.remove(NA-1);
23906                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23907                            "Retrieving available item: " + item);
23908                } else {
23909                    item = new ProcessChangeItem();
23910                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23911                            "Allocating new item: " + item);
23912                }
23913                item.changes = 0;
23914                item.pid = app.pid;
23915                item.uid = app.info.uid;
23916                if (mPendingProcessChanges.size() == 0) {
23917                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23918                            "*** Enqueueing dispatch processes changed!");
23919                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
23920                }
23921                mPendingProcessChanges.add(item);
23922            }
23923            item.changes |= changes;
23924            item.foregroundActivities = app.repForegroundActivities;
23925            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23926                    "Item " + Integer.toHexString(System.identityHashCode(item))
23927                    + " " + app.toShortString() + ": changes=" + item.changes
23928                    + " foreground=" + item.foregroundActivities
23929                    + " type=" + app.adjType + " source=" + app.adjSource
23930                    + " target=" + app.adjTarget);
23931        }
23932
23933        return success;
23934    }
23935
23936    private boolean isEphemeralLocked(int uid) {
23937        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
23938        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
23939            return false;
23940        }
23941        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
23942                packages[0]);
23943    }
23944
23945    @VisibleForTesting
23946    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
23947        final UidRecord.ChangeItem pendingChange;
23948        if (uidRec == null || uidRec.pendingChange == null) {
23949            if (mPendingUidChanges.size() == 0) {
23950                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23951                        "*** Enqueueing dispatch uid changed!");
23952                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
23953            }
23954            final int NA = mAvailUidChanges.size();
23955            if (NA > 0) {
23956                pendingChange = mAvailUidChanges.remove(NA-1);
23957                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23958                        "Retrieving available item: " + pendingChange);
23959            } else {
23960                pendingChange = new UidRecord.ChangeItem();
23961                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23962                        "Allocating new item: " + pendingChange);
23963            }
23964            if (uidRec != null) {
23965                uidRec.pendingChange = pendingChange;
23966                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
23967                    // If this uid is going away, and we haven't yet reported it is gone,
23968                    // then do so now.
23969                    change |= UidRecord.CHANGE_IDLE;
23970                }
23971            } else if (uid < 0) {
23972                throw new IllegalArgumentException("No UidRecord or uid");
23973            }
23974            pendingChange.uidRecord = uidRec;
23975            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
23976            mPendingUidChanges.add(pendingChange);
23977        } else {
23978            pendingChange = uidRec.pendingChange;
23979            // If there is no change in idle or active state, then keep whatever was pending.
23980            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
23981                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
23982                        | UidRecord.CHANGE_ACTIVE));
23983            }
23984            // If there is no change in cached or uncached state, then keep whatever was pending.
23985            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
23986                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
23987                        | UidRecord.CHANGE_UNCACHED));
23988            }
23989            // If this is a report of the UID being gone, then we shouldn't keep any previous
23990            // report of it being active or cached.  (That is, a gone uid is never active,
23991            // and never cached.)
23992            if ((change & UidRecord.CHANGE_GONE) != 0) {
23993                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
23994                if (!uidRec.idle) {
23995                    // If this uid is going away, and we haven't yet reported it is gone,
23996                    // then do so now.
23997                    change |= UidRecord.CHANGE_IDLE;
23998                }
23999            }
24000        }
24001        pendingChange.change = change;
24002        pendingChange.processState = uidRec != null
24003                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
24004        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
24005        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
24006        if (uidRec != null) {
24007            uidRec.lastReportedChange = change;
24008            uidRec.updateLastDispatchedProcStateSeq(change);
24009        }
24010
24011        // Directly update the power manager, since we sit on top of it and it is critical
24012        // it be kept in sync (so wake locks will be held as soon as appropriate).
24013        if (mLocalPowerManager != null) {
24014            // TO DO: dispatch cached/uncached changes here, so we don't need to report
24015            // all proc state changes.
24016            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
24017                mLocalPowerManager.uidActive(pendingChange.uid);
24018            }
24019            if ((change & UidRecord.CHANGE_IDLE) != 0) {
24020                mLocalPowerManager.uidIdle(pendingChange.uid);
24021            }
24022            if ((change & UidRecord.CHANGE_GONE) != 0) {
24023                mLocalPowerManager.uidGone(pendingChange.uid);
24024            } else {
24025                mLocalPowerManager.updateUidProcState(pendingChange.uid,
24026                        pendingChange.processState);
24027            }
24028        }
24029    }
24030
24031    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
24032            String authority) {
24033        if (app == null) return;
24034        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
24035            UserState userState = mUserController.getStartedUserState(app.userId);
24036            if (userState == null) return;
24037            final long now = SystemClock.elapsedRealtime();
24038            Long lastReported = userState.mProviderLastReportedFg.get(authority);
24039            if (lastReported == null || lastReported < now - 60 * 1000L) {
24040                if (mSystemReady) {
24041                    // Cannot touch the user stats if not system ready
24042                    mUsageStatsService.reportContentProviderUsage(
24043                            authority, providerPkgName, app.userId);
24044                }
24045                userState.mProviderLastReportedFg.put(authority, now);
24046            }
24047        }
24048    }
24049
24050    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
24051        if (DEBUG_USAGE_STATS) {
24052            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
24053                    + "] state changes: old = " + app.setProcState + ", new = "
24054                    + app.curProcState);
24055        }
24056        if (mUsageStatsService == null) {
24057            return;
24058        }
24059        boolean isInteraction;
24060        // To avoid some abuse patterns, we are going to be careful about what we consider
24061        // to be an app interaction.  Being the top activity doesn't count while the display
24062        // is sleeping, nor do short foreground services.
24063        if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
24064            isInteraction = true;
24065            app.fgInteractionTime = 0;
24066        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
24067            if (app.fgInteractionTime == 0) {
24068                app.fgInteractionTime = nowElapsed;
24069                isInteraction = false;
24070            } else {
24071                isInteraction = nowElapsed > app.fgInteractionTime
24072                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
24073            }
24074        } else {
24075            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
24076            app.fgInteractionTime = 0;
24077        }
24078        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
24079                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
24080            app.interactionEventTime = nowElapsed;
24081            String[] packages = app.getPackageList();
24082            if (packages != null) {
24083                for (int i = 0; i < packages.length; i++) {
24084                    mUsageStatsService.reportEvent(packages[i], app.userId,
24085                            UsageEvents.Event.SYSTEM_INTERACTION);
24086                }
24087            }
24088        }
24089        app.reportedInteraction = isInteraction;
24090        if (!isInteraction) {
24091            app.interactionEventTime = 0;
24092        }
24093    }
24094
24095    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
24096        if (proc.thread != null) {
24097            if (proc.baseProcessTracker != null) {
24098                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
24099            }
24100        }
24101    }
24102
24103    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
24104            ProcessRecord TOP_APP, boolean doingAll, long now) {
24105        if (app.thread == null) {
24106            return false;
24107        }
24108
24109        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
24110
24111        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
24112    }
24113
24114    @GuardedBy("this")
24115    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
24116            boolean oomAdj) {
24117        if (isForeground != proc.foregroundServices) {
24118            proc.foregroundServices = isForeground;
24119            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
24120                    proc.info.uid);
24121            if (isForeground) {
24122                if (curProcs == null) {
24123                    curProcs = new ArrayList<ProcessRecord>();
24124                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
24125                }
24126                if (!curProcs.contains(proc)) {
24127                    curProcs.add(proc);
24128                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
24129                            proc.info.packageName, proc.info.uid);
24130                }
24131            } else {
24132                if (curProcs != null) {
24133                    if (curProcs.remove(proc)) {
24134                        mBatteryStatsService.noteEvent(
24135                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
24136                                proc.info.packageName, proc.info.uid);
24137                        if (curProcs.size() <= 0) {
24138                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
24139                        }
24140                    }
24141                }
24142            }
24143            if (oomAdj) {
24144                updateOomAdjLocked();
24145            }
24146        }
24147    }
24148
24149    private final ActivityRecord resumedAppLocked() {
24150        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
24151        String pkg;
24152        int uid;
24153        if (act != null) {
24154            pkg = act.packageName;
24155            uid = act.info.applicationInfo.uid;
24156        } else {
24157            pkg = null;
24158            uid = -1;
24159        }
24160        // Has the UID or resumed package name changed?
24161        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
24162                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
24163            if (mCurResumedPackage != null) {
24164                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
24165                        mCurResumedPackage, mCurResumedUid);
24166            }
24167            mCurResumedPackage = pkg;
24168            mCurResumedUid = uid;
24169            if (mCurResumedPackage != null) {
24170                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
24171                        mCurResumedPackage, mCurResumedUid);
24172            }
24173        }
24174        return act;
24175    }
24176
24177    /**
24178     * Update OomAdj for a specific process.
24179     * @param app The process to update
24180     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
24181     *                  if necessary, or skip.
24182     * @return whether updateOomAdjLocked(app) was successful.
24183     */
24184    @GuardedBy("this")
24185    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
24186        final ActivityRecord TOP_ACT = resumedAppLocked();
24187        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24188        final boolean wasCached = app.cached;
24189
24190        mAdjSeq++;
24191
24192        // This is the desired cached adjusment we want to tell it to use.
24193        // If our app is currently cached, we know it, and that is it.  Otherwise,
24194        // we don't know it yet, and it needs to now be cached we will then
24195        // need to do a complete oom adj.
24196        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
24197                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
24198        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
24199                SystemClock.uptimeMillis());
24200        if (oomAdjAll
24201                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
24202            // Changed to/from cached state, so apps after it in the LRU
24203            // list may also be changed.
24204            updateOomAdjLocked();
24205        }
24206        return success;
24207    }
24208
24209    @GuardedBy("this")
24210    final void updateOomAdjLocked() {
24211        final ActivityRecord TOP_ACT = resumedAppLocked();
24212        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24213        final long now = SystemClock.uptimeMillis();
24214        final long nowElapsed = SystemClock.elapsedRealtime();
24215        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
24216        final int N = mLruProcesses.size();
24217
24218        if (false) {
24219            RuntimeException e = new RuntimeException();
24220            e.fillInStackTrace();
24221            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
24222        }
24223
24224        // Reset state in all uid records.
24225        for (int i=mActiveUids.size()-1; i>=0; i--) {
24226            final UidRecord uidRec = mActiveUids.valueAt(i);
24227            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24228                    "Starting update of " + uidRec);
24229            uidRec.reset();
24230        }
24231
24232        mStackSupervisor.rankTaskLayersIfNeeded();
24233
24234        mAdjSeq++;
24235        mNewNumServiceProcs = 0;
24236        mNewNumAServiceProcs = 0;
24237
24238        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
24239        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
24240
24241        // Let's determine how many processes we have running vs.
24242        // how many slots we have for background processes; we may want
24243        // to put multiple processes in a slot of there are enough of
24244        // them.
24245        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
24246                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
24247        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
24248        if (numEmptyProcs > cachedProcessLimit) {
24249            // If there are more empty processes than our limit on cached
24250            // processes, then use the cached process limit for the factor.
24251            // This ensures that the really old empty processes get pushed
24252            // down to the bottom, so if we are running low on memory we will
24253            // have a better chance at keeping around more cached processes
24254            // instead of a gazillion empty processes.
24255            numEmptyProcs = cachedProcessLimit;
24256        }
24257        int emptyFactor = numEmptyProcs/numSlots;
24258        if (emptyFactor < 1) emptyFactor = 1;
24259        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
24260        if (cachedFactor < 1) cachedFactor = 1;
24261        int stepCached = 0;
24262        int stepEmpty = 0;
24263        int numCached = 0;
24264        int numEmpty = 0;
24265        int numTrimming = 0;
24266
24267        mNumNonCachedProcs = 0;
24268        mNumCachedHiddenProcs = 0;
24269
24270        // First update the OOM adjustment for each of the
24271        // application processes based on their current state.
24272        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
24273        int nextCachedAdj = curCachedAdj+1;
24274        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
24275        int nextEmptyAdj = curEmptyAdj+2;
24276        for (int i=N-1; i>=0; i--) {
24277            ProcessRecord app = mLruProcesses.get(i);
24278            if (!app.killedByAm && app.thread != null) {
24279                app.procStateChanged = false;
24280                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
24281
24282                // If we haven't yet assigned the final cached adj
24283                // to the process, do that now.
24284                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
24285                    switch (app.curProcState) {
24286                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24287                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24288                        case ActivityManager.PROCESS_STATE_CACHED_RECENT:
24289                            // This process is a cached process holding activities...
24290                            // assign it the next cached value for that type, and then
24291                            // step that cached level.
24292                            app.curRawAdj = curCachedAdj;
24293                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
24294                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
24295                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
24296                                    + ")");
24297                            if (curCachedAdj != nextCachedAdj) {
24298                                stepCached++;
24299                                if (stepCached >= cachedFactor) {
24300                                    stepCached = 0;
24301                                    curCachedAdj = nextCachedAdj;
24302                                    nextCachedAdj += 2;
24303                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24304                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
24305                                    }
24306                                }
24307                            }
24308                            break;
24309                        default:
24310                            // For everything else, assign next empty cached process
24311                            // level and bump that up.  Note that this means that
24312                            // long-running services that have dropped down to the
24313                            // cached level will be treated as empty (since their process
24314                            // state is still as a service), which is what we want.
24315                            app.curRawAdj = curEmptyAdj;
24316                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
24317                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
24318                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
24319                                    + ")");
24320                            if (curEmptyAdj != nextEmptyAdj) {
24321                                stepEmpty++;
24322                                if (stepEmpty >= emptyFactor) {
24323                                    stepEmpty = 0;
24324                                    curEmptyAdj = nextEmptyAdj;
24325                                    nextEmptyAdj += 2;
24326                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24327                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
24328                                    }
24329                                }
24330                            }
24331                            break;
24332                    }
24333                }
24334
24335                applyOomAdjLocked(app, true, now, nowElapsed);
24336
24337                // Count the number of process types.
24338                switch (app.curProcState) {
24339                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24340                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24341                        mNumCachedHiddenProcs++;
24342                        numCached++;
24343                        if (numCached > cachedProcessLimit) {
24344                            app.kill("cached #" + numCached, true);
24345                        }
24346                        break;
24347                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
24348                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
24349                                && app.lastActivityTime < oldTime) {
24350                            app.kill("empty for "
24351                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
24352                                    / 1000) + "s", true);
24353                        } else {
24354                            numEmpty++;
24355                            if (numEmpty > emptyProcessLimit) {
24356                                app.kill("empty #" + numEmpty, true);
24357                            }
24358                        }
24359                        break;
24360                    default:
24361                        mNumNonCachedProcs++;
24362                        break;
24363                }
24364
24365                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
24366                    // If this is an isolated process, there are no services
24367                    // running in it, and it's not a special process with a
24368                    // custom entry point, then the process is no longer
24369                    // needed.  We agressively kill these because we can by
24370                    // definition not re-use the same process again, and it is
24371                    // good to avoid having whatever code was running in them
24372                    // left sitting around after no longer needed.
24373                    app.kill("isolated not needed", true);
24374                } else {
24375                    // Keeping this process, update its uid.
24376                    final UidRecord uidRec = app.uidRecord;
24377                    if (uidRec != null) {
24378                        uidRec.ephemeral = app.info.isInstantApp();
24379                        if (uidRec.curProcState > app.curProcState) {
24380                            uidRec.curProcState = app.curProcState;
24381                        }
24382                        if (app.foregroundServices) {
24383                            uidRec.foregroundServices = true;
24384                        }
24385                    }
24386                }
24387
24388                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24389                        && !app.killedByAm) {
24390                    numTrimming++;
24391                }
24392            }
24393        }
24394
24395        incrementProcStateSeqAndNotifyAppsLocked();
24396
24397        mNumServiceProcs = mNewNumServiceProcs;
24398
24399        // Now determine the memory trimming level of background processes.
24400        // Unfortunately we need to start at the back of the list to do this
24401        // properly.  We only do this if the number of background apps we
24402        // are managing to keep around is less than half the maximum we desire;
24403        // if we are keeping a good number around, we'll let them use whatever
24404        // memory they want.
24405        final int numCachedAndEmpty = numCached + numEmpty;
24406        int memFactor;
24407        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
24408                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
24409            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
24410                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
24411            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
24412                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
24413            } else {
24414                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
24415            }
24416        } else {
24417            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
24418        }
24419        // We always allow the memory level to go up (better).  We only allow it to go
24420        // down if we are in a state where that is allowed, *and* the total number of processes
24421        // has gone down since last time.
24422        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
24423                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
24424                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
24425        if (memFactor > mLastMemoryLevel) {
24426            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
24427                memFactor = mLastMemoryLevel;
24428                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
24429            }
24430        }
24431        if (memFactor != mLastMemoryLevel) {
24432            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
24433        }
24434        mLastMemoryLevel = memFactor;
24435        mLastNumProcesses = mLruProcesses.size();
24436        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
24437        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
24438        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
24439            if (mLowRamStartTime == 0) {
24440                mLowRamStartTime = now;
24441            }
24442            int step = 0;
24443            int fgTrimLevel;
24444            switch (memFactor) {
24445                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
24446                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
24447                    break;
24448                case ProcessStats.ADJ_MEM_FACTOR_LOW:
24449                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
24450                    break;
24451                default:
24452                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
24453                    break;
24454            }
24455            int factor = numTrimming/3;
24456            int minFactor = 2;
24457            if (mHomeProcess != null) minFactor++;
24458            if (mPreviousProcess != null) minFactor++;
24459            if (factor < minFactor) factor = minFactor;
24460            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
24461            for (int i=N-1; i>=0; i--) {
24462                ProcessRecord app = mLruProcesses.get(i);
24463                if (allChanged || app.procStateChanged) {
24464                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24465                    app.procStateChanged = false;
24466                }
24467                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24468                        && !app.killedByAm) {
24469                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
24470                        try {
24471                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24472                                    "Trimming memory of " + app.processName + " to " + curLevel);
24473                            app.thread.scheduleTrimMemory(curLevel);
24474                        } catch (RemoteException e) {
24475                        }
24476                        if (false) {
24477                            // For now we won't do this; our memory trimming seems
24478                            // to be good enough at this point that destroying
24479                            // activities causes more harm than good.
24480                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
24481                                    && app != mHomeProcess && app != mPreviousProcess) {
24482                                // Need to do this on its own message because the stack may not
24483                                // be in a consistent state at this point.
24484                                // For these apps we will also finish their activities
24485                                // to help them free memory.
24486                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
24487                            }
24488                        }
24489                    }
24490                    app.trimMemoryLevel = curLevel;
24491                    step++;
24492                    if (step >= factor) {
24493                        step = 0;
24494                        switch (curLevel) {
24495                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
24496                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
24497                                break;
24498                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
24499                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24500                                break;
24501                        }
24502                    }
24503                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
24504                        && !app.killedByAm) {
24505                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
24506                            && app.thread != null) {
24507                        try {
24508                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24509                                    "Trimming memory of heavy-weight " + app.processName
24510                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24511                            app.thread.scheduleTrimMemory(
24512                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24513                        } catch (RemoteException e) {
24514                        }
24515                    }
24516                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24517                } else {
24518                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24519                            || app.systemNoUi) && app.pendingUiClean) {
24520                        // If this application is now in the background and it
24521                        // had done UI, then give it the special trim level to
24522                        // have it free UI resources.
24523                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
24524                        if (app.trimMemoryLevel < level && app.thread != null) {
24525                            try {
24526                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24527                                        "Trimming memory of bg-ui " + app.processName
24528                                        + " to " + level);
24529                                app.thread.scheduleTrimMemory(level);
24530                            } catch (RemoteException e) {
24531                            }
24532                        }
24533                        app.pendingUiClean = false;
24534                    }
24535                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
24536                        try {
24537                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24538                                    "Trimming memory of fg " + app.processName
24539                                    + " to " + fgTrimLevel);
24540                            app.thread.scheduleTrimMemory(fgTrimLevel);
24541                        } catch (RemoteException e) {
24542                        }
24543                    }
24544                    app.trimMemoryLevel = fgTrimLevel;
24545                }
24546            }
24547        } else {
24548            if (mLowRamStartTime != 0) {
24549                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
24550                mLowRamStartTime = 0;
24551            }
24552            for (int i=N-1; i>=0; i--) {
24553                ProcessRecord app = mLruProcesses.get(i);
24554                if (allChanged || app.procStateChanged) {
24555                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24556                    app.procStateChanged = false;
24557                }
24558                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24559                        || app.systemNoUi) && app.pendingUiClean) {
24560                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
24561                            && app.thread != null) {
24562                        try {
24563                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24564                                    "Trimming memory of ui hidden " + app.processName
24565                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24566                            app.thread.scheduleTrimMemory(
24567                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24568                        } catch (RemoteException e) {
24569                        }
24570                    }
24571                    app.pendingUiClean = false;
24572                }
24573                app.trimMemoryLevel = 0;
24574            }
24575        }
24576
24577        if (mAlwaysFinishActivities) {
24578            // Need to do this on its own message because the stack may not
24579            // be in a consistent state at this point.
24580            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
24581        }
24582
24583        if (allChanged) {
24584            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
24585        }
24586
24587        ArrayList<UidRecord> becameIdle = null;
24588
24589        // Update from any uid changes.
24590        if (mLocalPowerManager != null) {
24591            mLocalPowerManager.startUidChanges();
24592        }
24593        for (int i=mActiveUids.size()-1; i>=0; i--) {
24594            final UidRecord uidRec = mActiveUids.valueAt(i);
24595            int uidChange = UidRecord.CHANGE_PROCSTATE;
24596            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
24597                    && (uidRec.setProcState != uidRec.curProcState
24598                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
24599                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24600                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
24601                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
24602                        + " to " + uidRec.curWhitelist);
24603                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
24604                        && !uidRec.curWhitelist) {
24605                    // UID is now in the background (and not on the temp whitelist).  Was it
24606                    // previously in the foreground (or on the temp whitelist)?
24607                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
24608                            || uidRec.setWhitelist) {
24609                        uidRec.lastBackgroundTime = nowElapsed;
24610                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
24611                            // Note: the background settle time is in elapsed realtime, while
24612                            // the handler time base is uptime.  All this means is that we may
24613                            // stop background uids later than we had intended, but that only
24614                            // happens because the device was sleeping so we are okay anyway.
24615                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24616                                    mConstants.BACKGROUND_SETTLE_TIME);
24617                        }
24618                    }
24619                    if (uidRec.idle && !uidRec.setIdle) {
24620                        uidChange = UidRecord.CHANGE_IDLE;
24621                        if (becameIdle == null) {
24622                            becameIdle = new ArrayList<>();
24623                        }
24624                        becameIdle.add(uidRec);
24625                    }
24626                } else {
24627                    if (uidRec.idle) {
24628                        uidChange = UidRecord.CHANGE_ACTIVE;
24629                        EventLogTags.writeAmUidActive(uidRec.uid);
24630                        uidRec.idle = false;
24631                    }
24632                    uidRec.lastBackgroundTime = 0;
24633                }
24634                final boolean wasCached = uidRec.setProcState
24635                        > ActivityManager.PROCESS_STATE_RECEIVER;
24636                final boolean isCached = uidRec.curProcState
24637                        > ActivityManager.PROCESS_STATE_RECEIVER;
24638                if (wasCached != isCached ||
24639                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
24640                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
24641                }
24642                uidRec.setProcState = uidRec.curProcState;
24643                uidRec.setWhitelist = uidRec.curWhitelist;
24644                uidRec.setIdle = uidRec.idle;
24645                enqueueUidChangeLocked(uidRec, -1, uidChange);
24646                noteUidProcessState(uidRec.uid, uidRec.curProcState);
24647                if (uidRec.foregroundServices) {
24648                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
24649                }
24650            }
24651        }
24652        if (mLocalPowerManager != null) {
24653            mLocalPowerManager.finishUidChanges();
24654        }
24655
24656        if (becameIdle != null) {
24657            // If we have any new uids that became idle this time, we need to make sure
24658            // they aren't left with running services.
24659            for (int i = becameIdle.size() - 1; i >= 0; i--) {
24660                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
24661            }
24662        }
24663
24664        if (mProcessStats.shouldWriteNowLocked(now)) {
24665            mHandler.post(new Runnable() {
24666                @Override public void run() {
24667                    synchronized (ActivityManagerService.this) {
24668                        mProcessStats.writeStateAsyncLocked();
24669                    }
24670                }
24671            });
24672        }
24673
24674        if (DEBUG_OOM_ADJ) {
24675            final long duration = SystemClock.uptimeMillis() - now;
24676            if (false) {
24677                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
24678                        new RuntimeException("here").fillInStackTrace());
24679            } else {
24680                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
24681            }
24682        }
24683    }
24684
24685    @Override
24686    public void makePackageIdle(String packageName, int userId) {
24687        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
24688                != PackageManager.PERMISSION_GRANTED) {
24689            String msg = "Permission Denial: makePackageIdle() from pid="
24690                    + Binder.getCallingPid()
24691                    + ", uid=" + Binder.getCallingUid()
24692                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
24693            Slog.w(TAG, msg);
24694            throw new SecurityException(msg);
24695        }
24696        final int callingPid = Binder.getCallingPid();
24697        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
24698                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
24699        long callingId = Binder.clearCallingIdentity();
24700        synchronized(this) {
24701            try {
24702                IPackageManager pm = AppGlobals.getPackageManager();
24703                int pkgUid = -1;
24704                try {
24705                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
24706                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
24707                } catch (RemoteException e) {
24708                }
24709                if (pkgUid == -1) {
24710                    throw new IllegalArgumentException("Unknown package name " + packageName);
24711                }
24712
24713                if (mLocalPowerManager != null) {
24714                    mLocalPowerManager.startUidChanges();
24715                }
24716                final int appId = UserHandle.getAppId(pkgUid);
24717                final int N = mActiveUids.size();
24718                for (int i=N-1; i>=0; i--) {
24719                    final UidRecord uidRec = mActiveUids.valueAt(i);
24720                    final long bgTime = uidRec.lastBackgroundTime;
24721                    if (bgTime > 0 && !uidRec.idle) {
24722                        if (UserHandle.getAppId(uidRec.uid) == appId) {
24723                            if (userId == UserHandle.USER_ALL ||
24724                                    userId == UserHandle.getUserId(uidRec.uid)) {
24725                                EventLogTags.writeAmUidIdle(uidRec.uid);
24726                                uidRec.idle = true;
24727                                uidRec.setIdle = true;
24728                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
24729                                        + " from package " + packageName + " user " + userId);
24730                                doStopUidLocked(uidRec.uid, uidRec);
24731                            }
24732                        }
24733                    }
24734                }
24735            } finally {
24736                if (mLocalPowerManager != null) {
24737                    mLocalPowerManager.finishUidChanges();
24738                }
24739                Binder.restoreCallingIdentity(callingId);
24740            }
24741        }
24742    }
24743
24744    final void idleUids() {
24745        synchronized (this) {
24746            final int N = mActiveUids.size();
24747            if (N <= 0) {
24748                return;
24749            }
24750            final long nowElapsed = SystemClock.elapsedRealtime();
24751            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
24752            long nextTime = 0;
24753            if (mLocalPowerManager != null) {
24754                mLocalPowerManager.startUidChanges();
24755            }
24756            for (int i=N-1; i>=0; i--) {
24757                final UidRecord uidRec = mActiveUids.valueAt(i);
24758                final long bgTime = uidRec.lastBackgroundTime;
24759                if (bgTime > 0 && !uidRec.idle) {
24760                    if (bgTime <= maxBgTime) {
24761                        EventLogTags.writeAmUidIdle(uidRec.uid);
24762                        uidRec.idle = true;
24763                        uidRec.setIdle = true;
24764                        doStopUidLocked(uidRec.uid, uidRec);
24765                    } else {
24766                        if (nextTime == 0 || nextTime > bgTime) {
24767                            nextTime = bgTime;
24768                        }
24769                    }
24770                }
24771            }
24772            if (mLocalPowerManager != null) {
24773                mLocalPowerManager.finishUidChanges();
24774            }
24775            if (nextTime > 0) {
24776                mHandler.removeMessages(IDLE_UIDS_MSG);
24777                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24778                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
24779            }
24780        }
24781    }
24782
24783    /**
24784     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
24785     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
24786     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
24787     */
24788    @VisibleForTesting
24789    @GuardedBy("this")
24790    void incrementProcStateSeqAndNotifyAppsLocked() {
24791        if (mWaitForNetworkTimeoutMs <= 0) {
24792            return;
24793        }
24794        // Used for identifying which uids need to block for network.
24795        ArrayList<Integer> blockingUids = null;
24796        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
24797            final UidRecord uidRec = mActiveUids.valueAt(i);
24798            // If the network is not restricted for uid, then nothing to do here.
24799            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
24800                continue;
24801            }
24802            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
24803                continue;
24804            }
24805            // If process state is not changed, then there's nothing to do.
24806            if (uidRec.setProcState == uidRec.curProcState) {
24807                continue;
24808            }
24809            final int blockState = getBlockStateForUid(uidRec);
24810            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
24811            // there's nothing the app needs to do in this scenario.
24812            if (blockState == NETWORK_STATE_NO_CHANGE) {
24813                continue;
24814            }
24815            synchronized (uidRec.networkStateLock) {
24816                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
24817                if (blockState == NETWORK_STATE_BLOCK) {
24818                    if (blockingUids == null) {
24819                        blockingUids = new ArrayList<>();
24820                    }
24821                    blockingUids.add(uidRec.uid);
24822                } else {
24823                    if (DEBUG_NETWORK) {
24824                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
24825                                + " threads for uid: " + uidRec);
24826                    }
24827                    if (uidRec.waitingForNetwork) {
24828                        uidRec.networkStateLock.notifyAll();
24829                    }
24830                }
24831            }
24832        }
24833
24834        // There are no uids that need to block, so nothing more to do.
24835        if (blockingUids == null) {
24836            return;
24837        }
24838
24839        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
24840            final ProcessRecord app = mLruProcesses.get(i);
24841            if (!blockingUids.contains(app.uid)) {
24842                continue;
24843            }
24844            if (!app.killedByAm && app.thread != null) {
24845                final UidRecord uidRec = mActiveUids.get(app.uid);
24846                try {
24847                    if (DEBUG_NETWORK) {
24848                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
24849                                + uidRec);
24850                    }
24851                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
24852                } catch (RemoteException ignored) {
24853                }
24854            }
24855        }
24856    }
24857
24858    /**
24859     * Checks if the uid is coming from background to foreground or vice versa and returns
24860     * appropriate block state based on this.
24861     *
24862     * @return blockState based on whether the uid is coming from background to foreground or
24863     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
24864     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
24865     *         {@link #NETWORK_STATE_NO_CHANGE}.
24866     */
24867    @VisibleForTesting
24868    int getBlockStateForUid(UidRecord uidRec) {
24869        // Denotes whether uid's process state is currently allowed network access.
24870        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
24871                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
24872        // Denotes whether uid's process state was previously allowed network access.
24873        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
24874                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
24875
24876        // When the uid is coming to foreground, AMS should inform the app thread that it should
24877        // block for the network rules to get updated before launching an activity.
24878        if (!wasAllowed && isAllowed) {
24879            return NETWORK_STATE_BLOCK;
24880        }
24881        // When the uid is going to background, AMS should inform the app thread that if an
24882        // activity launch is blocked for the network rules to get updated, it should be unblocked.
24883        if (wasAllowed && !isAllowed) {
24884            return NETWORK_STATE_UNBLOCK;
24885        }
24886        return NETWORK_STATE_NO_CHANGE;
24887    }
24888
24889    final void runInBackgroundDisabled(int uid) {
24890        synchronized (this) {
24891            UidRecord uidRec = mActiveUids.get(uid);
24892            if (uidRec != null) {
24893                // This uid is actually running...  should it be considered background now?
24894                if (uidRec.idle) {
24895                    doStopUidLocked(uidRec.uid, uidRec);
24896                }
24897            } else {
24898                // This uid isn't actually running...  still send a report about it being "stopped".
24899                doStopUidLocked(uid, null);
24900            }
24901        }
24902    }
24903
24904    /**
24905     * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
24906     */
24907    void doStopUidForIdleUidsLocked() {
24908        final int size = mActiveUids.size();
24909        for (int i = 0; i < size; i++) {
24910            final int uid = mActiveUids.keyAt(i);
24911            if (UserHandle.isCore(uid)) {
24912                continue;
24913            }
24914            final UidRecord uidRec = mActiveUids.valueAt(i);
24915            if (!uidRec.idle) {
24916                continue;
24917            }
24918            doStopUidLocked(uidRec.uid, uidRec);
24919        }
24920    }
24921
24922    final void doStopUidLocked(int uid, final UidRecord uidRec) {
24923        mServices.stopInBackgroundLocked(uid);
24924        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
24925    }
24926
24927    /**
24928     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
24929     */
24930    @GuardedBy("this")
24931    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
24932            long duration, String tag) {
24933        if (DEBUG_WHITELISTS) {
24934            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
24935                    + targetUid + ", " + duration + ")");
24936        }
24937
24938        synchronized (mPidsSelfLocked) {
24939            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
24940            if (pr == null) {
24941                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
24942                        + callerPid);
24943                return;
24944            }
24945            if (!pr.whitelistManager) {
24946                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
24947                        != PackageManager.PERMISSION_GRANTED) {
24948                    if (DEBUG_WHITELISTS) {
24949                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
24950                                + ": pid " + callerPid + " is not allowed");
24951                    }
24952                    return;
24953                }
24954            }
24955        }
24956
24957        tempWhitelistUidLocked(targetUid, duration, tag);
24958    }
24959
24960    /**
24961     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
24962     */
24963    @GuardedBy("this")
24964    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
24965        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
24966        setUidTempWhitelistStateLocked(targetUid, true);
24967        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
24968    }
24969
24970    void pushTempWhitelist() {
24971        final int N;
24972        final PendingTempWhitelist[] list;
24973
24974        // First copy out the pending changes...  we need to leave them in the map for now,
24975        // in case someone needs to check what is coming up while we don't have the lock held.
24976        synchronized(this) {
24977            N = mPendingTempWhitelist.size();
24978            list = new PendingTempWhitelist[N];
24979            for (int i = 0; i < N; i++) {
24980                list[i] = mPendingTempWhitelist.valueAt(i);
24981            }
24982        }
24983
24984        // Now safely dispatch changes to device idle controller.
24985        for (int i = 0; i < N; i++) {
24986            PendingTempWhitelist ptw = list[i];
24987            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
24988                    ptw.duration, true, ptw.tag);
24989        }
24990
24991        // And now we can safely remove them from the map.
24992        synchronized(this) {
24993            for (int i = 0; i < N; i++) {
24994                PendingTempWhitelist ptw = list[i];
24995                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
24996                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
24997                    mPendingTempWhitelist.removeAt(index);
24998                }
24999            }
25000        }
25001    }
25002
25003    @GuardedBy("this")
25004    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
25005        boolean changed = false;
25006        for (int i=mActiveUids.size()-1; i>=0; i--) {
25007            final UidRecord uidRec = mActiveUids.valueAt(i);
25008            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
25009                uidRec.curWhitelist = onWhitelist;
25010                changed = true;
25011            }
25012        }
25013        if (changed) {
25014            updateOomAdjLocked();
25015        }
25016    }
25017
25018    @GuardedBy("this")
25019    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
25020        boolean changed = false;
25021        final UidRecord uidRec = mActiveUids.get(uid);
25022        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
25023            uidRec.curWhitelist = onWhitelist;
25024            updateOomAdjLocked();
25025        }
25026    }
25027
25028    final void trimApplications() {
25029        synchronized (this) {
25030            int i;
25031
25032            // First remove any unused application processes whose package
25033            // has been removed.
25034            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
25035                final ProcessRecord app = mRemovedProcesses.get(i);
25036                if (app.activities.size() == 0 && app.recentTasks.size() == 0
25037                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
25038                    Slog.i(
25039                        TAG, "Exiting empty application process "
25040                        + app.toShortString() + " ("
25041                        + (app.thread != null ? app.thread.asBinder() : null)
25042                        + ")\n");
25043                    if (app.pid > 0 && app.pid != MY_PID) {
25044                        app.kill("empty", false);
25045                    } else if (app.thread != null) {
25046                        try {
25047                            app.thread.scheduleExit();
25048                        } catch (Exception e) {
25049                            // Ignore exceptions.
25050                        }
25051                    }
25052                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
25053                    mRemovedProcesses.remove(i);
25054
25055                    if (app.persistent) {
25056                        addAppLocked(app.info, null, false, null /* ABI override */);
25057                    }
25058                }
25059            }
25060
25061            // Now update the oom adj for all processes.
25062            updateOomAdjLocked();
25063        }
25064    }
25065
25066    /** This method sends the specified signal to each of the persistent apps */
25067    public void signalPersistentProcesses(int sig) throws RemoteException {
25068        if (sig != SIGNAL_USR1) {
25069            throw new SecurityException("Only SIGNAL_USR1 is allowed");
25070        }
25071
25072        synchronized (this) {
25073            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
25074                    != PackageManager.PERMISSION_GRANTED) {
25075                throw new SecurityException("Requires permission "
25076                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
25077            }
25078
25079            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
25080                ProcessRecord r = mLruProcesses.get(i);
25081                if (r.thread != null && r.persistent) {
25082                    sendSignal(r.pid, sig);
25083                }
25084            }
25085        }
25086    }
25087
25088    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
25089        if (proc == null || proc == mProfileProc) {
25090            proc = mProfileProc;
25091            profileType = mProfileType;
25092            clearProfilerLocked();
25093        }
25094        if (proc == null) {
25095            return;
25096        }
25097        try {
25098            proc.thread.profilerControl(false, null, profileType);
25099        } catch (RemoteException e) {
25100            throw new IllegalStateException("Process disappeared");
25101        }
25102    }
25103
25104    private void clearProfilerLocked() {
25105        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
25106            try {
25107                mProfilerInfo.profileFd.close();
25108            } catch (IOException e) {
25109            }
25110        }
25111        mProfileApp = null;
25112        mProfileProc = null;
25113        mProfilerInfo = null;
25114    }
25115
25116    public boolean profileControl(String process, int userId, boolean start,
25117            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
25118
25119        try {
25120            synchronized (this) {
25121                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25122                // its own permission.
25123                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25124                        != PackageManager.PERMISSION_GRANTED) {
25125                    throw new SecurityException("Requires permission "
25126                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25127                }
25128
25129                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
25130                    throw new IllegalArgumentException("null profile info or fd");
25131                }
25132
25133                ProcessRecord proc = null;
25134                if (process != null) {
25135                    proc = findProcessLocked(process, userId, "profileControl");
25136                }
25137
25138                if (start && (proc == null || proc.thread == null)) {
25139                    throw new IllegalArgumentException("Unknown process: " + process);
25140                }
25141
25142                if (start) {
25143                    stopProfilerLocked(null, 0);
25144                    setProfileApp(proc.info, proc.processName, profilerInfo);
25145                    mProfileProc = proc;
25146                    mProfileType = profileType;
25147                    ParcelFileDescriptor fd = profilerInfo.profileFd;
25148                    try {
25149                        fd = fd.dup();
25150                    } catch (IOException e) {
25151                        fd = null;
25152                    }
25153                    profilerInfo.profileFd = fd;
25154                    proc.thread.profilerControl(start, profilerInfo, profileType);
25155                    fd = null;
25156                    try {
25157                        mProfilerInfo.profileFd.close();
25158                    } catch (IOException e) {
25159                    }
25160                    mProfilerInfo.profileFd = null;
25161                } else {
25162                    stopProfilerLocked(proc, profileType);
25163                    if (profilerInfo != null && profilerInfo.profileFd != null) {
25164                        try {
25165                            profilerInfo.profileFd.close();
25166                        } catch (IOException e) {
25167                        }
25168                    }
25169                }
25170
25171                return true;
25172            }
25173        } catch (RemoteException e) {
25174            throw new IllegalStateException("Process disappeared");
25175        } finally {
25176            if (profilerInfo != null && profilerInfo.profileFd != null) {
25177                try {
25178                    profilerInfo.profileFd.close();
25179                } catch (IOException e) {
25180                }
25181            }
25182        }
25183    }
25184
25185    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
25186        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
25187                userId, true, ALLOW_FULL_ONLY, callName, null);
25188        ProcessRecord proc = null;
25189        try {
25190            int pid = Integer.parseInt(process);
25191            synchronized (mPidsSelfLocked) {
25192                proc = mPidsSelfLocked.get(pid);
25193            }
25194        } catch (NumberFormatException e) {
25195        }
25196
25197        if (proc == null) {
25198            ArrayMap<String, SparseArray<ProcessRecord>> all
25199                    = mProcessNames.getMap();
25200            SparseArray<ProcessRecord> procs = all.get(process);
25201            if (procs != null && procs.size() > 0) {
25202                proc = procs.valueAt(0);
25203                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
25204                    for (int i=1; i<procs.size(); i++) {
25205                        ProcessRecord thisProc = procs.valueAt(i);
25206                        if (thisProc.userId == userId) {
25207                            proc = thisProc;
25208                            break;
25209                        }
25210                    }
25211                }
25212            }
25213        }
25214
25215        return proc;
25216    }
25217
25218    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
25219            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
25220
25221        try {
25222            synchronized (this) {
25223                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25224                // its own permission (same as profileControl).
25225                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25226                        != PackageManager.PERMISSION_GRANTED) {
25227                    throw new SecurityException("Requires permission "
25228                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25229                }
25230
25231                if (fd == null) {
25232                    throw new IllegalArgumentException("null fd");
25233                }
25234
25235                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
25236                if (proc == null || proc.thread == null) {
25237                    throw new IllegalArgumentException("Unknown process: " + process);
25238                }
25239
25240                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25241                if (!isDebuggable) {
25242                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25243                        throw new SecurityException("Process not debuggable: " + proc);
25244                    }
25245                }
25246
25247                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
25248                fd = null;
25249                return true;
25250            }
25251        } catch (RemoteException e) {
25252            throw new IllegalStateException("Process disappeared");
25253        } finally {
25254            if (fd != null) {
25255                try {
25256                    fd.close();
25257                } catch (IOException e) {
25258                }
25259            }
25260        }
25261    }
25262
25263    @Override
25264    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
25265            String reportPackage) {
25266        if (processName != null) {
25267            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
25268                    "setDumpHeapDebugLimit()");
25269        } else {
25270            synchronized (mPidsSelfLocked) {
25271                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
25272                if (proc == null) {
25273                    throw new SecurityException("No process found for calling pid "
25274                            + Binder.getCallingPid());
25275                }
25276                if (!Build.IS_DEBUGGABLE
25277                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25278                    throw new SecurityException("Not running a debuggable build");
25279                }
25280                processName = proc.processName;
25281                uid = proc.uid;
25282                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
25283                    throw new SecurityException("Package " + reportPackage + " is not running in "
25284                            + proc);
25285                }
25286            }
25287        }
25288        synchronized (this) {
25289            if (maxMemSize > 0) {
25290                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
25291            } else {
25292                if (uid != 0) {
25293                    mMemWatchProcesses.remove(processName, uid);
25294                } else {
25295                    mMemWatchProcesses.getMap().remove(processName);
25296                }
25297            }
25298        }
25299    }
25300
25301    @Override
25302    public void dumpHeapFinished(String path) {
25303        synchronized (this) {
25304            if (Binder.getCallingPid() != mMemWatchDumpPid) {
25305                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
25306                        + " does not match last pid " + mMemWatchDumpPid);
25307                return;
25308            }
25309            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
25310                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
25311                        + " does not match last path " + mMemWatchDumpFile);
25312                return;
25313            }
25314            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
25315            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
25316
25317            // Forced gc to clean up the remnant hprof fd.
25318            Runtime.getRuntime().gc();
25319        }
25320    }
25321
25322    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
25323    public void monitor() {
25324        synchronized (this) { }
25325    }
25326
25327    void onCoreSettingsChange(Bundle settings) {
25328        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
25329            ProcessRecord processRecord = mLruProcesses.get(i);
25330            try {
25331                if (processRecord.thread != null) {
25332                    processRecord.thread.setCoreSettings(settings);
25333                }
25334            } catch (RemoteException re) {
25335                /* ignore */
25336            }
25337        }
25338    }
25339
25340    // Multi-user methods
25341
25342    /**
25343     * Start user, if its not already running, but don't bring it to foreground.
25344     */
25345    @Override
25346    public boolean startUserInBackground(final int userId) {
25347        return startUserInBackgroundWithListener(userId, null);
25348    }
25349
25350    @Override
25351    public boolean startUserInBackgroundWithListener(final int userId,
25352                @Nullable IProgressListener unlockListener) {
25353        return mUserController.startUser(userId, /* foreground */ false, unlockListener);
25354    }
25355
25356    @Override
25357    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
25358        return mUserController.unlockUser(userId, token, secret, listener);
25359    }
25360
25361    @Override
25362    public boolean switchUser(final int targetUserId) {
25363        return mUserController.switchUser(targetUserId);
25364    }
25365
25366    @Override
25367    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
25368        return mUserController.stopUser(userId, force, callback);
25369    }
25370
25371    @Override
25372    public UserInfo getCurrentUser() {
25373        return mUserController.getCurrentUser();
25374    }
25375
25376    String getStartedUserState(int userId) {
25377        final UserState userState = mUserController.getStartedUserState(userId);
25378        return UserState.stateToString(userState.state);
25379    }
25380
25381    @Override
25382    public boolean isUserRunning(int userId, int flags) {
25383        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
25384                && checkCallingPermission(INTERACT_ACROSS_USERS)
25385                    != PackageManager.PERMISSION_GRANTED) {
25386            String msg = "Permission Denial: isUserRunning() from pid="
25387                    + Binder.getCallingPid()
25388                    + ", uid=" + Binder.getCallingUid()
25389                    + " requires " + INTERACT_ACROSS_USERS;
25390            Slog.w(TAG, msg);
25391            throw new SecurityException(msg);
25392        }
25393        return mUserController.isUserRunning(userId, flags);
25394    }
25395
25396    @Override
25397    public int[] getRunningUserIds() {
25398        if (checkCallingPermission(INTERACT_ACROSS_USERS)
25399                != PackageManager.PERMISSION_GRANTED) {
25400            String msg = "Permission Denial: isUserRunning() from pid="
25401                    + Binder.getCallingPid()
25402                    + ", uid=" + Binder.getCallingUid()
25403                    + " requires " + INTERACT_ACROSS_USERS;
25404            Slog.w(TAG, msg);
25405            throw new SecurityException(msg);
25406        }
25407        return mUserController.getStartedUserArray();
25408    }
25409
25410    @Override
25411    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
25412        mUserController.registerUserSwitchObserver(observer, name);
25413    }
25414
25415    @Override
25416    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
25417        mUserController.unregisterUserSwitchObserver(observer);
25418    }
25419
25420    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
25421        if (info == null) return null;
25422        ApplicationInfo newInfo = new ApplicationInfo(info);
25423        newInfo.initForUser(userId);
25424        return newInfo;
25425    }
25426
25427    public boolean isUserStopped(int userId) {
25428        return mUserController.getStartedUserState(userId) == null;
25429    }
25430
25431    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
25432        if (aInfo == null
25433                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
25434            return aInfo;
25435        }
25436
25437        ActivityInfo info = new ActivityInfo(aInfo);
25438        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
25439        return info;
25440    }
25441
25442    private boolean processSanityChecksLocked(ProcessRecord process) {
25443        if (process == null || process.thread == null) {
25444            return false;
25445        }
25446
25447        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25448        if (!isDebuggable) {
25449            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25450                return false;
25451            }
25452        }
25453
25454        return true;
25455    }
25456
25457    public boolean startBinderTracking() throws RemoteException {
25458        synchronized (this) {
25459            mBinderTransactionTrackingEnabled = true;
25460            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25461            // permission (same as profileControl).
25462            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25463                    != PackageManager.PERMISSION_GRANTED) {
25464                throw new SecurityException("Requires permission "
25465                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25466            }
25467
25468            for (int i = 0; i < mLruProcesses.size(); i++) {
25469                ProcessRecord process = mLruProcesses.get(i);
25470                if (!processSanityChecksLocked(process)) {
25471                    continue;
25472                }
25473                try {
25474                    process.thread.startBinderTracking();
25475                } catch (RemoteException e) {
25476                    Log.v(TAG, "Process disappared");
25477                }
25478            }
25479            return true;
25480        }
25481    }
25482
25483    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
25484        try {
25485            synchronized (this) {
25486                mBinderTransactionTrackingEnabled = false;
25487                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25488                // permission (same as profileControl).
25489                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25490                        != PackageManager.PERMISSION_GRANTED) {
25491                    throw new SecurityException("Requires permission "
25492                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25493                }
25494
25495                if (fd == null) {
25496                    throw new IllegalArgumentException("null fd");
25497                }
25498
25499                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
25500                pw.println("Binder transaction traces for all processes.\n");
25501                for (ProcessRecord process : mLruProcesses) {
25502                    if (!processSanityChecksLocked(process)) {
25503                        continue;
25504                    }
25505
25506                    pw.println("Traces for process: " + process.processName);
25507                    pw.flush();
25508                    try {
25509                        TransferPipe tp = new TransferPipe();
25510                        try {
25511                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
25512                            tp.go(fd.getFileDescriptor());
25513                        } finally {
25514                            tp.kill();
25515                        }
25516                    } catch (IOException e) {
25517                        pw.println("Failure while dumping IPC traces from " + process +
25518                                ".  Exception: " + e);
25519                        pw.flush();
25520                    } catch (RemoteException e) {
25521                        pw.println("Got a RemoteException while dumping IPC traces from " +
25522                                process + ".  Exception: " + e);
25523                        pw.flush();
25524                    }
25525                }
25526                fd = null;
25527                return true;
25528            }
25529        } finally {
25530            if (fd != null) {
25531                try {
25532                    fd.close();
25533                } catch (IOException e) {
25534                }
25535            }
25536        }
25537    }
25538
25539    @VisibleForTesting
25540    final class LocalService extends ActivityManagerInternal {
25541        @Override
25542        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
25543                int targetUserId) {
25544            synchronized (ActivityManagerService.this) {
25545                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
25546                        targetPkg, intent, null, targetUserId);
25547            }
25548        }
25549
25550        @Override
25551        public String checkContentProviderAccess(String authority, int userId) {
25552            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
25553        }
25554
25555        @Override
25556        public void onWakefulnessChanged(int wakefulness) {
25557            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
25558        }
25559
25560        @Override
25561        public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
25562                String processName, String abiOverride, int uid, Runnable crashHandler) {
25563            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
25564                    processName, abiOverride, uid, crashHandler);
25565        }
25566
25567        @Override
25568        public SleepToken acquireSleepToken(String tag, int displayId) {
25569            Preconditions.checkNotNull(tag);
25570            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
25571        }
25572
25573        @Override
25574        public ComponentName getHomeActivityForUser(int userId) {
25575            synchronized (ActivityManagerService.this) {
25576                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
25577                return homeActivity == null ? null : homeActivity.realActivity;
25578            }
25579        }
25580
25581        @Override
25582        public void onUserRemoved(int userId) {
25583            synchronized (ActivityManagerService.this) {
25584                ActivityManagerService.this.onUserStoppedLocked(userId);
25585            }
25586            mBatteryStatsService.onUserRemoved(userId);
25587            mUserController.onUserRemoved(userId);
25588        }
25589
25590        @Override
25591        public void onLocalVoiceInteractionStarted(IBinder activity,
25592                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
25593            synchronized (ActivityManagerService.this) {
25594                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
25595                        voiceSession, voiceInteractor);
25596            }
25597        }
25598
25599        @Override
25600        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
25601            synchronized (ActivityManagerService.this) {
25602                mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
25603                        reasons, timestamp);
25604            }
25605        }
25606
25607        @Override
25608        public void notifyAppTransitionFinished() {
25609            synchronized (ActivityManagerService.this) {
25610                mStackSupervisor.notifyAppTransitionDone();
25611                mKeyguardController.notifyAppTransitionDone();
25612            }
25613        }
25614
25615        @Override
25616        public void notifyAppTransitionCancelled() {
25617            synchronized (ActivityManagerService.this) {
25618                mStackSupervisor.notifyAppTransitionDone();
25619            }
25620        }
25621
25622        @Override
25623        public List<IBinder> getTopVisibleActivities() {
25624            synchronized (ActivityManagerService.this) {
25625                return mStackSupervisor.getTopVisibleActivities();
25626            }
25627        }
25628
25629        @Override
25630        public void notifyDockedStackMinimizedChanged(boolean minimized) {
25631            synchronized (ActivityManagerService.this) {
25632                mStackSupervisor.setDockedStackMinimized(minimized);
25633            }
25634        }
25635
25636        @Override
25637        public void killForegroundAppsForUser(int userHandle) {
25638            synchronized (ActivityManagerService.this) {
25639                final ArrayList<ProcessRecord> procs = new ArrayList<>();
25640                final int NP = mProcessNames.getMap().size();
25641                for (int ip = 0; ip < NP; ip++) {
25642                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
25643                    final int NA = apps.size();
25644                    for (int ia = 0; ia < NA; ia++) {
25645                        final ProcessRecord app = apps.valueAt(ia);
25646                        if (app.persistent) {
25647                            // We don't kill persistent processes.
25648                            continue;
25649                        }
25650                        if (app.removed) {
25651                            procs.add(app);
25652                        } else if (app.userId == userHandle && app.foregroundActivities) {
25653                            app.removed = true;
25654                            procs.add(app);
25655                        }
25656                    }
25657                }
25658
25659                final int N = procs.size();
25660                for (int i = 0; i < N; i++) {
25661                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
25662                }
25663            }
25664        }
25665
25666        @Override
25667        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
25668                long duration) {
25669            if (!(target instanceof PendingIntentRecord)) {
25670                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
25671                return;
25672            }
25673            synchronized (ActivityManagerService.this) {
25674                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
25675            }
25676        }
25677
25678        @Override
25679        public void setDeviceIdleWhitelist(int[] appids) {
25680            synchronized (ActivityManagerService.this) {
25681                mDeviceIdleWhitelist = appids;
25682            }
25683        }
25684
25685        @Override
25686        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
25687            synchronized (ActivityManagerService.this) {
25688                mDeviceIdleTempWhitelist = appids;
25689                setAppIdTempWhitelistStateLocked(changingAppId, adding);
25690            }
25691        }
25692
25693        @Override
25694        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
25695                int userId) {
25696            Preconditions.checkNotNull(values, "Configuration must not be null");
25697            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
25698            synchronized (ActivityManagerService.this) {
25699                updateConfigurationLocked(values, null, false, true, userId,
25700                        false /* deferResume */);
25701            }
25702        }
25703
25704        @Override
25705        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
25706                Bundle bOptions) {
25707            Preconditions.checkNotNull(intents, "intents");
25708            final String[] resolvedTypes = new String[intents.length];
25709            for (int i = 0; i < intents.length; i++) {
25710                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
25711            }
25712
25713            // UID of the package on user userId.
25714            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
25715            // packageUid may not be initialized.
25716            int packageUid = 0;
25717            final long ident = Binder.clearCallingIdentity();
25718            try {
25719                packageUid = AppGlobals.getPackageManager().getPackageUid(
25720                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
25721            } catch (RemoteException e) {
25722                // Shouldn't happen.
25723            } finally {
25724                Binder.restoreCallingIdentity(ident);
25725            }
25726
25727            synchronized (ActivityManagerService.this) {
25728                return mActivityStartController.startActivitiesInPackage(
25729                        packageUid, packageName,
25730                        intents, resolvedTypes, null /* resultTo */,
25731                        SafeActivityOptions.fromBundle(bOptions), userId,
25732                        false /* validateIncomingUser */);
25733            }
25734        }
25735
25736        @Override
25737        public int getUidProcessState(int uid) {
25738            return getUidState(uid);
25739        }
25740
25741        @Override
25742        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
25743            synchronized (ActivityManagerService.this) {
25744
25745                // We might change the visibilities here, so prepare an empty app transition which
25746                // might be overridden later if we actually change visibilities.
25747                final boolean wasTransitionSet =
25748                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
25749                if (!wasTransitionSet) {
25750                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
25751                            false /* alwaysKeepCurrent */);
25752                }
25753                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
25754
25755                // If there was a transition set already we don't want to interfere with it as we
25756                // might be starting it too early.
25757                if (!wasTransitionSet) {
25758                    mWindowManager.executeAppTransition();
25759                }
25760            }
25761            if (callback != null) {
25762                callback.run();
25763            }
25764        }
25765
25766        @Override
25767        public boolean isSystemReady() {
25768            // no need to synchronize(this) just to read & return the value
25769            return mSystemReady;
25770        }
25771
25772        @Override
25773        public void notifyKeyguardTrustedChanged() {
25774            synchronized (ActivityManagerService.this) {
25775                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
25776                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
25777                }
25778            }
25779        }
25780
25781        /**
25782         * Sets if the given pid has an overlay UI or not.
25783         *
25784         * @param pid The pid we are setting overlay UI for.
25785         * @param hasOverlayUi True if the process has overlay UI.
25786         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
25787         */
25788        @Override
25789        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
25790            synchronized (ActivityManagerService.this) {
25791                final ProcessRecord pr;
25792                synchronized (mPidsSelfLocked) {
25793                    pr = mPidsSelfLocked.get(pid);
25794                    if (pr == null) {
25795                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
25796                        return;
25797                    }
25798                }
25799                if (pr.hasOverlayUi == hasOverlayUi) {
25800                    return;
25801                }
25802                pr.hasOverlayUi = hasOverlayUi;
25803                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
25804                updateOomAdjLocked(pr, true);
25805            }
25806        }
25807
25808        /**
25809         * Called after the network policy rules are updated by
25810         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
25811         * and {@param procStateSeq}.
25812         */
25813        @Override
25814        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
25815            if (DEBUG_NETWORK) {
25816                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
25817                        + uid + " seq: " + procStateSeq);
25818            }
25819            UidRecord record;
25820            synchronized (ActivityManagerService.this) {
25821                record = mActiveUids.get(uid);
25822                if (record == null) {
25823                    if (DEBUG_NETWORK) {
25824                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
25825                                + " procStateSeq: " + procStateSeq);
25826                    }
25827                    return;
25828                }
25829            }
25830            synchronized (record.networkStateLock) {
25831                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
25832                    if (DEBUG_NETWORK) {
25833                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
25834                                + " been handled for uid: " + uid);
25835                    }
25836                    return;
25837                }
25838                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
25839                if (record.curProcStateSeq > procStateSeq) {
25840                    if (DEBUG_NETWORK) {
25841                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
25842                                + ", curProcstateSeq: " + record.curProcStateSeq
25843                                + ", procStateSeq: " + procStateSeq);
25844                    }
25845                    return;
25846                }
25847                if (record.waitingForNetwork) {
25848                    if (DEBUG_NETWORK) {
25849                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
25850                                + ", procStateSeq: " + procStateSeq);
25851                    }
25852                    record.networkStateLock.notifyAll();
25853                }
25854            }
25855        }
25856
25857        @Override
25858        public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
25859            synchronized (ActivityManagerService.this) {
25860                mActiveVoiceInteractionServiceComponent = component;
25861            }
25862        }
25863
25864        /**
25865         * Called after virtual display Id is updated by
25866         * {@link com.android.server.vr.Vr2dDisplay} with a specific
25867         * {@param vrVr2dDisplayId}.
25868         */
25869        @Override
25870        public void setVr2dDisplayId(int vr2dDisplayId) {
25871            if (DEBUG_STACK) {
25872                Slog.d(TAG, "setVr2dDisplayId called for: " +
25873                        vr2dDisplayId);
25874            }
25875            synchronized (ActivityManagerService.this) {
25876                mVr2dDisplayId = vr2dDisplayId;
25877            }
25878        }
25879
25880        @Override
25881        public void saveANRState(String reason) {
25882            synchronized (ActivityManagerService.this) {
25883                final StringWriter sw = new StringWriter();
25884                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
25885                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
25886                if (reason != null) {
25887                    pw.println("  Reason: " + reason);
25888                }
25889                pw.println();
25890                mActivityStartController.dump(pw, "  ", null);
25891                pw.println();
25892                pw.println("-------------------------------------------------------------------------------");
25893                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
25894                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
25895                        "" /* header */);
25896                pw.println();
25897                pw.close();
25898
25899                mLastANRState = sw.toString();
25900            }
25901        }
25902
25903        @Override
25904        public void clearSavedANRState() {
25905            synchronized (ActivityManagerService.this) {
25906                mLastANRState = null;
25907            }
25908        }
25909
25910        @Override
25911        public void setFocusedActivity(IBinder token) {
25912            synchronized (ActivityManagerService.this) {
25913                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
25914                if (r == null) {
25915                    throw new IllegalArgumentException(
25916                            "setFocusedActivity: No activity record matching token=" + token);
25917                }
25918                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
25919                        r, "setFocusedActivity")) {
25920                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
25921                }
25922            }
25923        }
25924
25925        @Override
25926        public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
25927            synchronized (ActivityManagerService.this) {
25928                if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
25929                    ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
25930                    if (types == null) {
25931                        if (uid < 0) {
25932                            return;
25933                        }
25934                        types = new ArrayMap<>();
25935                        mAllowAppSwitchUids.put(userId, types);
25936                    }
25937                    if (uid < 0) {
25938                        types.remove(type);
25939                    } else {
25940                        types.put(type, uid);
25941                    }
25942                }
25943            }
25944        }
25945
25946        @Override
25947        public boolean isRuntimeRestarted() {
25948            return mSystemServiceManager.isRuntimeRestarted();
25949        }
25950
25951        @Override
25952        public boolean hasRunningActivity(int uid, @Nullable String packageName) {
25953            if (packageName == null) return false;
25954
25955            synchronized (ActivityManagerService.this) {
25956                for (int i = 0; i < mLruProcesses.size(); i++) {
25957                    final ProcessRecord processRecord = mLruProcesses.get(i);
25958                    if (processRecord.uid == uid) {
25959                        for (int j = 0; j < processRecord.activities.size(); j++) {
25960                            final ActivityRecord activityRecord = processRecord.activities.get(j);
25961                            if (packageName.equals(activityRecord.packageName)) {
25962                                return true;
25963                            }
25964                        }
25965                    }
25966                }
25967            }
25968            return false;
25969        }
25970
25971        @Override
25972        public void registerScreenObserver(ScreenObserver observer) {
25973            mScreenObservers.add(observer);
25974        }
25975
25976        @Override
25977        public boolean canStartMoreUsers() {
25978            return mUserController.canStartMoreUsers();
25979        }
25980
25981        @Override
25982        public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
25983            mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
25984        }
25985
25986        @Override
25987        public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
25988            mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
25989        }
25990
25991        @Override
25992        public int getMaxRunningUsers() {
25993            return mUserController.mMaxRunningUsers;
25994        }
25995
25996        public boolean isCallerRecents(int callingUid) {
25997            return getRecentTasks().isCallerRecents(callingUid);
25998        }
25999
26000        @Override
26001        public boolean isUidActive(int uid) {
26002            synchronized (ActivityManagerService.this) {
26003                final UidRecord uidRec = mActiveUids.get(uid);
26004                return (uidRec != null) && !uidRec.idle;
26005            }
26006        }
26007    }
26008
26009    /**
26010     * Called by app main thread to wait for the network policy rules to get updated.
26011     *
26012     * @param procStateSeq The sequence number indicating the process state change that the main
26013     *                     thread is interested in.
26014     */
26015    @Override
26016    public void waitForNetworkStateUpdate(long procStateSeq) {
26017        final int callingUid = Binder.getCallingUid();
26018        if (DEBUG_NETWORK) {
26019            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
26020        }
26021        UidRecord record;
26022        synchronized (this) {
26023            record = mActiveUids.get(callingUid);
26024            if (record == null) {
26025                return;
26026            }
26027        }
26028        synchronized (record.networkStateLock) {
26029            if (record.lastDispatchedProcStateSeq < procStateSeq) {
26030                if (DEBUG_NETWORK) {
26031                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
26032                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
26033                            + " lastProcStateSeqDispatchedToObservers: "
26034                            + record.lastDispatchedProcStateSeq);
26035                }
26036                return;
26037            }
26038            if (record.curProcStateSeq > procStateSeq) {
26039                if (DEBUG_NETWORK) {
26040                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
26041                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
26042                            + ", procStateSeq: " + procStateSeq);
26043                }
26044                return;
26045            }
26046            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26047                if (DEBUG_NETWORK) {
26048                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
26049                            + procStateSeq + ", so no need to wait. Uid: "
26050                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
26051                            + record.lastNetworkUpdatedProcStateSeq);
26052                }
26053                return;
26054            }
26055            try {
26056                if (DEBUG_NETWORK) {
26057                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
26058                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
26059                }
26060                final long startTime = SystemClock.uptimeMillis();
26061                record.waitingForNetwork = true;
26062                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
26063                record.waitingForNetwork = false;
26064                final long totalTime = SystemClock.uptimeMillis() - startTime;
26065                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
26066                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
26067                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
26068                            + procStateSeq + " UidRec: " + record
26069                            + " validateUidRec: " + mValidateUids.get(callingUid));
26070                }
26071            } catch (InterruptedException e) {
26072                Thread.currentThread().interrupt();
26073            }
26074        }
26075    }
26076
26077    public void waitForBroadcastIdle(PrintWriter pw) {
26078        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
26079        while (true) {
26080            boolean idle = true;
26081            synchronized (this) {
26082                for (BroadcastQueue queue : mBroadcastQueues) {
26083                    if (!queue.isIdle()) {
26084                        final String msg = "Waiting for queue " + queue + " to become idle...";
26085                        pw.println(msg);
26086                        pw.flush();
26087                        Slog.v(TAG, msg);
26088                        idle = false;
26089                    }
26090                }
26091            }
26092
26093            if (idle) {
26094                final String msg = "All broadcast queues are idle!";
26095                pw.println(msg);
26096                pw.flush();
26097                Slog.v(TAG, msg);
26098                return;
26099            } else {
26100                SystemClock.sleep(1000);
26101            }
26102        }
26103    }
26104
26105    /**
26106     * Return the user id of the last resumed activity.
26107     */
26108    @Override
26109    public @UserIdInt int getLastResumedActivityUserId() {
26110        enforceCallingPermission(
26111                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
26112        synchronized (this) {
26113            if (mLastResumedActivity == null) {
26114                return mUserController.getCurrentUserId();
26115            }
26116            return mLastResumedActivity.userId;
26117        }
26118    }
26119
26120    /**
26121     * Kill processes for the user with id userId and that depend on the package named packageName
26122     */
26123    @Override
26124    public void killPackageDependents(String packageName, int userId) {
26125        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
26126        if (packageName == null) {
26127            throw new NullPointerException(
26128                    "Cannot kill the dependents of a package without its name.");
26129        }
26130
26131        long callingId = Binder.clearCallingIdentity();
26132        IPackageManager pm = AppGlobals.getPackageManager();
26133        int pkgUid = -1;
26134        try {
26135            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
26136        } catch (RemoteException e) {
26137        }
26138        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
26139            throw new IllegalArgumentException(
26140                    "Cannot kill dependents of non-existing package " + packageName);
26141        }
26142        try {
26143            synchronized(this) {
26144                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
26145                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
26146                        "dep: " + packageName);
26147            }
26148        } finally {
26149            Binder.restoreCallingIdentity(callingId);
26150        }
26151    }
26152
26153    @Override
26154    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
26155            CharSequence message) throws RemoteException {
26156        if (message != null) {
26157            enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
26158                    "dismissKeyguard()");
26159        }
26160        final long callingId = Binder.clearCallingIdentity();
26161        try {
26162            mKeyguardController.dismissKeyguard(token, callback, message);
26163        } finally {
26164            Binder.restoreCallingIdentity(callingId);
26165        }
26166    }
26167
26168    @Override
26169    public int restartUserInBackground(final int userId) {
26170        return mUserController.restartUser(userId, /* foreground */ false);
26171    }
26172
26173    @Override
26174    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
26175        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
26176                "scheduleApplicationInfoChanged()");
26177
26178        synchronized (this) {
26179            final long origId = Binder.clearCallingIdentity();
26180            try {
26181                updateApplicationInfoLocked(packageNames, userId);
26182            } finally {
26183                Binder.restoreCallingIdentity(origId);
26184            }
26185        }
26186    }
26187
26188    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
26189        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
26190        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
26191            final ProcessRecord app = mLruProcesses.get(i);
26192            if (app.thread == null) {
26193                continue;
26194            }
26195
26196            if (userId != UserHandle.USER_ALL && app.userId != userId) {
26197                continue;
26198            }
26199
26200            final int packageCount = app.pkgList.size();
26201            for (int j = 0; j < packageCount; j++) {
26202                final String packageName = app.pkgList.keyAt(j);
26203                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
26204                    try {
26205                        final ApplicationInfo ai = AppGlobals.getPackageManager()
26206                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
26207                        if (ai != null) {
26208                            app.thread.scheduleApplicationInfoChanged(ai);
26209                        }
26210                    } catch (RemoteException e) {
26211                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
26212                                    packageName, app));
26213                    }
26214                }
26215            }
26216        }
26217        if (updateFrameworkRes) {
26218            // Update system server components that need to know about changed overlays. Because the
26219            // overlay is applied in ActivityThread, we need to serialize through its thread too.
26220            final Executor executor = ActivityThread.currentActivityThread().getExecutor();
26221            final DisplayManagerInternal display =
26222                    LocalServices.getService(DisplayManagerInternal.class);
26223            if (display != null) {
26224                executor.execute(display::onOverlayChanged);
26225            }
26226            if (mWindowManager != null) {
26227                executor.execute(mWindowManager::onOverlayChanged);
26228            }
26229        }
26230    }
26231
26232    /**
26233     * Attach an agent to the specified process (proces name or PID)
26234     */
26235    public void attachAgent(String process, String path) {
26236        try {
26237            synchronized (this) {
26238                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
26239                if (proc == null || proc.thread == null) {
26240                    throw new IllegalArgumentException("Unknown process: " + process);
26241                }
26242
26243                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26244                if (!isDebuggable) {
26245                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26246                        throw new SecurityException("Process not debuggable: " + proc);
26247                    }
26248                }
26249
26250                proc.thread.attachAgent(path);
26251            }
26252        } catch (RemoteException e) {
26253            throw new IllegalStateException("Process disappeared");
26254        }
26255    }
26256
26257    @VisibleForTesting
26258    public static class Injector {
26259        private NetworkManagementInternal mNmi;
26260
26261        public Context getContext() {
26262            return null;
26263        }
26264
26265        public AppOpsService getAppOpsService(File file, Handler handler) {
26266            return new AppOpsService(file, handler);
26267        }
26268
26269        public Handler getUiHandler(ActivityManagerService service) {
26270            return service.new UiHandler();
26271        }
26272
26273        public boolean isNetworkRestrictedForUid(int uid) {
26274            if (ensureHasNetworkManagementInternal()) {
26275                return mNmi.isNetworkRestrictedForUid(uid);
26276            }
26277            return false;
26278        }
26279
26280        private boolean ensureHasNetworkManagementInternal() {
26281            if (mNmi == null) {
26282                mNmi = LocalServices.getService(NetworkManagementInternal.class);
26283            }
26284            return mNmi != null;
26285        }
26286    }
26287
26288    @Override
26289    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
26290            throws RemoteException {
26291        synchronized (this) {
26292            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26293            if (r == null) {
26294                return;
26295            }
26296            final long origId = Binder.clearCallingIdentity();
26297            try {
26298                r.setShowWhenLocked(showWhenLocked);
26299            } finally {
26300                Binder.restoreCallingIdentity(origId);
26301            }
26302        }
26303    }
26304
26305    @Override
26306    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
26307        synchronized (this) {
26308            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26309            if (r == null) {
26310                return;
26311            }
26312            final long origId = Binder.clearCallingIdentity();
26313            try {
26314                r.setTurnScreenOn(turnScreenOn);
26315            } finally {
26316                Binder.restoreCallingIdentity(origId);
26317            }
26318        }
26319    }
26320
26321    @Override
26322    public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
26323            throws RemoteException {
26324        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
26325                "registerRemoteAnimations");
26326        synchronized (this) {
26327            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26328            if (r == null) {
26329                return;
26330            }
26331            final long origId = Binder.clearCallingIdentity();
26332            try {
26333                r.registerRemoteAnimations(definition);
26334            } finally {
26335                Binder.restoreCallingIdentity(origId);
26336            }
26337        }
26338    }
26339}
26340