ActivityManagerService.java revision 3f7be62d316cf366fabca64b718f17982c8f436d
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_HOME;
42import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
43import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
44import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
45import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
46import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
47import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
48import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
49import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
50import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
51import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
52import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
53import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
54import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
55import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
56import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
57import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
58import static android.content.pm.PackageManager.GET_PROVIDERS;
59import static android.content.pm.PackageManager.MATCH_ANY_USER;
60import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
61import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
62import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
63import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
64import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
65import static android.content.pm.PackageManager.PERMISSION_GRANTED;
66import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
67import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
68import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
69import static android.os.Build.VERSION_CODES.N;
70import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
71import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
72import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
73import static android.os.IServiceManager.DUMP_FLAG_PROTO;
74import static android.os.Process.BLUETOOTH_UID;
75import static android.os.Process.FIRST_APPLICATION_UID;
76import static android.os.Process.FIRST_ISOLATED_UID;
77import static android.os.Process.LAST_ISOLATED_UID;
78import static android.os.Process.NFC_UID;
79import static android.os.Process.PHONE_UID;
80import static android.os.Process.PROC_CHAR;
81import static android.os.Process.PROC_OUT_LONG;
82import static android.os.Process.PROC_PARENS;
83import static android.os.Process.PROC_SPACE_TERM;
84import static android.os.Process.ProcessStartResult;
85import static android.os.Process.ROOT_UID;
86import static android.os.Process.SCHED_FIFO;
87import static android.os.Process.SCHED_OTHER;
88import static android.os.Process.SCHED_RESET_ON_FORK;
89import static android.os.Process.SE_UID;
90import static android.os.Process.SHELL_UID;
91import static android.os.Process.SIGNAL_QUIT;
92import static android.os.Process.SIGNAL_USR1;
93import static android.os.Process.SYSTEM_UID;
94import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
95import static android.os.Process.THREAD_GROUP_DEFAULT;
96import static android.os.Process.THREAD_GROUP_TOP_APP;
97import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
98import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
99import static android.os.Process.getFreeMemory;
100import static android.os.Process.getTotalMemory;
101import static android.os.Process.isThreadInProcess;
102import static android.os.Process.killProcess;
103import static android.os.Process.killProcessQuiet;
104import static android.os.Process.myPid;
105import static android.os.Process.myUid;
106import static android.os.Process.readProcFile;
107import static android.os.Process.removeAllProcessGroups;
108import static android.os.Process.sendSignal;
109import static android.os.Process.setProcessGroup;
110import static android.os.Process.setThreadPriority;
111import static android.os.Process.setThreadScheduler;
112import static android.os.Process.startWebView;
113import static android.os.Process.zygoteProcess;
114import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
115import static android.provider.Settings.Global.DEBUG_APP;
116import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
117import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
118import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
119import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
120import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
121import static android.provider.Settings.System.FONT_SCALE;
122import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
123import static android.text.format.DateUtils.DAY_IN_MILLIS;
124import static android.view.Display.DEFAULT_DISPLAY;
125import static android.view.Display.INVALID_DISPLAY;
126
127import static com.android.internal.util.XmlUtils.readBooleanAttribute;
128import static com.android.internal.util.XmlUtils.readIntAttribute;
129import static com.android.internal.util.XmlUtils.readLongAttribute;
130import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
131import static com.android.internal.util.XmlUtils.writeIntAttribute;
132import static com.android.internal.util.XmlUtils.writeLongAttribute;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
141import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
142import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
143import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
144import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
145import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
146import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
147import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
148import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
149import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
150import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
151import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
152import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
153import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
154import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
155import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
156import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
157import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
158import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
159import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
160import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
161import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
162import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
163import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
164import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
165import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
166import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
167import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
168import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
169import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
170import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
171import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
172import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
173import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
174import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
175import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
176import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
177import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
178import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
179import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
180import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
181import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
182import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
183import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
184import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
185import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
186import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
187import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
188import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
189import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
190import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
191import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
192import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
193import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
194import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
195import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
196import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
197import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
198import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
199import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
200import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
201import static android.view.WindowManager.TRANSIT_NONE;
202import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
203import static android.view.WindowManager.TRANSIT_TASK_OPEN;
204import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
205
206import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
207import static org.xmlpull.v1.XmlPullParser.START_TAG;
208
209import android.Manifest;
210import android.Manifest.permission;
211import android.annotation.NonNull;
212import android.annotation.Nullable;
213import android.annotation.UserIdInt;
214import android.app.Activity;
215import android.app.ActivityManager;
216import android.app.ActivityManager.RunningTaskInfo;
217import android.app.ActivityManager.StackInfo;
218import android.app.ActivityManager.TaskSnapshot;
219import android.app.ActivityManagerInternal;
220import android.app.ActivityManagerInternal.ScreenObserver;
221import android.app.ActivityManagerInternal.SleepToken;
222import android.app.ActivityManagerProto;
223import android.app.ActivityOptions;
224import android.app.ActivityThread;
225import android.app.AlertDialog;
226import android.app.AppGlobals;
227import android.app.AppOpsManager;
228import android.app.ApplicationErrorReport;
229import android.app.ApplicationThreadConstants;
230import android.app.BroadcastOptions;
231import android.app.ContentProviderHolder;
232import android.app.Dialog;
233import android.app.GrantedUriPermission;
234import android.app.IActivityController;
235import android.app.IActivityManager;
236import android.app.IApplicationThread;
237import android.app.IAssistDataReceiver;
238import android.app.IInstrumentationWatcher;
239import android.app.INotificationManager;
240import android.app.IProcessObserver;
241import android.app.IServiceConnection;
242import android.app.IStopUserCallback;
243import android.app.ITaskStackListener;
244import android.app.IUiAutomationConnection;
245import android.app.IUidObserver;
246import android.app.IUserSwitchObserver;
247import android.app.Instrumentation;
248import android.app.Notification;
249import android.app.NotificationManager;
250import android.app.PendingIntent;
251import android.app.PictureInPictureParams;
252import android.app.ProfilerInfo;
253import android.app.RemoteAction;
254import android.app.WaitResult;
255import android.app.WindowConfiguration.ActivityType;
256import android.app.WindowConfiguration.WindowingMode;
257import android.app.admin.DevicePolicyManager;
258import android.app.assist.AssistContent;
259import android.app.assist.AssistStructure;
260import android.app.backup.IBackupManager;
261import android.app.servertransaction.ConfigurationChangeItem;
262import android.app.usage.UsageEvents;
263import android.app.usage.UsageStatsManagerInternal;
264import android.appwidget.AppWidgetManager;
265import android.content.ActivityNotFoundException;
266import android.content.BroadcastReceiver;
267import android.content.ClipData;
268import android.content.ComponentCallbacks2;
269import android.content.ComponentName;
270import android.content.ContentProvider;
271import android.content.ContentResolver;
272import android.content.Context;
273import android.content.DialogInterface;
274import android.content.IContentProvider;
275import android.content.IIntentReceiver;
276import android.content.IIntentSender;
277import android.content.Intent;
278import android.content.IntentFilter;
279import android.content.pm.ActivityInfo;
280import android.content.pm.ApplicationInfo;
281import android.content.pm.ConfigurationInfo;
282import android.content.pm.IPackageDataObserver;
283import android.content.pm.IPackageManager;
284import android.content.pm.InstrumentationInfo;
285import android.content.pm.PackageInfo;
286import android.content.pm.PackageManager;
287import android.content.pm.PackageManager.NameNotFoundException;
288import android.content.pm.PackageManagerInternal;
289import android.content.pm.ParceledListSlice;
290import android.content.pm.PathPermission;
291import android.content.pm.PermissionInfo;
292import android.content.pm.ProviderInfo;
293import android.content.pm.ResolveInfo;
294import android.content.pm.SELinuxUtil;
295import android.content.pm.ServiceInfo;
296import android.content.pm.UserInfo;
297import android.content.res.CompatibilityInfo;
298import android.content.res.Configuration;
299import android.content.res.Resources;
300import android.database.ContentObserver;
301import android.graphics.Bitmap;
302import android.graphics.Point;
303import android.graphics.Rect;
304import android.hardware.display.DisplayManagerInternal;
305import android.location.LocationManager;
306import android.media.audiofx.AudioEffect;
307import android.metrics.LogMaker;
308import android.net.Proxy;
309import android.net.ProxyInfo;
310import android.net.Uri;
311import android.os.BatteryStats;
312import android.os.Binder;
313import android.os.Build;
314import android.os.Bundle;
315import android.os.Debug;
316import android.os.DropBoxManager;
317import android.os.Environment;
318import android.os.FactoryTest;
319import android.os.FileObserver;
320import android.os.FileUtils;
321import android.os.Handler;
322import android.os.IBinder;
323import android.os.IDeviceIdentifiersPolicyService;
324import android.os.IPermissionController;
325import android.os.IProcessInfoService;
326import android.os.IProgressListener;
327import android.os.LocaleList;
328import android.os.Looper;
329import android.os.Message;
330import android.os.Parcel;
331import android.os.ParcelFileDescriptor;
332import android.os.PersistableBundle;
333import android.os.PowerManager;
334import android.os.PowerManager.ServiceType;
335import android.os.PowerManagerInternal;
336import android.os.Process;
337import android.os.RemoteCallbackList;
338import android.os.RemoteException;
339import android.os.ResultReceiver;
340import android.os.ServiceManager;
341import android.os.ShellCallback;
342import android.os.StrictMode;
343import android.os.SystemClock;
344import android.os.SystemProperties;
345import android.os.Trace;
346import android.os.TransactionTooLargeException;
347import android.os.UpdateLock;
348import android.os.UserHandle;
349import android.os.UserManager;
350import android.os.WorkSource;
351import android.os.storage.IStorageManager;
352import android.os.storage.StorageManager;
353import android.os.storage.StorageManagerInternal;
354import android.provider.Downloads;
355import android.provider.Settings;
356import android.service.voice.IVoiceInteractionSession;
357import android.service.voice.VoiceInteractionManagerInternal;
358import android.telecom.TelecomManager;
359import android.text.TextUtils;
360import android.text.format.DateUtils;
361import android.text.format.Time;
362import android.text.style.SuggestionSpan;
363import android.util.ArrayMap;
364import android.util.ArraySet;
365import android.util.AtomicFile;
366import android.util.DebugUtils;
367import android.util.EventLog;
368import android.util.Log;
369import android.util.LongSparseArray;
370import android.util.Pair;
371import android.util.PrintWriterPrinter;
372import android.util.Slog;
373import android.util.SparseArray;
374import android.util.SparseIntArray;
375import android.util.StatsLog;
376import android.util.TimeUtils;
377import android.util.TimingsTraceLog;
378import android.util.Xml;
379import android.util.proto.ProtoOutputStream;
380import android.util.proto.ProtoUtils;
381import android.view.Gravity;
382import android.view.IRecentsAnimationRunner;
383import android.view.LayoutInflater;
384import android.view.RemoteAnimationDefinition;
385import android.view.View;
386import android.view.WindowManager;
387
388import android.view.autofill.AutofillManagerInternal;
389import com.android.internal.R;
390import com.android.internal.annotations.GuardedBy;
391import com.android.internal.annotations.VisibleForTesting;
392import com.android.internal.app.AssistUtils;
393import com.android.internal.app.DumpHeapActivity;
394import com.android.internal.app.IAppOpsCallback;
395import com.android.internal.app.IAppOpsService;
396import com.android.internal.app.IVoiceInteractor;
397import com.android.internal.app.ProcessMap;
398import com.android.internal.app.SystemUserHomeActivity;
399import com.android.internal.app.procstats.ProcessStats;
400import com.android.internal.logging.MetricsLogger;
401import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
402import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
403import com.android.internal.notification.SystemNotificationChannels;
404import com.android.internal.os.BackgroundThread;
405import com.android.internal.os.BatteryStatsImpl;
406import com.android.internal.os.BinderInternal;
407import com.android.internal.os.logging.MetricsLoggerWrapper;
408import com.android.internal.os.ByteTransferPipe;
409import com.android.internal.os.IResultReceiver;
410import com.android.internal.os.ProcessCpuTracker;
411import com.android.internal.os.TransferPipe;
412import com.android.internal.os.Zygote;
413import com.android.internal.policy.IKeyguardDismissCallback;
414import com.android.internal.policy.KeyguardDismissCallback;
415import com.android.internal.telephony.TelephonyIntents;
416import com.android.internal.util.ArrayUtils;
417import com.android.internal.util.DumpUtils;
418import com.android.internal.util.FastPrintWriter;
419import com.android.internal.util.FastXmlSerializer;
420import com.android.internal.util.MemInfoReader;
421import com.android.internal.util.Preconditions;
422import com.android.server.AlarmManagerInternal;
423import com.android.server.AppOpsService;
424import com.android.server.AttributeCache;
425import com.android.server.DeviceIdleController;
426import com.android.server.IntentResolver;
427import com.android.server.IoThread;
428import com.android.server.LocalServices;
429import com.android.server.LockGuard;
430import com.android.server.NetworkManagementInternal;
431import com.android.server.RescueParty;
432import com.android.server.ServiceThread;
433import com.android.server.SystemConfig;
434import com.android.server.SystemService;
435import com.android.server.SystemServiceManager;
436import com.android.server.ThreadPriorityBooster;
437import com.android.server.Watchdog;
438import com.android.server.am.ActivityStack.ActivityState;
439import com.android.server.am.proto.ActivityManagerServiceProto;
440import com.android.server.am.proto.BroadcastProto;
441import com.android.server.am.proto.GrantUriProto;
442import com.android.server.am.proto.ImportanceTokenProto;
443import com.android.server.am.proto.MemInfoProto;
444import com.android.server.am.proto.NeededUriGrantsProto;
445import com.android.server.am.proto.ProcessOomProto;
446import com.android.server.am.proto.ProcessToGcProto;
447import com.android.server.am.proto.ProcessesProto;
448import com.android.server.am.proto.ProcessesProto.UidObserverRegistrationProto;
449import com.android.server.am.proto.StickyBroadcastProto;
450import com.android.server.firewall.IntentFirewall;
451import com.android.server.job.JobSchedulerInternal;
452import com.android.server.pm.Installer;
453import com.android.server.pm.Installer.InstallerException;
454import com.android.server.utils.PriorityDump;
455import com.android.server.vr.VrManagerInternal;
456import com.android.server.wm.PinnedStackWindowController;
457import com.android.server.wm.RecentsAnimationController;
458import com.android.server.wm.WindowManagerService;
459
460import dalvik.system.VMRuntime;
461
462import libcore.io.IoUtils;
463import libcore.util.EmptyArray;
464
465import com.google.android.collect.Lists;
466import com.google.android.collect.Maps;
467
468import org.xmlpull.v1.XmlPullParser;
469import org.xmlpull.v1.XmlPullParserException;
470import org.xmlpull.v1.XmlSerializer;
471
472import java.io.File;
473import java.io.FileDescriptor;
474import java.io.FileInputStream;
475import java.io.FileNotFoundException;
476import java.io.FileOutputStream;
477import java.io.IOException;
478import java.io.InputStreamReader;
479import java.io.PrintWriter;
480import java.io.StringWriter;
481import java.io.UnsupportedEncodingException;
482import java.lang.ref.WeakReference;
483import java.nio.charset.StandardCharsets;
484import java.text.DateFormat;
485import java.text.SimpleDateFormat;
486import java.util.ArrayList;
487import java.util.Arrays;
488import java.util.Collections;
489import java.util.Comparator;
490import java.util.Date;
491import java.util.HashMap;
492import java.util.HashSet;
493import java.util.Iterator;
494import java.util.List;
495import java.util.Locale;
496import java.util.Map;
497import java.util.Objects;
498import java.util.Set;
499import java.util.concurrent.CountDownLatch;
500import java.util.concurrent.Executor;
501import java.util.concurrent.atomic.AtomicBoolean;
502import java.util.concurrent.atomic.AtomicLong;
503
504public class ActivityManagerService extends IActivityManager.Stub
505        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
506
507    /**
508     * Priority we boost main thread and RT of top app to.
509     */
510    public static final int TOP_APP_PRIORITY_BOOST = -10;
511
512    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
513    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
514    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
515    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
516    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
517    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
518    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
519    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
520    private static final String TAG_LRU = TAG + POSTFIX_LRU;
521    private static final String TAG_MU = TAG + POSTFIX_MU;
522    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
523    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
524    private static final String TAG_POWER = TAG + POSTFIX_POWER;
525    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
526    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
527    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
528    private static final String TAG_PSS = TAG + POSTFIX_PSS;
529    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
530    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
531    private static final String TAG_STACK = TAG + POSTFIX_STACK;
532    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
533    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
534    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
535    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
536
537    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
538    // here so that while the job scheduler can depend on AMS, the other way around
539    // need not be the case.
540    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
541
542    /** Control over CPU and battery monitoring */
543    // write battery stats every 30 minutes.
544    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
545    static final boolean MONITOR_CPU_USAGE = true;
546    // don't sample cpu less than every 5 seconds.
547    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
548    // wait possibly forever for next cpu sample.
549    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
550    static final boolean MONITOR_THREAD_CPU_USAGE = false;
551
552    // The flags that are set for all calls we make to the package manager.
553    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
554
555    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
556
557    // Amount of time after a call to stopAppSwitches() during which we will
558    // prevent further untrusted switches from happening.
559    static final long APP_SWITCH_DELAY_TIME = 5*1000;
560
561    // How long we wait for a launched process to attach to the activity manager
562    // before we decide it's never going to come up for real.
563    static final int PROC_START_TIMEOUT = 10*1000;
564    // How long we wait for an attached process to publish its content providers
565    // before we decide it must be hung.
566    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
567
568    // How long we wait for a launched process to attach to the activity manager
569    // before we decide it's never going to come up for real, when the process was
570    // started with a wrapper for instrumentation (such as Valgrind) because it
571    // could take much longer than usual.
572    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
573
574    // How long we allow a receiver to run before giving up on it.
575    static final int BROADCAST_FG_TIMEOUT = 10*1000;
576    static final int BROADCAST_BG_TIMEOUT = 60*1000;
577
578    // How long we wait until we timeout on key dispatching.
579    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
580
581    // How long we wait until we timeout on key dispatching during instrumentation.
582    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
583
584    // How long to wait in getAssistContextExtras for the activity and foreground services
585    // to respond with the result.
586    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
587
588    // How long top wait when going through the modern assist (which doesn't need to block
589    // on getting this result before starting to launch its UI).
590    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
591
592    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
593    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
594
595    // Maximum number of persisted Uri grants a package is allowed
596    static final int MAX_PERSISTED_URI_GRANTS = 128;
597
598    static final int MY_PID = myPid();
599
600    static final String[] EMPTY_STRING_ARRAY = new String[0];
601
602    // How many bytes to write into the dropbox log before truncating
603    static final int DROPBOX_MAX_SIZE = 192 * 1024;
604    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
605    // as one line, but close enough for now.
606    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
607
608    // Access modes for handleIncomingUser.
609    static final int ALLOW_NON_FULL = 0;
610    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
611    static final int ALLOW_FULL_ONLY = 2;
612
613    // Necessary ApplicationInfo flags to mark an app as persistent
614    private static final int PERSISTENT_MASK =
615            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
616
617    // Intent sent when remote bugreport collection has been completed
618    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
619            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
620
621    // Used to indicate that an app transition should be animated.
622    static final boolean ANIMATE = true;
623
624    // Determines whether to take full screen screenshots
625    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
626
627    /**
628     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
629     */
630    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
631
632    /**
633     * State indicating that there is no need for any blocking for network.
634     */
635    @VisibleForTesting
636    static final int NETWORK_STATE_NO_CHANGE = 0;
637
638    /**
639     * State indicating that the main thread needs to be informed about the network wait.
640     */
641    @VisibleForTesting
642    static final int NETWORK_STATE_BLOCK = 1;
643
644    /**
645     * State indicating that any threads waiting for network state to get updated can be unblocked.
646     */
647    @VisibleForTesting
648    static final int NETWORK_STATE_UNBLOCK = 2;
649
650    // Max character limit for a notification title. If the notification title is larger than this
651    // the notification will not be legible to the user.
652    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
653
654    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
655
656    /** All system services */
657    SystemServiceManager mSystemServiceManager;
658
659    // Wrapper around VoiceInteractionServiceManager
660    private AssistUtils mAssistUtils;
661
662    // Keeps track of the active voice interaction service component, notified from
663    // VoiceInteractionManagerService
664    ComponentName mActiveVoiceInteractionServiceComponent;
665
666    private Installer mInstaller;
667
668    /** Run all ActivityStacks through this */
669    final ActivityStackSupervisor mStackSupervisor;
670    private final KeyguardController mKeyguardController;
671
672    private final ActivityStartController mActivityStartController;
673
674    final ClientLifecycleManager mLifecycleManager;
675
676    final TaskChangeNotificationController mTaskChangeNotificationController;
677
678    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
679
680    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
681
682    public final IntentFirewall mIntentFirewall;
683
684    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
685    // default action automatically.  Important for devices without direct input
686    // devices.
687    private boolean mShowDialogs = true;
688
689    private final VrController mVrController;
690
691    // VR Vr2d Display Id.
692    int mVr2dDisplayId = INVALID_DISPLAY;
693
694    // Whether we should use SCHED_FIFO for UI and RenderThreads.
695    private boolean mUseFifoUiScheduling = false;
696
697    BroadcastQueue mFgBroadcastQueue;
698    BroadcastQueue mBgBroadcastQueue;
699    // Convenient for easy iteration over the queues. Foreground is first
700    // so that dispatch of foreground broadcasts gets precedence.
701    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
702
703    BroadcastStats mLastBroadcastStats;
704    BroadcastStats mCurBroadcastStats;
705
706    BroadcastQueue broadcastQueueForIntent(Intent intent) {
707        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
708        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
709                "Broadcast intent " + intent + " on "
710                + (isFg ? "foreground" : "background") + " queue");
711        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
712    }
713
714    /**
715     * The last resumed activity. This is identical to the current resumed activity most
716     * of the time but could be different when we're pausing one activity before we resume
717     * another activity.
718     */
719    private ActivityRecord mLastResumedActivity;
720
721    /**
722     * If non-null, we are tracking the time the user spends in the currently focused app.
723     */
724    private AppTimeTracker mCurAppTimeTracker;
725
726    /**
727     * List of intents that were used to start the most recent tasks.
728     */
729    private final RecentTasks mRecentTasks;
730
731    /**
732     * For addAppTask: cached of the last activity component that was added.
733     */
734    ComponentName mLastAddedTaskComponent;
735
736    /**
737     * For addAppTask: cached of the last activity uid that was added.
738     */
739    int mLastAddedTaskUid;
740
741    /**
742     * For addAppTask: cached of the last ActivityInfo that was added.
743     */
744    ActivityInfo mLastAddedTaskActivity;
745
746    /**
747     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
748     */
749    String mDeviceOwnerName;
750
751    /**
752     * The controller for all operations related to locktask.
753     */
754    final LockTaskController mLockTaskController;
755
756    final UserController mUserController;
757
758    /**
759     * Packages that are being allowed to perform unrestricted app switches.  Mapping is
760     * User -> Type -> uid.
761     */
762    final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
763
764    final AppErrors mAppErrors;
765
766    final AppWarnings mAppWarnings;
767
768    /**
769     * Dump of the activity state at the time of the last ANR. Cleared after
770     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
771     */
772    String mLastANRState;
773
774    /**
775     * Indicates the maximum time spent waiting for the network rules to get updated.
776     */
777    @VisibleForTesting
778    long mWaitForNetworkTimeoutMs;
779
780    /**
781     * Helper class which strips out priority and proto arguments then calls the dump function with
782     * the appropriate arguments. If priority arguments are omitted, function calls the legacy
783     * dump command.
784     * If priority arguments are omitted all sections are dumped, otherwise sections are dumped
785     * according to their priority.
786     */
787    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
788        @Override
789        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
790                boolean asProto) {
791            if (asProto) return;
792            doDump(fd, pw, new String[]{"activities"}, asProto);
793        }
794
795        @Override
796        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
797            doDump(fd, pw, new String[]{"-a", "--normal-priority"}, asProto);
798        }
799
800        @Override
801        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
802            doDump(fd, pw, args, asProto);
803        }
804    };
805
806    public boolean canShowErrorDialogs() {
807        return mShowDialogs && !mSleeping && !mShuttingDown
808                && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
809                && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
810                        mUserController.getCurrentUserId())
811                && !(UserManager.isDeviceInDemoMode(mContext)
812                        && mUserController.getCurrentUser().isDemo());
813    }
814
815    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
816            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
817
818    static void boostPriorityForLockedSection() {
819        sThreadPriorityBooster.boost();
820    }
821
822    static void resetPriorityAfterLockedSection() {
823        sThreadPriorityBooster.reset();
824    }
825
826    public class PendingAssistExtras extends Binder implements Runnable {
827        public final ActivityRecord activity;
828        public boolean isHome;
829        public final Bundle extras;
830        public final Intent intent;
831        public final String hint;
832        public final IAssistDataReceiver receiver;
833        public final int userHandle;
834        public boolean haveResult = false;
835        public Bundle result = null;
836        public AssistStructure structure = null;
837        public AssistContent content = null;
838        public Bundle receiverExtras;
839
840        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
841                String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
842                int _userHandle) {
843            activity = _activity;
844            extras = _extras;
845            intent = _intent;
846            hint = _hint;
847            receiver = _receiver;
848            receiverExtras = _receiverExtras;
849            userHandle = _userHandle;
850        }
851
852        @Override
853        public void run() {
854            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
855            synchronized (this) {
856                haveResult = true;
857                notifyAll();
858            }
859            pendingAssistExtrasTimedOut(this);
860        }
861    }
862
863    final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
864
865    /**
866     * Process management.
867     */
868    final ProcessList mProcessList = new ProcessList();
869
870    /**
871     * All of the applications we currently have running organized by name.
872     * The keys are strings of the application package name (as
873     * returned by the package manager), and the keys are ApplicationRecord
874     * objects.
875     */
876    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
877
878    /**
879     * Tracking long-term execution of processes to look for abuse and other
880     * bad app behavior.
881     */
882    final ProcessStatsService mProcessStats;
883
884    /**
885     * The currently running isolated processes.
886     */
887    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
888
889    /**
890     * Counter for assigning isolated process uids, to avoid frequently reusing the
891     * same ones.
892     */
893    int mNextIsolatedProcessUid = 0;
894
895    /**
896     * The currently running heavy-weight process, if any.
897     */
898    ProcessRecord mHeavyWeightProcess = null;
899
900    /**
901     * Non-persistent appId whitelist for background restrictions
902     */
903    int[] mBackgroundAppIdWhitelist = new int[] {
904            BLUETOOTH_UID
905    };
906
907    /**
908     * Broadcast actions that will always be deliverable to unlaunched/background apps
909     */
910    ArraySet<String> mBackgroundLaunchBroadcasts;
911
912    /**
913     * All of the processes we currently have running organized by pid.
914     * The keys are the pid running the application.
915     *
916     * <p>NOTE: This object is protected by its own lock, NOT the global
917     * activity manager lock!
918     */
919    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
920
921    /**
922     * All of the processes that have been forced to be important.  The key
923     * is the pid of the caller who requested it (we hold a death
924     * link on it).
925     */
926    abstract class ImportanceToken implements IBinder.DeathRecipient {
927        final int pid;
928        final IBinder token;
929        final String reason;
930
931        ImportanceToken(int _pid, IBinder _token, String _reason) {
932            pid = _pid;
933            token = _token;
934            reason = _reason;
935        }
936
937        @Override
938        public String toString() {
939            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
940                    + " " + reason + " " + pid + " " + token + " }";
941        }
942
943        void writeToProto(ProtoOutputStream proto, long fieldId) {
944            final long pToken = proto.start(fieldId);
945            proto.write(ImportanceTokenProto.PID, pid);
946            if (token != null) {
947                proto.write(ImportanceTokenProto.TOKEN, token.toString());
948            }
949            proto.write(ImportanceTokenProto.REASON, reason);
950            proto.end(pToken);
951        }
952    }
953    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
954
955    /**
956     * List of records for processes that someone had tried to start before the
957     * system was ready.  We don't start them at that point, but ensure they
958     * are started by the time booting is complete.
959     */
960    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
961
962    /**
963     * List of persistent applications that are in the process
964     * of being started.
965     */
966    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
967
968    /**
969     * Processes that are being forcibly torn down.
970     */
971    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
972
973    /**
974     * List of running applications, sorted by recent usage.
975     * The first entry in the list is the least recently used.
976     */
977    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
978
979    /**
980     * Where in mLruProcesses that the processes hosting activities start.
981     */
982    int mLruProcessActivityStart = 0;
983
984    /**
985     * Where in mLruProcesses that the processes hosting services start.
986     * This is after (lower index) than mLruProcessesActivityStart.
987     */
988    int mLruProcessServiceStart = 0;
989
990    /**
991     * List of processes that should gc as soon as things are idle.
992     */
993    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
994
995    /**
996     * Processes we want to collect PSS data from.
997     */
998    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
999
1000    private boolean mBinderTransactionTrackingEnabled = false;
1001
1002    /**
1003     * Last time we requested PSS data of all processes.
1004     */
1005    long mLastFullPssTime = SystemClock.uptimeMillis();
1006
1007    /**
1008     * If set, the next time we collect PSS data we should do a full collection
1009     * with data from native processes and the kernel.
1010     */
1011    boolean mFullPssPending = false;
1012
1013    /**
1014     * This is the process holding what we currently consider to be
1015     * the "home" activity.
1016     */
1017    ProcessRecord mHomeProcess;
1018
1019    /**
1020     * This is the process holding the activity the user last visited that
1021     * is in a different process from the one they are currently in.
1022     */
1023    ProcessRecord mPreviousProcess;
1024
1025    /**
1026     * The time at which the previous process was last visible.
1027     */
1028    long mPreviousProcessVisibleTime;
1029
1030    /**
1031     * Track all uids that have actively running processes.
1032     */
1033    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1034
1035    /**
1036     * This is for verifying the UID report flow.
1037     */
1038    static final boolean VALIDATE_UID_STATES = true;
1039    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1040
1041    /**
1042     * Packages that the user has asked to have run in screen size
1043     * compatibility mode instead of filling the screen.
1044     */
1045    final CompatModePackages mCompatModePackages;
1046
1047    /**
1048     * Set of IntentSenderRecord objects that are currently active.
1049     */
1050    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1051            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1052
1053    /**
1054     * Fingerprints (hashCode()) of stack traces that we've
1055     * already logged DropBox entries for.  Guarded by itself.  If
1056     * something (rogue user app) forces this over
1057     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1058     */
1059    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1060    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1061
1062    /**
1063     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1064     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1065     */
1066    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1067
1068    /**
1069     * Resolver for broadcast intents to registered receivers.
1070     * Holds BroadcastFilter (subclass of IntentFilter).
1071     */
1072    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1073            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1074        @Override
1075        protected boolean allowFilterResult(
1076                BroadcastFilter filter, List<BroadcastFilter> dest) {
1077            IBinder target = filter.receiverList.receiver.asBinder();
1078            for (int i = dest.size() - 1; i >= 0; i--) {
1079                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1080                    return false;
1081                }
1082            }
1083            return true;
1084        }
1085
1086        @Override
1087        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1088            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1089                    || userId == filter.owningUserId) {
1090                return super.newResult(filter, match, userId);
1091            }
1092            return null;
1093        }
1094
1095        @Override
1096        protected BroadcastFilter[] newArray(int size) {
1097            return new BroadcastFilter[size];
1098        }
1099
1100        @Override
1101        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1102            return packageName.equals(filter.packageName);
1103        }
1104    };
1105
1106    /**
1107     * State of all active sticky broadcasts per user.  Keys are the action of the
1108     * sticky Intent, values are an ArrayList of all broadcasted intents with
1109     * that action (which should usually be one).  The SparseArray is keyed
1110     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1111     * for stickies that are sent to all users.
1112     */
1113    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1114            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1115
1116    final ActiveServices mServices;
1117
1118    final static class Association {
1119        final int mSourceUid;
1120        final String mSourceProcess;
1121        final int mTargetUid;
1122        final ComponentName mTargetComponent;
1123        final String mTargetProcess;
1124
1125        int mCount;
1126        long mTime;
1127
1128        int mNesting;
1129        long mStartTime;
1130
1131        // states of the source process when the bind occurred.
1132        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1133        long mLastStateUptime;
1134        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1135                - ActivityManager.MIN_PROCESS_STATE+1];
1136
1137        Association(int sourceUid, String sourceProcess, int targetUid,
1138                ComponentName targetComponent, String targetProcess) {
1139            mSourceUid = sourceUid;
1140            mSourceProcess = sourceProcess;
1141            mTargetUid = targetUid;
1142            mTargetComponent = targetComponent;
1143            mTargetProcess = targetProcess;
1144        }
1145    }
1146
1147    /**
1148     * When service association tracking is enabled, this is all of the associations we
1149     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1150     * -> association data.
1151     */
1152    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1153            mAssociations = new SparseArray<>();
1154    boolean mTrackingAssociations;
1155
1156    /**
1157     * Backup/restore process management
1158     */
1159    String mBackupAppName = null;
1160    BackupRecord mBackupTarget = null;
1161
1162    final ProviderMap mProviderMap;
1163
1164    /**
1165     * List of content providers who have clients waiting for them.  The
1166     * application is currently being launched and the provider will be
1167     * removed from this list once it is published.
1168     */
1169    final ArrayList<ContentProviderRecord> mLaunchingProviders
1170            = new ArrayList<ContentProviderRecord>();
1171
1172    /**
1173     * File storing persisted {@link #mGrantedUriPermissions}.
1174     */
1175    private final AtomicFile mGrantFile;
1176
1177    /** XML constants used in {@link #mGrantFile} */
1178    private static final String TAG_URI_GRANTS = "uri-grants";
1179    private static final String TAG_URI_GRANT = "uri-grant";
1180    private static final String ATTR_USER_HANDLE = "userHandle";
1181    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1182    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1183    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1184    private static final String ATTR_TARGET_PKG = "targetPkg";
1185    private static final String ATTR_URI = "uri";
1186    private static final String ATTR_MODE_FLAGS = "modeFlags";
1187    private static final String ATTR_CREATED_TIME = "createdTime";
1188    private static final String ATTR_PREFIX = "prefix";
1189
1190    /**
1191     * Global set of specific {@link Uri} permissions that have been granted.
1192     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1193     * to {@link UriPermission#uri} to {@link UriPermission}.
1194     */
1195    @GuardedBy("this")
1196    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1197            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1198
1199    public static class GrantUri {
1200        public final int sourceUserId;
1201        public final Uri uri;
1202        public boolean prefix;
1203
1204        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1205            this.sourceUserId = sourceUserId;
1206            this.uri = uri;
1207            this.prefix = prefix;
1208        }
1209
1210        @Override
1211        public int hashCode() {
1212            int hashCode = 1;
1213            hashCode = 31 * hashCode + sourceUserId;
1214            hashCode = 31 * hashCode + uri.hashCode();
1215            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1216            return hashCode;
1217        }
1218
1219        @Override
1220        public boolean equals(Object o) {
1221            if (o instanceof GrantUri) {
1222                GrantUri other = (GrantUri) o;
1223                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1224                        && prefix == other.prefix;
1225            }
1226            return false;
1227        }
1228
1229        @Override
1230        public String toString() {
1231            String result = uri.toString() + " [user " + sourceUserId + "]";
1232            if (prefix) result += " [prefix]";
1233            return result;
1234        }
1235
1236        public String toSafeString() {
1237            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1238            if (prefix) result += " [prefix]";
1239            return result;
1240        }
1241
1242        public void writeToProto(ProtoOutputStream proto, long fieldId) {
1243            long token = proto.start(fieldId);
1244            proto.write(GrantUriProto.URI, uri.toString());
1245            proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
1246            proto.end(token);
1247        }
1248
1249        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1250            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1251                    ContentProvider.getUriWithoutUserId(uri), false);
1252        }
1253    }
1254
1255    CoreSettingsObserver mCoreSettingsObserver;
1256
1257    FontScaleSettingObserver mFontScaleSettingObserver;
1258
1259    private final class FontScaleSettingObserver extends ContentObserver {
1260        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1261
1262        public FontScaleSettingObserver() {
1263            super(mHandler);
1264            ContentResolver resolver = mContext.getContentResolver();
1265            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1266        }
1267
1268        @Override
1269        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1270            if (mFontScaleUri.equals(uri)) {
1271                updateFontScaleIfNeeded(userId);
1272            }
1273        }
1274    }
1275
1276    DevelopmentSettingsObserver mDevelopmentSettingsObserver;
1277
1278    private final class DevelopmentSettingsObserver extends ContentObserver {
1279        private final Uri mUri = Settings.Global
1280                .getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
1281
1282        private final ComponentName mBugreportStorageProvider = new ComponentName(
1283                "com.android.shell", "com.android.shell.BugreportStorageProvider");
1284
1285        public DevelopmentSettingsObserver() {
1286            super(mHandler);
1287            mContext.getContentResolver().registerContentObserver(mUri, false, this,
1288                    UserHandle.USER_ALL);
1289            // Always kick once to ensure that we match current state
1290            onChange();
1291        }
1292
1293        @Override
1294        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1295            if (mUri.equals(uri)) {
1296                onChange();
1297            }
1298        }
1299
1300        public void onChange() {
1301            final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
1302                    Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, Build.IS_ENG ? 1 : 0) != 0;
1303            mContext.getPackageManager().setComponentEnabledSetting(mBugreportStorageProvider,
1304                    enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1305                            : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
1306                    0);
1307        }
1308    }
1309
1310    /**
1311     * Thread-local storage used to carry caller permissions over through
1312     * indirect content-provider access.
1313     */
1314    private class Identity {
1315        public final IBinder token;
1316        public final int pid;
1317        public final int uid;
1318
1319        Identity(IBinder _token, int _pid, int _uid) {
1320            token = _token;
1321            pid = _pid;
1322            uid = _uid;
1323        }
1324    }
1325
1326    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1327
1328    /**
1329     * All information we have collected about the runtime performance of
1330     * any user id that can impact battery performance.
1331     */
1332    final BatteryStatsService mBatteryStatsService;
1333
1334    /**
1335     * Information about component usage
1336     */
1337    UsageStatsManagerInternal mUsageStatsService;
1338
1339    /**
1340     * Access to DeviceIdleController service.
1341     */
1342    DeviceIdleController.LocalService mLocalDeviceIdleController;
1343
1344    /**
1345     * Set of app ids that are whitelisted for device idle and thus background check.
1346     */
1347    int[] mDeviceIdleWhitelist = new int[0];
1348
1349    /**
1350     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1351     */
1352    int[] mDeviceIdleTempWhitelist = new int[0];
1353
1354    static final class PendingTempWhitelist {
1355        final int targetUid;
1356        final long duration;
1357        final String tag;
1358
1359        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1360            targetUid = _targetUid;
1361            duration = _duration;
1362            tag = _tag;
1363        }
1364
1365        void writeToProto(ProtoOutputStream proto, long fieldId) {
1366            final long token = proto.start(fieldId);
1367            proto.write(ProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
1368            proto.write(ProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
1369            proto.write(ProcessesProto.PendingTempWhitelist.TAG, tag);
1370            proto.end(token);
1371        }
1372    }
1373
1374    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1375
1376    /**
1377     * Information about and control over application operations
1378     */
1379    final AppOpsService mAppOpsService;
1380
1381    /** Current sequencing integer of the configuration, for skipping old configurations. */
1382    private int mConfigurationSeq;
1383
1384    /**
1385     * Temp object used when global and/or display override configuration is updated. It is also
1386     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1387     * anyone...
1388     */
1389    private Configuration mTempConfig = new Configuration();
1390
1391    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1392            new UpdateConfigurationResult();
1393    private static final class UpdateConfigurationResult {
1394        // Configuration changes that were updated.
1395        int changes;
1396        // If the activity was relaunched to match the new configuration.
1397        boolean activityRelaunched;
1398
1399        void reset() {
1400            changes = 0;
1401            activityRelaunched = false;
1402        }
1403    }
1404
1405    boolean mSuppressResizeConfigChanges;
1406
1407    /**
1408     * Hardware-reported OpenGLES version.
1409     */
1410    final int GL_ES_VERSION;
1411
1412    /**
1413     * List of initialization arguments to pass to all processes when binding applications to them.
1414     * For example, references to the commonly used services.
1415     */
1416    HashMap<String, IBinder> mAppBindArgs;
1417    HashMap<String, IBinder> mIsolatedAppBindArgs;
1418
1419    /**
1420     * Temporary to avoid allocations.  Protected by main lock.
1421     */
1422    final StringBuilder mStringBuilder = new StringBuilder(256);
1423
1424    /**
1425     * Used to control how we initialize the service.
1426     */
1427    ComponentName mTopComponent;
1428    String mTopAction = Intent.ACTION_MAIN;
1429    String mTopData;
1430
1431    volatile boolean mProcessesReady = false;
1432    volatile boolean mSystemReady = false;
1433    volatile boolean mOnBattery = false;
1434    volatile int mFactoryTest;
1435
1436    @GuardedBy("this") boolean mBooting = false;
1437    @GuardedBy("this") boolean mCallFinishBooting = false;
1438    @GuardedBy("this") boolean mBootAnimationComplete = false;
1439    @GuardedBy("this") boolean mLaunchWarningShown = false;
1440    private @GuardedBy("this") boolean mCheckedForSetup = false;
1441
1442    final Context mContext;
1443
1444    /**
1445     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1446     * change at runtime. Use mContext for non-UI purposes.
1447     */
1448    final Context mUiContext;
1449
1450    /**
1451     * The time at which we will allow normal application switches again,
1452     * after a call to {@link #stopAppSwitches()}.
1453     */
1454    long mAppSwitchesAllowedTime;
1455
1456    /**
1457     * This is set to true after the first switch after mAppSwitchesAllowedTime
1458     * is set; any switches after that will clear the time.
1459     */
1460    boolean mDidAppSwitch;
1461
1462    /**
1463     * Last time (in uptime) at which we checked for power usage.
1464     */
1465    long mLastPowerCheckUptime;
1466
1467    /**
1468     * Set while we are wanting to sleep, to prevent any
1469     * activities from being started/resumed.
1470     *
1471     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1472     *
1473     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1474     * while in the sleep state until there is a pending transition out of sleep, in which case
1475     * mSleeping is set to false, and remains false while awake.
1476     *
1477     * Whether mSleeping can quickly toggled between true/false without the device actually
1478     * display changing states is undefined.
1479     */
1480    private boolean mSleeping = false;
1481
1482    /**
1483     * The process state used for processes that are running the top activities.
1484     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1485     */
1486    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1487
1488    /**
1489     * Set while we are running a voice interaction.  This overrides
1490     * sleeping while it is active.
1491     */
1492    IVoiceInteractionSession mRunningVoice;
1493
1494    /**
1495     * For some direct access we need to power manager.
1496     */
1497    PowerManagerInternal mLocalPowerManager;
1498
1499    /**
1500     * We want to hold a wake lock while running a voice interaction session, since
1501     * this may happen with the screen off and we need to keep the CPU running to
1502     * be able to continue to interact with the user.
1503     */
1504    PowerManager.WakeLock mVoiceWakeLock;
1505
1506    /**
1507     * State of external calls telling us if the device is awake or asleep.
1508     */
1509    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1510
1511    /**
1512     * Set if we are shutting down the system, similar to sleeping.
1513     */
1514    boolean mShuttingDown = false;
1515
1516    /**
1517     * Current sequence id for oom_adj computation traversal.
1518     */
1519    int mAdjSeq = 0;
1520
1521    /**
1522     * Current sequence id for process LRU updating.
1523     */
1524    int mLruSeq = 0;
1525
1526    /**
1527     * Keep track of the non-cached/empty process we last found, to help
1528     * determine how to distribute cached/empty processes next time.
1529     */
1530    int mNumNonCachedProcs = 0;
1531
1532    /**
1533     * Keep track of the number of cached hidden procs, to balance oom adj
1534     * distribution between those and empty procs.
1535     */
1536    int mNumCachedHiddenProcs = 0;
1537
1538    /**
1539     * Keep track of the number of service processes we last found, to
1540     * determine on the next iteration which should be B services.
1541     */
1542    int mNumServiceProcs = 0;
1543    int mNewNumAServiceProcs = 0;
1544    int mNewNumServiceProcs = 0;
1545
1546    /**
1547     * Allow the current computed overall memory level of the system to go down?
1548     * This is set to false when we are killing processes for reasons other than
1549     * memory management, so that the now smaller process list will not be taken as
1550     * an indication that memory is tighter.
1551     */
1552    boolean mAllowLowerMemLevel = false;
1553
1554    /**
1555     * The last computed memory level, for holding when we are in a state that
1556     * processes are going away for other reasons.
1557     */
1558    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1559
1560    /**
1561     * The last total number of process we have, to determine if changes actually look
1562     * like a shrinking number of process due to lower RAM.
1563     */
1564    int mLastNumProcesses;
1565
1566    /**
1567     * The uptime of the last time we performed idle maintenance.
1568     */
1569    long mLastIdleTime = SystemClock.uptimeMillis();
1570
1571    /**
1572     * Total time spent with RAM that has been added in the past since the last idle time.
1573     */
1574    long mLowRamTimeSinceLastIdle = 0;
1575
1576    /**
1577     * If RAM is currently low, when that horrible situation started.
1578     */
1579    long mLowRamStartTime = 0;
1580
1581    /**
1582     * For reporting to battery stats the current top application.
1583     */
1584    private String mCurResumedPackage = null;
1585    private int mCurResumedUid = -1;
1586
1587    /**
1588     * For reporting to battery stats the apps currently running foreground
1589     * service.  The ProcessMap is package/uid tuples; each of these contain
1590     * an array of the currently foreground processes.
1591     */
1592    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1593            = new ProcessMap<ArrayList<ProcessRecord>>();
1594
1595    /**
1596     * Set if the systemServer made a call to enterSafeMode.
1597     */
1598    boolean mSafeMode;
1599
1600    /**
1601     * If true, we are running under a test environment so will sample PSS from processes
1602     * much more rapidly to try to collect better data when the tests are rapidly
1603     * running through apps.
1604     */
1605    boolean mTestPssMode = false;
1606
1607    String mDebugApp = null;
1608    boolean mWaitForDebugger = false;
1609    boolean mDebugTransient = false;
1610    String mOrigDebugApp = null;
1611    boolean mOrigWaitForDebugger = false;
1612    boolean mAlwaysFinishActivities = false;
1613    boolean mForceResizableActivities;
1614    /**
1615     * Flag that indicates if multi-window is enabled.
1616     *
1617     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1618     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1619     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1620     * At least one of the forms of multi-window must be enabled in order for this flag to be
1621     * initialized to 'true'.
1622     *
1623     * @see #mSupportsSplitScreenMultiWindow
1624     * @see #mSupportsFreeformWindowManagement
1625     * @see #mSupportsPictureInPicture
1626     * @see #mSupportsMultiDisplay
1627     */
1628    boolean mSupportsMultiWindow;
1629    boolean mSupportsSplitScreenMultiWindow;
1630    boolean mSupportsFreeformWindowManagement;
1631    boolean mSupportsPictureInPicture;
1632    boolean mSupportsMultiDisplay;
1633    boolean mSupportsLeanbackOnly;
1634    IActivityController mController = null;
1635    boolean mControllerIsAMonkey = false;
1636    String mProfileApp = null;
1637    ProcessRecord mProfileProc = null;
1638    ProfilerInfo mProfilerInfo = null;
1639
1640    /**
1641     * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
1642     * is not null, this map is checked and the mapped agent installed during bind-time. Note:
1643     * A non-null agent in mProfileInfo overrides this.
1644     */
1645    private @Nullable Map<String, String> mAppAgentMap = null;
1646
1647    int mProfileType = 0;
1648    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1649    String mMemWatchDumpProcName;
1650    String mMemWatchDumpFile;
1651    int mMemWatchDumpPid;
1652    int mMemWatchDumpUid;
1653    String mTrackAllocationApp = null;
1654    String mNativeDebuggingApp = null;
1655
1656    final long[] mTmpLong = new long[3];
1657
1658    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1659
1660    /**
1661     * A global counter for generating sequence numbers.
1662     * This value will be used when incrementing sequence numbers in individual uidRecords.
1663     *
1664     * Having a global counter ensures that seq numbers are monotonically increasing for a
1665     * particular uid even when the uidRecord is re-created.
1666     */
1667    @GuardedBy("this")
1668    @VisibleForTesting
1669    long mProcStateSeqCounter = 0;
1670
1671    /**
1672     * A global counter for generating sequence numbers to uniquely identify pending process starts.
1673     */
1674    @GuardedBy("this")
1675    private long mProcStartSeqCounter = 0;
1676
1677    /**
1678     * Contains {@link ProcessRecord} objects for pending process starts.
1679     *
1680     * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1681     */
1682    @GuardedBy("this")
1683    private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1684
1685    private final Injector mInjector;
1686
1687    static final class ProcessChangeItem {
1688        static final int CHANGE_ACTIVITIES = 1<<0;
1689        int changes;
1690        int uid;
1691        int pid;
1692        int processState;
1693        boolean foregroundActivities;
1694    }
1695
1696    static final class UidObserverRegistration {
1697        final int uid;
1698        final String pkg;
1699        final int which;
1700        final int cutpoint;
1701
1702        final SparseIntArray lastProcStates;
1703
1704        // Please keep the enum lists in sync
1705        private static int[] ORIG_ENUMS = new int[]{
1706                ActivityManager.UID_OBSERVER_IDLE,
1707                ActivityManager.UID_OBSERVER_ACTIVE,
1708                ActivityManager.UID_OBSERVER_GONE,
1709                ActivityManager.UID_OBSERVER_PROCSTATE,
1710        };
1711        private static int[] PROTO_ENUMS = new int[]{
1712                ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
1713                ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
1714                ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
1715                ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
1716        };
1717
1718        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1719            uid = _uid;
1720            pkg = _pkg;
1721            which = _which;
1722            cutpoint = _cutpoint;
1723            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1724                lastProcStates = new SparseIntArray();
1725            } else {
1726                lastProcStates = null;
1727            }
1728        }
1729
1730        void writeToProto(ProtoOutputStream proto, long fieldId) {
1731            final long token = proto.start(fieldId);
1732            proto.write(UidObserverRegistrationProto.UID, uid);
1733            proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
1734            ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
1735                    which, ORIG_ENUMS, PROTO_ENUMS);
1736            proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
1737            if (lastProcStates != null) {
1738                final int NI = lastProcStates.size();
1739                for (int i=0; i<NI; i++) {
1740                    final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
1741                    proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
1742                    proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
1743                    proto.end(pToken);
1744                }
1745            }
1746            proto.end(token);
1747        }
1748    }
1749
1750    final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1751
1752    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1753    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1754
1755    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1756    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1757
1758    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1759    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1760
1761    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1762    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1763
1764    OomAdjObserver mCurOomAdjObserver;
1765    int mCurOomAdjUid;
1766
1767    interface OomAdjObserver {
1768        void onOomAdjMessage(String msg);
1769    }
1770
1771    /**
1772     * Runtime CPU use collection thread.  This object's lock is used to
1773     * perform synchronization with the thread (notifying it to run).
1774     */
1775    final Thread mProcessCpuThread;
1776
1777    /**
1778     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1779     * Must acquire this object's lock when accessing it.
1780     * NOTE: this lock will be held while doing long operations (trawling
1781     * through all processes in /proc), so it should never be acquired by
1782     * any critical paths such as when holding the main activity manager lock.
1783     */
1784    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1785            MONITOR_THREAD_CPU_USAGE);
1786    final AtomicLong mLastCpuTime = new AtomicLong(0);
1787    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1788    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1789
1790    long mLastWriteTime = 0;
1791
1792    /**
1793     * Used to retain an update lock when the foreground activity is in
1794     * immersive mode.
1795     */
1796    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1797
1798    /**
1799     * Set to true after the system has finished booting.
1800     */
1801    boolean mBooted = false;
1802
1803    WindowManagerService mWindowManager;
1804    final ActivityThread mSystemThread;
1805
1806    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1807        final ProcessRecord mApp;
1808        final int mPid;
1809        final IApplicationThread mAppThread;
1810
1811        AppDeathRecipient(ProcessRecord app, int pid,
1812                IApplicationThread thread) {
1813            if (DEBUG_ALL) Slog.v(
1814                TAG, "New death recipient " + this
1815                + " for thread " + thread.asBinder());
1816            mApp = app;
1817            mPid = pid;
1818            mAppThread = thread;
1819        }
1820
1821        @Override
1822        public void binderDied() {
1823            if (DEBUG_ALL) Slog.v(
1824                TAG, "Death received in " + this
1825                + " for thread " + mAppThread.asBinder());
1826            synchronized(ActivityManagerService.this) {
1827                appDiedLocked(mApp, mPid, mAppThread, true);
1828            }
1829        }
1830    }
1831
1832    static final int SHOW_ERROR_UI_MSG = 1;
1833    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1834    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1835    static final int UPDATE_CONFIGURATION_MSG = 4;
1836    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1837    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1838    static final int SERVICE_TIMEOUT_MSG = 12;
1839    static final int UPDATE_TIME_ZONE = 13;
1840    static final int SHOW_UID_ERROR_UI_MSG = 14;
1841    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1842    static final int PROC_START_TIMEOUT_MSG = 20;
1843    static final int KILL_APPLICATION_MSG = 22;
1844    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1845    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1846    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1847    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1848    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1849    static final int CLEAR_DNS_CACHE_MSG = 28;
1850    static final int UPDATE_HTTP_PROXY_MSG = 29;
1851    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1852    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1853    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1854    static final int REPORT_MEM_USAGE_MSG = 33;
1855    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1856    static final int PERSIST_URI_GRANTS_MSG = 38;
1857    static final int REQUEST_ALL_PSS_MSG = 39;
1858    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1859    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1860    static final int FINISH_BOOTING_MSG = 45;
1861    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1862    static final int DISMISS_DIALOG_UI_MSG = 48;
1863    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1864    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1865    static final int DELETE_DUMPHEAP_MSG = 51;
1866    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1867    static final int REPORT_TIME_TRACKER_MSG = 54;
1868    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1869    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1870    static final int IDLE_UIDS_MSG = 58;
1871    static final int LOG_STACK_STATE = 60;
1872    static final int VR_MODE_CHANGE_MSG = 61;
1873    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1874    static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
1875    static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
1876    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1877    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1878    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1879    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1880    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1881
1882    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1883    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1884    static final int FIRST_COMPAT_MODE_MSG = 300;
1885    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1886
1887    static ServiceThread sKillThread = null;
1888    static KillHandler sKillHandler = null;
1889
1890    CompatModeDialog mCompatModeDialog;
1891    long mLastMemUsageReportTime = 0;
1892
1893    /**
1894     * Flag whether the current user is a "monkey", i.e. whether
1895     * the UI is driven by a UI automation tool.
1896     */
1897    private boolean mUserIsMonkey;
1898
1899    /** The dimensions of the thumbnails in the Recents UI. */
1900    int mThumbnailWidth;
1901    int mThumbnailHeight;
1902    float mFullscreenThumbnailScale;
1903
1904    final ServiceThread mHandlerThread;
1905    final MainHandler mHandler;
1906    final Handler mUiHandler;
1907    final ServiceThread mProcStartHandlerThread;
1908    final Handler mProcStartHandler;
1909
1910    final ActivityManagerConstants mConstants;
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 REQUEST_ALL_PSS_MSG: {
2324                synchronized (ActivityManagerService.this) {
2325                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2326                }
2327                break;
2328            }
2329            case UPDATE_TIME_PREFERENCE_MSG: {
2330                // The user's time format preference might have changed.
2331                // For convenience we re-use the Intent extra values.
2332                synchronized (ActivityManagerService.this) {
2333                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2334                        ProcessRecord r = mLruProcesses.get(i);
2335                        if (r.thread != null) {
2336                            try {
2337                                r.thread.updateTimePrefs(msg.arg1);
2338                            } catch (RemoteException ex) {
2339                                Slog.w(TAG, "Failed to update preferences for: "
2340                                        + r.info.processName);
2341                            }
2342                        }
2343                    }
2344                }
2345                break;
2346            }
2347            case ENTER_ANIMATION_COMPLETE_MSG: {
2348                synchronized (ActivityManagerService.this) {
2349                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2350                    if (r != null && r.app != null && r.app.thread != null) {
2351                        try {
2352                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2353                        } catch (RemoteException e) {
2354                        }
2355                    }
2356                }
2357                break;
2358            }
2359            case FINISH_BOOTING_MSG: {
2360                if (msg.arg1 != 0) {
2361                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2362                    finishBooting();
2363                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2364                }
2365                if (msg.arg2 != 0) {
2366                    enableScreenAfterBoot();
2367                }
2368                break;
2369            }
2370            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2371                try {
2372                    Locale l = (Locale) msg.obj;
2373                    IBinder service = ServiceManager.getService("mount");
2374                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2375                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2376                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2377                } catch (RemoteException e) {
2378                    Log.e(TAG, "Error storing locale for decryption UI", e);
2379                }
2380                break;
2381            }
2382            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2383                final int uid = msg.arg1;
2384                final byte[] firstPacket = (byte[]) msg.obj;
2385
2386                synchronized (mPidsSelfLocked) {
2387                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2388                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2389                        if (p.uid == uid) {
2390                            try {
2391                                p.thread.notifyCleartextNetwork(firstPacket);
2392                            } catch (RemoteException ignored) {
2393                            }
2394                        }
2395                    }
2396                }
2397                break;
2398            }
2399            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2400                final String procName;
2401                final int uid;
2402                final long memLimit;
2403                final String reportPackage;
2404                synchronized (ActivityManagerService.this) {
2405                    procName = mMemWatchDumpProcName;
2406                    uid = mMemWatchDumpUid;
2407                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2408                    if (val == null) {
2409                        val = mMemWatchProcesses.get(procName, 0);
2410                    }
2411                    if (val != null) {
2412                        memLimit = val.first;
2413                        reportPackage = val.second;
2414                    } else {
2415                        memLimit = 0;
2416                        reportPackage = null;
2417                    }
2418                }
2419                if (procName == null) {
2420                    return;
2421                }
2422
2423                if (DEBUG_PSS) Slog.d(TAG_PSS,
2424                        "Showing dump heap notification from " + procName + "/" + uid);
2425
2426                INotificationManager inm = NotificationManager.getService();
2427                if (inm == null) {
2428                    return;
2429                }
2430
2431                String text = mContext.getString(R.string.dump_heap_notification, procName);
2432
2433
2434                Intent deleteIntent = new Intent();
2435                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2436                Intent intent = new Intent();
2437                intent.setClassName("android", DumpHeapActivity.class.getName());
2438                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2439                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2440                if (reportPackage != null) {
2441                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2442                }
2443                int userId = UserHandle.getUserId(uid);
2444                Notification notification =
2445                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2446                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2447                        .setWhen(0)
2448                        .setOngoing(true)
2449                        .setAutoCancel(true)
2450                        .setTicker(text)
2451                        .setColor(mContext.getColor(
2452                                com.android.internal.R.color.system_notification_accent_color))
2453                        .setContentTitle(text)
2454                        .setContentText(
2455                                mContext.getText(R.string.dump_heap_notification_detail))
2456                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2457                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2458                                new UserHandle(userId)))
2459                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2460                                deleteIntent, 0, UserHandle.SYSTEM))
2461                        .build();
2462
2463                try {
2464                    inm.enqueueNotificationWithTag("android", "android", null,
2465                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2466                            notification, userId);
2467                } catch (RuntimeException e) {
2468                    Slog.w(ActivityManagerService.TAG,
2469                            "Error showing notification for dump heap", e);
2470                } catch (RemoteException e) {
2471                }
2472            } break;
2473            case DELETE_DUMPHEAP_MSG: {
2474                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2475                        null, DumpHeapActivity.JAVA_URI,
2476                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2477                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2478                        UserHandle.myUserId());
2479                synchronized (ActivityManagerService.this) {
2480                    mMemWatchDumpFile = null;
2481                    mMemWatchDumpProcName = null;
2482                    mMemWatchDumpPid = -1;
2483                    mMemWatchDumpUid = -1;
2484                }
2485            } break;
2486            case REPORT_TIME_TRACKER_MSG: {
2487                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2488                tracker.deliverResult(mContext);
2489            } break;
2490            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2491                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2492                try {
2493                    connection.shutdown();
2494                } catch (RemoteException e) {
2495                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2496                }
2497                // Only a UiAutomation can set this flag and now that
2498                // it is finished we make sure it is reset to its default.
2499                mUserIsMonkey = false;
2500            } break;
2501            case IDLE_UIDS_MSG: {
2502                idleUids();
2503            } break;
2504            case VR_MODE_CHANGE_MSG: {
2505                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2506                    return;
2507                }
2508                synchronized (ActivityManagerService.this) {
2509                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2510                    mWindowManager.disableNonVrUi(disableNonVrUi);
2511                    if (disableNonVrUi) {
2512                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2513                        // then remove the pinned stack.
2514                        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2515                    }
2516                }
2517            } break;
2518            case DISPATCH_SCREEN_AWAKE_MSG: {
2519                final boolean isAwake = msg.arg1 != 0;
2520                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2521                    mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2522                }
2523            } break;
2524            case DISPATCH_SCREEN_KEYGUARD_MSG: {
2525                final boolean isShowing = msg.arg1 != 0;
2526                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2527                    mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2528                }
2529            } break;
2530            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2531                synchronized (ActivityManagerService.this) {
2532                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2533                        ProcessRecord r = mLruProcesses.get(i);
2534                        if (r.thread != null) {
2535                            try {
2536                                r.thread.handleTrustStorageUpdate();
2537                            } catch (RemoteException ex) {
2538                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2539                                        r.info.processName);
2540                            }
2541                        }
2542                    }
2543                }
2544            } break;
2545            }
2546        }
2547    };
2548
2549    static final int COLLECT_PSS_BG_MSG = 1;
2550
2551    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2552        @Override
2553        public void handleMessage(Message msg) {
2554            switch (msg.what) {
2555            case COLLECT_PSS_BG_MSG: {
2556                long start = SystemClock.uptimeMillis();
2557                MemInfoReader memInfo = null;
2558                synchronized (ActivityManagerService.this) {
2559                    if (mFullPssPending) {
2560                        mFullPssPending = false;
2561                        memInfo = new MemInfoReader();
2562                    }
2563                }
2564                if (memInfo != null) {
2565                    updateCpuStatsNow();
2566                    long nativeTotalPss = 0;
2567                    final List<ProcessCpuTracker.Stats> stats;
2568                    synchronized (mProcessCpuTracker) {
2569                        stats = mProcessCpuTracker.getStats( (st)-> {
2570                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2571                        });
2572                    }
2573                    final int N = stats.size();
2574                    for (int j = 0; j < N; j++) {
2575                        synchronized (mPidsSelfLocked) {
2576                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2577                                // This is one of our own processes; skip it.
2578                                continue;
2579                            }
2580                        }
2581                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2582                    }
2583                    memInfo.readMemInfo();
2584                    synchronized (ActivityManagerService.this) {
2585                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2586                                + (SystemClock.uptimeMillis()-start) + "ms");
2587                        final long cachedKb = memInfo.getCachedSizeKb();
2588                        final long freeKb = memInfo.getFreeSizeKb();
2589                        final long zramKb = memInfo.getZramTotalSizeKb();
2590                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2591                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2592                                kernelKb*1024, nativeTotalPss*1024);
2593                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2594                                nativeTotalPss);
2595                    }
2596                }
2597
2598                int num = 0;
2599                long[] tmp = new long[3];
2600                do {
2601                    ProcessRecord proc;
2602                    int procState;
2603                    int statType;
2604                    int pid;
2605                    long lastPssTime;
2606                    synchronized (ActivityManagerService.this) {
2607                        if (mPendingPssProcesses.size() <= 0) {
2608                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2609                                    "Collected pss of " + num + " processes in "
2610                                    + (SystemClock.uptimeMillis() - start) + "ms");
2611                            mPendingPssProcesses.clear();
2612                            return;
2613                        }
2614                        proc = mPendingPssProcesses.remove(0);
2615                        procState = proc.pssProcState;
2616                        statType = proc.pssStatType;
2617                        lastPssTime = proc.lastPssTime;
2618                        if (proc.thread != null && procState == proc.setProcState
2619                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2620                                        < SystemClock.uptimeMillis()) {
2621                            pid = proc.pid;
2622                        } else {
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    @VisibleForTesting
2830    public ActivityManagerService(Injector injector) {
2831        mInjector = injector;
2832        mContext = mInjector.getContext();
2833        mUiContext = null;
2834        GL_ES_VERSION = 0;
2835        mActivityStartController = null;
2836        mAppErrors = null;
2837        mAppWarnings = null;
2838        mAppOpsService = mInjector.getAppOpsService(null, null);
2839        mBatteryStatsService = null;
2840        mCompatModePackages = null;
2841        mConstants = null;
2842        mGrantFile = null;
2843        mHandler = null;
2844        mHandlerThread = null;
2845        mIntentFirewall = null;
2846        mKeyguardController = null;
2847        mPermissionReviewRequired = false;
2848        mProcessCpuThread = null;
2849        mProcessStats = null;
2850        mProviderMap = null;
2851        mRecentTasks = null;
2852        mServices = null;
2853        mStackSupervisor = null;
2854        mSystemThread = null;
2855        mTaskChangeNotificationController = null;
2856        mUiHandler = injector.getUiHandler(null);
2857        mUserController = null;
2858        mVrController = null;
2859        mLockTaskController = null;
2860        mLifecycleManager = null;
2861        mProcStartHandlerThread = null;
2862        mProcStartHandler = null;
2863    }
2864
2865    // Note: This method is invoked on the main thread but may need to attach various
2866    // handlers to other threads.  So take care to be explicit about the looper.
2867    public ActivityManagerService(Context systemContext) {
2868        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2869        mInjector = new Injector();
2870        mContext = systemContext;
2871
2872        mFactoryTest = FactoryTest.getMode();
2873        mSystemThread = ActivityThread.currentActivityThread();
2874        mUiContext = mSystemThread.getSystemUiContext();
2875
2876        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2877
2878        mPermissionReviewRequired = mContext.getResources().getBoolean(
2879                com.android.internal.R.bool.config_permissionReviewRequired);
2880
2881        mHandlerThread = new ServiceThread(TAG,
2882                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2883        mHandlerThread.start();
2884        mHandler = new MainHandler(mHandlerThread.getLooper());
2885        mUiHandler = mInjector.getUiHandler(this);
2886
2887        mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
2888                THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
2889        mProcStartHandlerThread.start();
2890        mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
2891
2892        mConstants = new ActivityManagerConstants(this, mHandler);
2893
2894        /* static; one-time init here */
2895        if (sKillHandler == null) {
2896            sKillThread = new ServiceThread(TAG + ":kill",
2897                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2898            sKillThread.start();
2899            sKillHandler = new KillHandler(sKillThread.getLooper());
2900        }
2901
2902        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2903                "foreground", BROADCAST_FG_TIMEOUT, false);
2904        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2905                "background", BROADCAST_BG_TIMEOUT, true);
2906        mBroadcastQueues[0] = mFgBroadcastQueue;
2907        mBroadcastQueues[1] = mBgBroadcastQueue;
2908
2909        mServices = new ActiveServices(this);
2910        mProviderMap = new ProviderMap(this);
2911        mAppErrors = new AppErrors(mUiContext, this);
2912
2913        File dataDir = Environment.getDataDirectory();
2914        File systemDir = new File(dataDir, "system");
2915        systemDir.mkdirs();
2916
2917        mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
2918
2919        // TODO: Move creation of battery stats service outside of activity manager service.
2920        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2921        mBatteryStatsService.getActiveStatistics().readLocked();
2922        mBatteryStatsService.scheduleWriteToDisk();
2923        mOnBattery = DEBUG_POWER ? true
2924                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2925        mBatteryStatsService.getActiveStatistics().setCallback(this);
2926
2927        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2928
2929        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2930        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2931                new IAppOpsCallback.Stub() {
2932                    @Override public void opChanged(int op, int uid, String packageName) {
2933                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2934                            if (mAppOpsService.checkOperation(op, uid, packageName)
2935                                    != AppOpsManager.MODE_ALLOWED) {
2936                                runInBackgroundDisabled(uid);
2937                            }
2938                        }
2939                    }
2940                });
2941
2942        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
2943
2944        mUserController = new UserController(this);
2945
2946        mVrController = new VrController(this);
2947
2948        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2949            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2950
2951        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2952            mUseFifoUiScheduling = true;
2953        }
2954
2955        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2956        mTempConfig.setToDefaults();
2957        mTempConfig.setLocales(LocaleList.getDefault());
2958        mConfigurationSeq = mTempConfig.seq = 1;
2959        mStackSupervisor = createStackSupervisor();
2960        mStackSupervisor.onConfigurationChanged(mTempConfig);
2961        mKeyguardController = mStackSupervisor.getKeyguardController();
2962        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2963        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2964        mTaskChangeNotificationController =
2965                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2966        mActivityStartController = new ActivityStartController(this);
2967        mRecentTasks = createRecentTasks();
2968        mStackSupervisor.setRecentTasks(mRecentTasks);
2969        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
2970        mLifecycleManager = new ClientLifecycleManager();
2971
2972        mProcessCpuThread = new Thread("CpuTracker") {
2973            @Override
2974            public void run() {
2975                synchronized (mProcessCpuTracker) {
2976                    mProcessCpuInitLatch.countDown();
2977                    mProcessCpuTracker.init();
2978                }
2979                while (true) {
2980                    try {
2981                        try {
2982                            synchronized(this) {
2983                                final long now = SystemClock.uptimeMillis();
2984                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2985                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2986                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2987                                //        + ", write delay=" + nextWriteDelay);
2988                                if (nextWriteDelay < nextCpuDelay) {
2989                                    nextCpuDelay = nextWriteDelay;
2990                                }
2991                                if (nextCpuDelay > 0) {
2992                                    mProcessCpuMutexFree.set(true);
2993                                    this.wait(nextCpuDelay);
2994                                }
2995                            }
2996                        } catch (InterruptedException e) {
2997                        }
2998                        updateCpuStatsNow();
2999                    } catch (Exception e) {
3000                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
3001                    }
3002                }
3003            }
3004        };
3005
3006        Watchdog.getInstance().addMonitor(this);
3007        Watchdog.getInstance().addThread(mHandler);
3008    }
3009
3010    protected ActivityStackSupervisor createStackSupervisor() {
3011        final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
3012        supervisor.initialize();
3013        return supervisor;
3014    }
3015
3016    protected RecentTasks createRecentTasks() {
3017        return new RecentTasks(this, mStackSupervisor);
3018    }
3019
3020    RecentTasks getRecentTasks() {
3021        return mRecentTasks;
3022    }
3023
3024    public void setSystemServiceManager(SystemServiceManager mgr) {
3025        mSystemServiceManager = mgr;
3026    }
3027
3028    public void setInstaller(Installer installer) {
3029        mInstaller = installer;
3030    }
3031
3032    private void start() {
3033        removeAllProcessGroups();
3034        mProcessCpuThread.start();
3035
3036        mBatteryStatsService.publish();
3037        mAppOpsService.publish(mContext);
3038        Slog.d("AppOps", "AppOpsService published");
3039        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
3040        // Wait for the synchronized block started in mProcessCpuThread,
3041        // so that any other acccess to mProcessCpuTracker from main thread
3042        // will be blocked during mProcessCpuTracker initialization.
3043        try {
3044            mProcessCpuInitLatch.await();
3045        } catch (InterruptedException e) {
3046            Slog.wtf(TAG, "Interrupted wait during start", e);
3047            Thread.currentThread().interrupt();
3048            throw new IllegalStateException("Interrupted wait during start");
3049        }
3050    }
3051
3052    void onUserStoppedLocked(int userId) {
3053        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
3054        mAllowAppSwitchUids.remove(userId);
3055    }
3056
3057    public void initPowerManagement() {
3058        mStackSupervisor.initPowerManagement();
3059        mBatteryStatsService.initPowerManagement();
3060        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
3061        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
3062        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
3063        mVoiceWakeLock.setReferenceCounted(false);
3064    }
3065
3066    private ArraySet<String> getBackgroundLaunchBroadcasts() {
3067        if (mBackgroundLaunchBroadcasts == null) {
3068            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
3069        }
3070        return mBackgroundLaunchBroadcasts;
3071    }
3072
3073    @Override
3074    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3075            throws RemoteException {
3076        if (code == SYSPROPS_TRANSACTION) {
3077            // We need to tell all apps about the system property change.
3078            ArrayList<IBinder> procs = new ArrayList<IBinder>();
3079            synchronized(this) {
3080                final int NP = mProcessNames.getMap().size();
3081                for (int ip=0; ip<NP; ip++) {
3082                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3083                    final int NA = apps.size();
3084                    for (int ia=0; ia<NA; ia++) {
3085                        ProcessRecord app = apps.valueAt(ia);
3086                        if (app.thread != null) {
3087                            procs.add(app.thread.asBinder());
3088                        }
3089                    }
3090                }
3091            }
3092
3093            int N = procs.size();
3094            for (int i=0; i<N; i++) {
3095                Parcel data2 = Parcel.obtain();
3096                try {
3097                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
3098                            Binder.FLAG_ONEWAY);
3099                } catch (RemoteException e) {
3100                }
3101                data2.recycle();
3102            }
3103        }
3104        try {
3105            return super.onTransact(code, data, reply, flags);
3106        } catch (RuntimeException e) {
3107            // The activity manager only throws certain exceptions intentionally, so let's
3108            // log all others.
3109            if (!(e instanceof SecurityException
3110                    || e instanceof IllegalArgumentException
3111                    || e instanceof IllegalStateException)) {
3112                Slog.wtf(TAG, "Activity Manager Crash."
3113                        + " UID:" + Binder.getCallingUid()
3114                        + " PID:" + Binder.getCallingPid()
3115                        + " TRANS:" + code, e);
3116            }
3117            throw e;
3118        }
3119    }
3120
3121    void updateCpuStats() {
3122        final long now = SystemClock.uptimeMillis();
3123        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3124            return;
3125        }
3126        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3127            synchronized (mProcessCpuThread) {
3128                mProcessCpuThread.notify();
3129            }
3130        }
3131    }
3132
3133    void updateCpuStatsNow() {
3134        synchronized (mProcessCpuTracker) {
3135            mProcessCpuMutexFree.set(false);
3136            final long now = SystemClock.uptimeMillis();
3137            boolean haveNewCpuStats = false;
3138
3139            if (MONITOR_CPU_USAGE &&
3140                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3141                mLastCpuTime.set(now);
3142                mProcessCpuTracker.update();
3143                if (mProcessCpuTracker.hasGoodLastStats()) {
3144                    haveNewCpuStats = true;
3145                    //Slog.i(TAG, mProcessCpu.printCurrentState());
3146                    //Slog.i(TAG, "Total CPU usage: "
3147                    //        + mProcessCpu.getTotalCpuPercent() + "%");
3148
3149                    // Slog the cpu usage if the property is set.
3150                    if ("true".equals(SystemProperties.get("events.cpu"))) {
3151                        int user = mProcessCpuTracker.getLastUserTime();
3152                        int system = mProcessCpuTracker.getLastSystemTime();
3153                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
3154                        int irq = mProcessCpuTracker.getLastIrqTime();
3155                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3156                        int idle = mProcessCpuTracker.getLastIdleTime();
3157
3158                        int total = user + system + iowait + irq + softIrq + idle;
3159                        if (total == 0) total = 1;
3160
3161                        EventLog.writeEvent(EventLogTags.CPU,
3162                                ((user+system+iowait+irq+softIrq) * 100) / total,
3163                                (user * 100) / total,
3164                                (system * 100) / total,
3165                                (iowait * 100) / total,
3166                                (irq * 100) / total,
3167                                (softIrq * 100) / total);
3168                    }
3169                }
3170            }
3171
3172            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3173            synchronized(bstats) {
3174                synchronized(mPidsSelfLocked) {
3175                    if (haveNewCpuStats) {
3176                        if (bstats.startAddingCpuLocked()) {
3177                            int totalUTime = 0;
3178                            int totalSTime = 0;
3179                            final int N = mProcessCpuTracker.countStats();
3180                            for (int i=0; i<N; i++) {
3181                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3182                                if (!st.working) {
3183                                    continue;
3184                                }
3185                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3186                                totalUTime += st.rel_utime;
3187                                totalSTime += st.rel_stime;
3188                                if (pr != null) {
3189                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3190                                    if (ps == null || !ps.isActive()) {
3191                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3192                                                pr.info.uid, pr.processName);
3193                                    }
3194                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3195                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3196                                    if (pr.lastCpuTime == 0) {
3197                                        pr.lastCpuTime = pr.curCpuTime;
3198                                    }
3199                                } else {
3200                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3201                                    if (ps == null || !ps.isActive()) {
3202                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3203                                                bstats.mapUid(st.uid), st.name);
3204                                    }
3205                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3206                                }
3207                            }
3208                            final int userTime = mProcessCpuTracker.getLastUserTime();
3209                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3210                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3211                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3212                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3213                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3214                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3215                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3216                        }
3217                    }
3218                }
3219
3220                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3221                    mLastWriteTime = now;
3222                    mBatteryStatsService.scheduleWriteToDisk();
3223                }
3224            }
3225        }
3226    }
3227
3228    @Override
3229    public void batteryNeedsCpuUpdate() {
3230        updateCpuStatsNow();
3231    }
3232
3233    @Override
3234    public void batteryPowerChanged(boolean onBattery) {
3235        // When plugging in, update the CPU stats first before changing
3236        // the plug state.
3237        updateCpuStatsNow();
3238        synchronized (this) {
3239            synchronized(mPidsSelfLocked) {
3240                mOnBattery = DEBUG_POWER ? true : onBattery;
3241            }
3242        }
3243    }
3244
3245    @Override
3246    public void batterySendBroadcast(Intent intent) {
3247        synchronized (this) {
3248            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3249                    OP_NONE, null, false, false,
3250                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3251        }
3252    }
3253
3254    /**
3255     * Initialize the application bind args. These are passed to each
3256     * process when the bindApplication() IPC is sent to the process. They're
3257     * lazily setup to make sure the services are running when they're asked for.
3258     */
3259    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3260        // Isolated processes won't get this optimization, so that we don't
3261        // violate the rules about which services they have access to.
3262        if (isolated) {
3263            if (mIsolatedAppBindArgs == null) {
3264                mIsolatedAppBindArgs = new HashMap<>();
3265                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3266            }
3267            return mIsolatedAppBindArgs;
3268        }
3269
3270        if (mAppBindArgs == null) {
3271            mAppBindArgs = new HashMap<>();
3272
3273            // Setup the application init args
3274            mAppBindArgs.put("package", ServiceManager.getService("package"));
3275            mAppBindArgs.put("window", ServiceManager.getService("window"));
3276            mAppBindArgs.put(Context.ALARM_SERVICE,
3277                    ServiceManager.getService(Context.ALARM_SERVICE));
3278        }
3279        return mAppBindArgs;
3280    }
3281
3282    /**
3283     * Update AMS states when an activity is resumed. This should only be called by
3284     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3285     */
3286    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3287        final TaskRecord task = r.getTask();
3288        if (task.isActivityTypeStandard()) {
3289            if (mCurAppTimeTracker != r.appTimeTracker) {
3290                // We are switching app tracking.  Complete the current one.
3291                if (mCurAppTimeTracker != null) {
3292                    mCurAppTimeTracker.stop();
3293                    mHandler.obtainMessage(
3294                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3295                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3296                    mCurAppTimeTracker = null;
3297                }
3298                if (r.appTimeTracker != null) {
3299                    mCurAppTimeTracker = r.appTimeTracker;
3300                    startTimeTrackingFocusedActivityLocked();
3301                }
3302            } else {
3303                startTimeTrackingFocusedActivityLocked();
3304            }
3305        } else {
3306            r.appTimeTracker = null;
3307        }
3308        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3309        // TODO: Probably not, because we don't want to resume voice on switching
3310        // back to this activity
3311        if (task.voiceInteractor != null) {
3312            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3313        } else {
3314            finishRunningVoiceLocked();
3315
3316            if (mLastResumedActivity != null) {
3317                final IVoiceInteractionSession session;
3318
3319                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3320                if (lastResumedActivityTask != null
3321                        && lastResumedActivityTask.voiceSession != null) {
3322                    session = lastResumedActivityTask.voiceSession;
3323                } else {
3324                    session = mLastResumedActivity.voiceSession;
3325                }
3326
3327                if (session != null) {
3328                    // We had been in a voice interaction session, but now focused has
3329                    // move to something different.  Just finish the session, we can't
3330                    // return to it and retain the proper state and synchronization with
3331                    // the voice interaction service.
3332                    finishVoiceTask(session);
3333                }
3334            }
3335        }
3336
3337        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3338            mUserController.sendForegroundProfileChanged(r.userId);
3339        }
3340        mLastResumedActivity = r;
3341
3342        mWindowManager.setFocusedApp(r.appToken, true);
3343
3344        applyUpdateLockStateLocked(r);
3345        applyUpdateVrModeLocked(r);
3346
3347        EventLogTags.writeAmSetResumedActivity(
3348                r == null ? -1 : r.userId,
3349                r == null ? "NULL" : r.shortComponentName,
3350                reason);
3351    }
3352
3353    @Override
3354    public void setFocusedStack(int stackId) {
3355        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3356        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3357        final long callingId = Binder.clearCallingIdentity();
3358        try {
3359            synchronized (this) {
3360                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3361                if (stack == null) {
3362                    Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3363                    return;
3364                }
3365                final ActivityRecord r = stack.topRunningActivityLocked();
3366                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3367                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3368                }
3369            }
3370        } finally {
3371            Binder.restoreCallingIdentity(callingId);
3372        }
3373    }
3374
3375    @Override
3376    public void setFocusedTask(int taskId) {
3377        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3378        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3379        final long callingId = Binder.clearCallingIdentity();
3380        try {
3381            synchronized (this) {
3382                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3383                if (task == null) {
3384                    return;
3385                }
3386                final ActivityRecord r = task.topRunningActivityLocked();
3387                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3388                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3389                }
3390            }
3391        } finally {
3392            Binder.restoreCallingIdentity(callingId);
3393        }
3394    }
3395
3396    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3397    @Override
3398    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3399        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3400                "registerTaskStackListener()");
3401        mTaskChangeNotificationController.registerTaskStackListener(listener);
3402    }
3403
3404    /**
3405     * Unregister a task stack listener so that it stops receiving callbacks.
3406     */
3407    @Override
3408    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3409        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3410                "unregisterTaskStackListener()");
3411         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3412     }
3413
3414    @Override
3415    public void notifyActivityDrawn(IBinder token) {
3416        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3417        synchronized (this) {
3418            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3419            if (r != null) {
3420                r.getStack().notifyActivityDrawnLocked(r);
3421            }
3422        }
3423    }
3424
3425    final void applyUpdateLockStateLocked(ActivityRecord r) {
3426        // Modifications to the UpdateLock state are done on our handler, outside
3427        // the activity manager's locks.  The new state is determined based on the
3428        // state *now* of the relevant activity record.  The object is passed to
3429        // the handler solely for logging detail, not to be consulted/modified.
3430        final boolean nextState = r != null && r.immersive;
3431        mHandler.sendMessage(
3432                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3433    }
3434
3435    final void applyUpdateVrModeLocked(ActivityRecord r) {
3436        // VR apps are expected to run in a main display. If an app is turning on VR for
3437        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3438        // fullscreen stack before enabling VR Mode.
3439        // TODO: The goal of this code is to keep the VR app on the main display. When the
3440        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3441        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3442        // option would be a better choice here.
3443        if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3444            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3445                    + " to main stack for VR");
3446            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3447                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3448            moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3449        }
3450        mHandler.sendMessage(
3451                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3452    }
3453
3454    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3455        Message msg = Message.obtain();
3456        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3457        msg.obj = r.getTask().askedCompatMode ? null : r;
3458        mUiHandler.sendMessage(msg);
3459    }
3460
3461    final AppWarnings getAppWarningsLocked() {
3462        return mAppWarnings;
3463    }
3464
3465    /**
3466     * Shows app warning dialogs, if necessary.
3467     *
3468     * @param r activity record for which the warnings may be displayed
3469     */
3470    final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3471        mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3472        mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3473        mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
3474    }
3475
3476    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3477            String what, Object obj, ProcessRecord srcApp) {
3478        app.lastActivityTime = now;
3479
3480        if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3481            // Don't want to touch dependent processes that are hosting activities.
3482            return index;
3483        }
3484
3485        int lrui = mLruProcesses.lastIndexOf(app);
3486        if (lrui < 0) {
3487            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3488                    + what + " " + obj + " from " + srcApp);
3489            return index;
3490        }
3491
3492        if (lrui >= index) {
3493            // Don't want to cause this to move dependent processes *back* in the
3494            // list as if they were less frequently used.
3495            return index;
3496        }
3497
3498        if (lrui >= mLruProcessActivityStart) {
3499            // Don't want to touch dependent processes that are hosting activities.
3500            return index;
3501        }
3502
3503        mLruProcesses.remove(lrui);
3504        if (index > 0) {
3505            index--;
3506        }
3507        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3508                + " in LRU list: " + app);
3509        mLruProcesses.add(index, app);
3510        return index;
3511    }
3512
3513    static void killProcessGroup(int uid, int pid) {
3514        if (sKillHandler != null) {
3515            sKillHandler.sendMessage(
3516                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3517        } else {
3518            Slog.w(TAG, "Asked to kill process group before system bringup!");
3519            Process.killProcessGroup(uid, pid);
3520        }
3521    }
3522
3523    final void removeLruProcessLocked(ProcessRecord app) {
3524        int lrui = mLruProcesses.lastIndexOf(app);
3525        if (lrui >= 0) {
3526            if (!app.killed) {
3527                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3528                if (app.pid > 0) {
3529                    killProcessQuiet(app.pid);
3530                    killProcessGroup(app.uid, app.pid);
3531                } else {
3532                    app.pendingStart = false;
3533                }
3534            }
3535            if (lrui <= mLruProcessActivityStart) {
3536                mLruProcessActivityStart--;
3537            }
3538            if (lrui <= mLruProcessServiceStart) {
3539                mLruProcessServiceStart--;
3540            }
3541            mLruProcesses.remove(lrui);
3542        }
3543    }
3544
3545    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3546            ProcessRecord client) {
3547        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3548                || app.treatLikeActivity || app.recentTasks.size() > 0;
3549        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3550        if (!activityChange && hasActivity) {
3551            // The process has activities, so we are only allowing activity-based adjustments
3552            // to move it.  It should be kept in the front of the list with other
3553            // processes that have activities, and we don't want those to change their
3554            // order except due to activity operations.
3555            return;
3556        }
3557
3558        mLruSeq++;
3559        final long now = SystemClock.uptimeMillis();
3560        app.lastActivityTime = now;
3561
3562        // First a quick reject: if the app is already at the position we will
3563        // put it, then there is nothing to do.
3564        if (hasActivity) {
3565            final int N = mLruProcesses.size();
3566            if (N > 0 && mLruProcesses.get(N-1) == app) {
3567                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3568                return;
3569            }
3570        } else {
3571            if (mLruProcessServiceStart > 0
3572                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3573                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3574                return;
3575            }
3576        }
3577
3578        int lrui = mLruProcesses.lastIndexOf(app);
3579
3580        if (app.persistent && lrui >= 0) {
3581            // We don't care about the position of persistent processes, as long as
3582            // they are in the list.
3583            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3584            return;
3585        }
3586
3587        /* In progress: compute new position first, so we can avoid doing work
3588           if the process is not actually going to move.  Not yet working.
3589        int addIndex;
3590        int nextIndex;
3591        boolean inActivity = false, inService = false;
3592        if (hasActivity) {
3593            // Process has activities, put it at the very tipsy-top.
3594            addIndex = mLruProcesses.size();
3595            nextIndex = mLruProcessServiceStart;
3596            inActivity = true;
3597        } else if (hasService) {
3598            // Process has services, put it at the top of the service list.
3599            addIndex = mLruProcessActivityStart;
3600            nextIndex = mLruProcessServiceStart;
3601            inActivity = true;
3602            inService = true;
3603        } else  {
3604            // Process not otherwise of interest, it goes to the top of the non-service area.
3605            addIndex = mLruProcessServiceStart;
3606            if (client != null) {
3607                int clientIndex = mLruProcesses.lastIndexOf(client);
3608                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3609                        + app);
3610                if (clientIndex >= 0 && addIndex > clientIndex) {
3611                    addIndex = clientIndex;
3612                }
3613            }
3614            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3615        }
3616
3617        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3618                + mLruProcessActivityStart + "): " + app);
3619        */
3620
3621        if (lrui >= 0) {
3622            if (lrui < mLruProcessActivityStart) {
3623                mLruProcessActivityStart--;
3624            }
3625            if (lrui < mLruProcessServiceStart) {
3626                mLruProcessServiceStart--;
3627            }
3628            /*
3629            if (addIndex > lrui) {
3630                addIndex--;
3631            }
3632            if (nextIndex > lrui) {
3633                nextIndex--;
3634            }
3635            */
3636            mLruProcesses.remove(lrui);
3637        }
3638
3639        /*
3640        mLruProcesses.add(addIndex, app);
3641        if (inActivity) {
3642            mLruProcessActivityStart++;
3643        }
3644        if (inService) {
3645            mLruProcessActivityStart++;
3646        }
3647        */
3648
3649        int nextIndex;
3650        if (hasActivity) {
3651            final int N = mLruProcesses.size();
3652            if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
3653                    && mLruProcessActivityStart < (N - 1)) {
3654                // Process doesn't have activities, but has clients with
3655                // activities...  move it up, but one below the top (the top
3656                // should always have a real activity).
3657                if (DEBUG_LRU) Slog.d(TAG_LRU,
3658                        "Adding to second-top of LRU activity list: " + app);
3659                mLruProcesses.add(N - 1, app);
3660                // To keep it from spamming the LRU list (by making a bunch of clients),
3661                // we will push down any other entries owned by the app.
3662                final int uid = app.info.uid;
3663                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3664                    ProcessRecord subProc = mLruProcesses.get(i);
3665                    if (subProc.info.uid == uid) {
3666                        // We want to push this one down the list.  If the process after
3667                        // it is for the same uid, however, don't do so, because we don't
3668                        // want them internally to be re-ordered.
3669                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3670                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3671                                    "Pushing uid " + uid + " swapping at " + i + ": "
3672                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3673                            ProcessRecord tmp = mLruProcesses.get(i);
3674                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3675                            mLruProcesses.set(i - 1, tmp);
3676                            i--;
3677                        }
3678                    } else {
3679                        // A gap, we can stop here.
3680                        break;
3681                    }
3682                }
3683            } else {
3684                // Process has activities, put it at the very tipsy-top.
3685                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3686                mLruProcesses.add(app);
3687            }
3688            nextIndex = mLruProcessServiceStart;
3689        } else if (hasService) {
3690            // Process has services, put it at the top of the service list.
3691            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3692            mLruProcesses.add(mLruProcessActivityStart, app);
3693            nextIndex = mLruProcessServiceStart;
3694            mLruProcessActivityStart++;
3695        } else  {
3696            // Process not otherwise of interest, it goes to the top of the non-service area.
3697            int index = mLruProcessServiceStart;
3698            if (client != null) {
3699                // If there is a client, don't allow the process to be moved up higher
3700                // in the list than that client.
3701                int clientIndex = mLruProcesses.lastIndexOf(client);
3702                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3703                        + " when updating " + app);
3704                if (clientIndex <= lrui) {
3705                    // Don't allow the client index restriction to push it down farther in the
3706                    // list than it already is.
3707                    clientIndex = lrui;
3708                }
3709                if (clientIndex >= 0 && index > clientIndex) {
3710                    index = clientIndex;
3711                }
3712            }
3713            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3714            mLruProcesses.add(index, app);
3715            nextIndex = index-1;
3716            mLruProcessActivityStart++;
3717            mLruProcessServiceStart++;
3718        }
3719
3720        // If the app is currently using a content provider or service,
3721        // bump those processes as well.
3722        for (int j=app.connections.size()-1; j>=0; j--) {
3723            ConnectionRecord cr = app.connections.valueAt(j);
3724            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3725                    && cr.binding.service.app != null
3726                    && cr.binding.service.app.lruSeq != mLruSeq
3727                    && !cr.binding.service.app.persistent) {
3728                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3729                        "service connection", cr, app);
3730            }
3731        }
3732        for (int j=app.conProviders.size()-1; j>=0; j--) {
3733            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3734            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3735                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3736                        "provider reference", cpr, app);
3737            }
3738        }
3739    }
3740
3741    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3742        if (uid == SYSTEM_UID) {
3743            // The system gets to run in any process.  If there are multiple
3744            // processes with the same uid, just pick the first (this
3745            // should never happen).
3746            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3747            if (procs == null) return null;
3748            final int procCount = procs.size();
3749            for (int i = 0; i < procCount; i++) {
3750                final int procUid = procs.keyAt(i);
3751                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3752                    // Don't use an app process or different user process for system component.
3753                    continue;
3754                }
3755                return procs.valueAt(i);
3756            }
3757        }
3758        ProcessRecord proc = mProcessNames.get(processName, uid);
3759        if (false && proc != null && !keepIfLarge
3760                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3761                && proc.lastCachedPss >= 4000) {
3762            // Turn this condition on to cause killing to happen regularly, for testing.
3763            if (proc.baseProcessTracker != null) {
3764                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3765            }
3766            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3767        } else if (proc != null && !keepIfLarge
3768                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3769                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3770            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3771            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3772                if (proc.baseProcessTracker != null) {
3773                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3774                }
3775                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3776            }
3777        }
3778        return proc;
3779    }
3780
3781    void notifyPackageUse(String packageName, int reason) {
3782        synchronized(this) {
3783            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3784        }
3785    }
3786
3787    boolean isNextTransitionForward() {
3788        int transit = mWindowManager.getPendingAppTransition();
3789        return transit == TRANSIT_ACTIVITY_OPEN
3790                || transit == TRANSIT_TASK_OPEN
3791                || transit == TRANSIT_TASK_TO_FRONT;
3792    }
3793
3794    boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3795            String processName, String abiOverride, int uid, Runnable crashHandler) {
3796        synchronized(this) {
3797            ApplicationInfo info = new ApplicationInfo();
3798            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3799            // For isolated processes, the former contains the parent's uid and the latter the
3800            // actual uid of the isolated process.
3801            // In the special case introduced by this method (which is, starting an isolated
3802            // process directly from the SystemServer without an actual parent app process) the
3803            // closest thing to a parent's uid is SYSTEM_UID.
3804            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3805            // the |isolated| logic in the ProcessRecord constructor.
3806            info.uid = SYSTEM_UID;
3807            info.processName = processName;
3808            info.className = entryPoint;
3809            info.packageName = "android";
3810            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3811            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3812                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3813                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3814                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3815                    crashHandler);
3816            return proc != null;
3817        }
3818    }
3819
3820    final ProcessRecord startProcessLocked(String processName,
3821            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3822            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3823            boolean isolated, boolean keepIfLarge) {
3824        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3825                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3826                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3827                null /* crashHandler */);
3828    }
3829
3830    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3831            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3832            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3833            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3834        long startTime = SystemClock.elapsedRealtime();
3835        ProcessRecord app;
3836        if (!isolated) {
3837            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3838            checkTime(startTime, "startProcess: after getProcessRecord");
3839
3840            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3841                // If we are in the background, then check to see if this process
3842                // is bad.  If so, we will just silently fail.
3843                if (mAppErrors.isBadProcessLocked(info)) {
3844                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3845                            + "/" + info.processName);
3846                    return null;
3847                }
3848            } else {
3849                // When the user is explicitly starting a process, then clear its
3850                // crash count so that we won't make it bad until they see at
3851                // least one crash dialog again, and make the process good again
3852                // if it had been bad.
3853                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3854                        + "/" + info.processName);
3855                mAppErrors.resetProcessCrashTimeLocked(info);
3856                if (mAppErrors.isBadProcessLocked(info)) {
3857                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3858                            UserHandle.getUserId(info.uid), info.uid,
3859                            info.processName);
3860                    mAppErrors.clearBadProcessLocked(info);
3861                    if (app != null) {
3862                        app.bad = false;
3863                    }
3864                }
3865            }
3866        } else {
3867            // If this is an isolated process, it can't re-use an existing process.
3868            app = null;
3869        }
3870
3871        // We don't have to do anything more if:
3872        // (1) There is an existing application record; and
3873        // (2) The caller doesn't think it is dead, OR there is no thread
3874        //     object attached to it so we know it couldn't have crashed; and
3875        // (3) There is a pid assigned to it, so it is either starting or
3876        //     already running.
3877        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3878                + " app=" + app + " knownToBeDead=" + knownToBeDead
3879                + " thread=" + (app != null ? app.thread : null)
3880                + " pid=" + (app != null ? app.pid : -1));
3881        if (app != null && app.pid > 0) {
3882            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3883                // We already have the app running, or are waiting for it to
3884                // come up (we have a pid but not yet its thread), so keep it.
3885                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3886                // If this is a new package in the process, add the package to the list
3887                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3888                checkTime(startTime, "startProcess: done, added package to proc");
3889                return app;
3890            }
3891
3892            // An application record is attached to a previous process,
3893            // clean it up now.
3894            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3895            checkTime(startTime, "startProcess: bad proc running, killing");
3896            killProcessGroup(app.uid, app.pid);
3897            handleAppDiedLocked(app, true, true);
3898            checkTime(startTime, "startProcess: done killing old proc");
3899        }
3900
3901        String hostingNameStr = hostingName != null
3902                ? hostingName.flattenToShortString() : null;
3903
3904        if (app == null) {
3905            checkTime(startTime, "startProcess: creating new process record");
3906            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3907            if (app == null) {
3908                Slog.w(TAG, "Failed making new process record for "
3909                        + processName + "/" + info.uid + " isolated=" + isolated);
3910                return null;
3911            }
3912            app.crashHandler = crashHandler;
3913            app.isolatedEntryPoint = entryPoint;
3914            app.isolatedEntryPointArgs = entryPointArgs;
3915            checkTime(startTime, "startProcess: done creating new process record");
3916        } else {
3917            // If this is a new package in the process, add the package to the list
3918            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3919            checkTime(startTime, "startProcess: added package to existing proc");
3920        }
3921
3922        // If the system is not ready yet, then hold off on starting this
3923        // process until it is.
3924        if (!mProcessesReady
3925                && !isAllowedWhileBooting(info)
3926                && !allowWhileBooting) {
3927            if (!mProcessesOnHold.contains(app)) {
3928                mProcessesOnHold.add(app);
3929            }
3930            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3931                    "System not ready, putting on hold: " + app);
3932            checkTime(startTime, "startProcess: returning with proc on hold");
3933            return app;
3934        }
3935
3936        checkTime(startTime, "startProcess: stepping in to startProcess");
3937        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
3938        checkTime(startTime, "startProcess: done starting proc!");
3939        return success ? app : null;
3940    }
3941
3942    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3943        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3944    }
3945
3946    private final void startProcessLocked(ProcessRecord app,
3947            String hostingType, String hostingNameStr) {
3948        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
3949    }
3950
3951    /**
3952     * @return {@code true} if process start is successful, false otherwise.
3953     */
3954    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
3955            String hostingNameStr, String abiOverride) {
3956        if (app.pendingStart) {
3957            return true;
3958        }
3959        long startTime = SystemClock.elapsedRealtime();
3960        if (app.pid > 0 && app.pid != MY_PID) {
3961            checkTime(startTime, "startProcess: removing from pids map");
3962            synchronized (mPidsSelfLocked) {
3963                mPidsSelfLocked.remove(app.pid);
3964                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3965            }
3966            checkTime(startTime, "startProcess: done removing from pids map");
3967            app.setPid(0);
3968        }
3969
3970        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3971                "startProcessLocked removing on hold: " + app);
3972        mProcessesOnHold.remove(app);
3973
3974        checkTime(startTime, "startProcess: starting to update cpu stats");
3975        updateCpuStats();
3976        checkTime(startTime, "startProcess: done updating cpu stats");
3977
3978        try {
3979            try {
3980                final int userId = UserHandle.getUserId(app.uid);
3981                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3982            } catch (RemoteException e) {
3983                throw e.rethrowAsRuntimeException();
3984            }
3985
3986            int uid = app.uid;
3987            int[] gids = null;
3988            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3989            if (!app.isolated) {
3990                int[] permGids = null;
3991                try {
3992                    checkTime(startTime, "startProcess: getting gids from package manager");
3993                    final IPackageManager pm = AppGlobals.getPackageManager();
3994                    permGids = pm.getPackageGids(app.info.packageName,
3995                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3996                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3997                            StorageManagerInternal.class);
3998                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3999                            app.info.packageName);
4000                } catch (RemoteException e) {
4001                    throw e.rethrowAsRuntimeException();
4002                }
4003
4004                /*
4005                 * Add shared application and profile GIDs so applications can share some
4006                 * resources like shared libraries and access user-wide resources
4007                 */
4008                if (ArrayUtils.isEmpty(permGids)) {
4009                    gids = new int[3];
4010                } else {
4011                    gids = new int[permGids.length + 3];
4012                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
4013                }
4014                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
4015                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
4016                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
4017
4018                // Replace any invalid GIDs
4019                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
4020                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
4021            }
4022            checkTime(startTime, "startProcess: building args");
4023            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
4024                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4025                        && mTopComponent != null
4026                        && app.processName.equals(mTopComponent.getPackageName())) {
4027                    uid = 0;
4028                }
4029                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
4030                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
4031                    uid = 0;
4032                }
4033            }
4034            int runtimeFlags = 0;
4035            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4036                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
4037                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
4038                // Also turn on CheckJNI for debuggable apps. It's quite
4039                // awkward to turn on otherwise.
4040                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4041            }
4042            // Run the app in safe mode if its manifest requests so or the
4043            // system is booted in safe mode.
4044            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
4045                mSafeMode == true) {
4046                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
4047            }
4048            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4049                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4050            }
4051            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4052            if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
4053                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4054            }
4055            String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
4056            if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
4057                runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
4058            }
4059            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4060                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4061            }
4062            if ("1".equals(SystemProperties.get("debug.assert"))) {
4063                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
4064            }
4065            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
4066                // Enable all debug flags required by the native debugger.
4067                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
4068                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
4069                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
4070                mNativeDebuggingApp = null;
4071            }
4072
4073            if (app.info.isPrivilegedApp() &&
4074                    SystemProperties.getBoolean("pm.dexopt.priv-apps-oob", false)) {
4075                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
4076            }
4077
4078            if (app.info.isAllowedToUseHiddenApi()) {
4079                // This app is allowed to use undocumented and private APIs. Set
4080                // up its runtime with the appropriate flag.
4081                runtimeFlags |= Zygote.DISABLE_HIDDEN_API_CHECKS;
4082            }
4083
4084            String invokeWith = null;
4085            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4086                // Debuggable apps may include a wrapper script with their library directory.
4087                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
4088                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4089                try {
4090                    if (new File(wrapperFileName).exists()) {
4091                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4092                    }
4093                } finally {
4094                    StrictMode.setThreadPolicy(oldPolicy);
4095                }
4096            }
4097
4098            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4099            if (requiredAbi == null) {
4100                requiredAbi = Build.SUPPORTED_ABIS[0];
4101            }
4102
4103            String instructionSet = null;
4104            if (app.info.primaryCpuAbi != null) {
4105                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4106            }
4107
4108            app.gids = gids;
4109            app.requiredAbi = requiredAbi;
4110            app.instructionSet = instructionSet;
4111
4112            // the per-user SELinux context must be set
4113            if (TextUtils.isEmpty(app.info.seInfoUser)) {
4114                Slog.wtf(TAG, "SELinux tag not defined",
4115                        new IllegalStateException("SELinux tag not defined for "
4116                        + app.info.packageName + " (uid " + app.uid + ")"));
4117            }
4118            final String seInfo = app.info.seInfo
4119                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
4120            // Start the process.  It will either succeed and return a result containing
4121            // the PID of the new process, or else throw a RuntimeException.
4122            final String entryPoint = "android.app.ActivityThread";
4123
4124            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4125                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4126                    startTime);
4127        } catch (RuntimeException e) {
4128            Slog.e(TAG, "Failure starting process " + app.processName, e);
4129
4130            // Something went very wrong while trying to start this process; one
4131            // common case is when the package is frozen due to an active
4132            // upgrade. To recover, clean up any active bookkeeping related to
4133            // starting this process. (We already invoked this method once when
4134            // the package was initially frozen through KILL_APPLICATION_MSG, so
4135            // it doesn't hurt to use it again.)
4136            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4137                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4138            return false;
4139        }
4140    }
4141
4142    @GuardedBy("this")
4143    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4144            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4145            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4146            long startTime) {
4147        app.pendingStart = true;
4148        app.killedByAm = false;
4149        app.removed = false;
4150        app.killed = false;
4151        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4152        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4153        if (mConstants.FLAG_PROCESS_START_ASYNC) {
4154            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4155                    "Posting procStart msg for " + app.toShortString());
4156            mProcStartHandler.post(() -> {
4157                try {
4158                    synchronized (ActivityManagerService.this) {
4159                        final String reason = isProcStartValidLocked(app, startSeq);
4160                        if (reason != null) {
4161                            Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4162                                    + " don't start process, " + reason);
4163                            app.pendingStart = false;
4164                            return;
4165                        }
4166                        app.usingWrapper = invokeWith != null
4167                                || SystemProperties.get("wrap." + app.processName) != null;
4168                        mPendingStarts.put(startSeq, app);
4169                    }
4170                    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4171                            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4172                            requiredAbi, instructionSet, invokeWith, app.startTime);
4173                    synchronized (ActivityManagerService.this) {
4174                        handleProcessStartedLocked(app, startResult, startSeq);
4175                    }
4176                } catch (RuntimeException e) {
4177                    synchronized (ActivityManagerService.this) {
4178                        Slog.e(TAG, "Failure starting process " + app.processName, e);
4179                        mPendingStarts.remove(startSeq);
4180                        app.pendingStart = false;
4181                        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4182                                false, false, true, false, false,
4183                                UserHandle.getUserId(app.userId), "start failure");
4184                    }
4185                }
4186            });
4187            return true;
4188        } else {
4189            try {
4190                final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4191                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4192                        invokeWith, startTime);
4193                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4194                        startSeq, false);
4195            } catch (RuntimeException e) {
4196                Slog.e(TAG, "Failure starting process " + app.processName, e);
4197                app.pendingStart = false;
4198                forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4199                        false, false, true, false, false,
4200                        UserHandle.getUserId(app.userId), "start failure");
4201            }
4202            return app.pid > 0;
4203        }
4204    }
4205
4206    private ProcessStartResult startProcess(String hostingType, String entryPoint,
4207            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4208            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4209            long startTime) {
4210        try {
4211            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4212                    app.processName);
4213            checkTime(startTime, "startProcess: asking zygote to start proc");
4214            final ProcessStartResult startResult;
4215            if (hostingType.equals("webview_service")) {
4216                startResult = startWebView(entryPoint,
4217                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4218                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4219                        app.info.dataDir, null,
4220                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4221            } else {
4222                startResult = Process.start(entryPoint,
4223                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4224                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4225                        app.info.dataDir, invokeWith,
4226                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4227            }
4228            checkTime(startTime, "startProcess: returned from zygote!");
4229            return startResult;
4230        } finally {
4231            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4232        }
4233    }
4234
4235    @GuardedBy("this")
4236    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4237        StringBuilder sb = null;
4238        if (app.killedByAm) {
4239            if (sb == null) sb = new StringBuilder();
4240            sb.append("killedByAm=true;");
4241        }
4242        if (mProcessNames.get(app.processName, app.uid) != app) {
4243            if (sb == null) sb = new StringBuilder();
4244            sb.append("No entry in mProcessNames;");
4245        }
4246        if (!app.pendingStart) {
4247            if (sb == null) sb = new StringBuilder();
4248            sb.append("pendingStart=false;");
4249        }
4250        if (app.startSeq > expectedStartSeq) {
4251            if (sb == null) sb = new StringBuilder();
4252            sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4253        }
4254        return sb == null ? null : sb.toString();
4255    }
4256
4257    @GuardedBy("this")
4258    private boolean handleProcessStartedLocked(ProcessRecord pending,
4259            ProcessStartResult startResult, long expectedStartSeq) {
4260        // Indicates that this process start has been taken care of.
4261        if (mPendingStarts.get(expectedStartSeq) == null) {
4262            if (pending.pid == startResult.pid) {
4263                pending.usingWrapper = startResult.usingWrapper;
4264                // TODO: Update already existing clients of usingWrapper
4265            }
4266            return false;
4267        }
4268        return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4269                expectedStartSeq, false);
4270    }
4271
4272    @GuardedBy("this")
4273    private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4274            long expectedStartSeq, boolean procAttached) {
4275        mPendingStarts.remove(expectedStartSeq);
4276        final String reason = isProcStartValidLocked(app, expectedStartSeq);
4277        if (reason != null) {
4278            Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4279                    + ", " + reason);
4280            app.pendingStart = false;
4281            Process.killProcessQuiet(pid);
4282            Process.killProcessGroup(app.uid, app.pid);
4283            return false;
4284        }
4285        mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4286        checkTime(app.startTime, "startProcess: done updating battery stats");
4287
4288        EventLog.writeEvent(EventLogTags.AM_PROC_START,
4289                UserHandle.getUserId(app.startUid), pid, app.startUid,
4290                app.processName, app.hostingType,
4291                app.hostingNameStr != null ? app.hostingNameStr : "");
4292
4293        try {
4294            AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4295                    app.seInfo, app.info.sourceDir, pid);
4296        } catch (RemoteException ex) {
4297            // Ignore
4298        }
4299
4300        if (app.persistent) {
4301            Watchdog.getInstance().processStarted(app.processName, pid);
4302        }
4303
4304        checkTime(app.startTime, "startProcess: building log message");
4305        StringBuilder buf = mStringBuilder;
4306        buf.setLength(0);
4307        buf.append("Start proc ");
4308        buf.append(pid);
4309        buf.append(':');
4310        buf.append(app.processName);
4311        buf.append('/');
4312        UserHandle.formatUid(buf, app.startUid);
4313        if (app.isolatedEntryPoint != null) {
4314            buf.append(" [");
4315            buf.append(app.isolatedEntryPoint);
4316            buf.append("]");
4317        }
4318        buf.append(" for ");
4319        buf.append(app.hostingType);
4320        if (app.hostingNameStr != null) {
4321            buf.append(" ");
4322            buf.append(app.hostingNameStr);
4323        }
4324        Slog.i(TAG, buf.toString());
4325        app.setPid(pid);
4326        app.usingWrapper = usingWrapper;
4327        app.pendingStart = false;
4328        checkTime(app.startTime, "startProcess: starting to update pids map");
4329        ProcessRecord oldApp;
4330        synchronized (mPidsSelfLocked) {
4331            oldApp = mPidsSelfLocked.get(pid);
4332        }
4333        // If there is already an app occupying that pid that hasn't been cleaned up
4334        if (oldApp != null && !app.isolated) {
4335            // Clean up anything relating to this pid first
4336            Slog.w(TAG, "Reusing pid " + pid
4337                    + " while app is still mapped to it");
4338            cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4339                    true /*replacingPid*/);
4340        }
4341        synchronized (mPidsSelfLocked) {
4342            this.mPidsSelfLocked.put(pid, app);
4343            if (!procAttached) {
4344                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4345                msg.obj = app;
4346                mHandler.sendMessageDelayed(msg, usingWrapper
4347                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4348            }
4349        }
4350        checkTime(app.startTime, "startProcess: done updating pids map");
4351        return true;
4352    }
4353
4354    void updateUsageStats(ActivityRecord component, boolean resumed) {
4355        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4356                "updateUsageStats: comp=" + component + "res=" + resumed);
4357        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4358        StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4359            component.userId, component.realActivity.getPackageName(),
4360            component.realActivity.getShortClassName(), resumed ?
4361                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_FOREGROUND :
4362                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_BACKGROUND);
4363        if (resumed) {
4364            if (mUsageStatsService != null) {
4365                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4366                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4367
4368            }
4369            synchronized (stats) {
4370                stats.noteActivityResumedLocked(component.app.uid);
4371            }
4372        } else {
4373            if (mUsageStatsService != null) {
4374                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4375                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4376            }
4377            synchronized (stats) {
4378                stats.noteActivityPausedLocked(component.app.uid);
4379            }
4380        }
4381    }
4382
4383    Intent getHomeIntent() {
4384        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4385        intent.setComponent(mTopComponent);
4386        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4387        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4388            intent.addCategory(Intent.CATEGORY_HOME);
4389        }
4390        return intent;
4391    }
4392
4393    boolean startHomeActivityLocked(int userId, String reason) {
4394        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4395                && mTopAction == null) {
4396            // We are running in factory test mode, but unable to find
4397            // the factory test app, so just sit around displaying the
4398            // error message and don't try to start anything.
4399            return false;
4400        }
4401        Intent intent = getHomeIntent();
4402        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4403        if (aInfo != null) {
4404            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4405            // Don't do this if the home app is currently being
4406            // instrumented.
4407            aInfo = new ActivityInfo(aInfo);
4408            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4409            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4410                    aInfo.applicationInfo.uid, true);
4411            if (app == null || app.instr == null) {
4412                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4413                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4414                // For ANR debugging to verify if the user activity is the one that actually
4415                // launched.
4416                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4417                mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4418            }
4419        } else {
4420            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4421        }
4422
4423        return true;
4424    }
4425
4426    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4427        ActivityInfo ai = null;
4428        ComponentName comp = intent.getComponent();
4429        try {
4430            if (comp != null) {
4431                // Factory test.
4432                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4433            } else {
4434                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4435                        intent,
4436                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4437                        flags, userId);
4438
4439                if (info != null) {
4440                    ai = info.activityInfo;
4441                }
4442            }
4443        } catch (RemoteException e) {
4444            // ignore
4445        }
4446
4447        return ai;
4448    }
4449
4450    boolean getCheckedForSetup() {
4451        return mCheckedForSetup;
4452    }
4453
4454    void setCheckedForSetup(boolean checked) {
4455        mCheckedForSetup = checked;
4456    }
4457
4458    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4459        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4460    }
4461
4462    void enforceNotIsolatedCaller(String caller) {
4463        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4464            throw new SecurityException("Isolated process not allowed to call " + caller);
4465        }
4466    }
4467
4468    @Override
4469    public int getFrontActivityScreenCompatMode() {
4470        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4471        synchronized (this) {
4472            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4473        }
4474    }
4475
4476    @Override
4477    public void setFrontActivityScreenCompatMode(int mode) {
4478        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4479                "setFrontActivityScreenCompatMode");
4480        synchronized (this) {
4481            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4482        }
4483    }
4484
4485    @Override
4486    public int getPackageScreenCompatMode(String packageName) {
4487        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4488        synchronized (this) {
4489            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4490        }
4491    }
4492
4493    @Override
4494    public void setPackageScreenCompatMode(String packageName, int mode) {
4495        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4496                "setPackageScreenCompatMode");
4497        synchronized (this) {
4498            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4499        }
4500    }
4501
4502    @Override
4503    public boolean getPackageAskScreenCompat(String packageName) {
4504        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4505        synchronized (this) {
4506            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4507        }
4508    }
4509
4510    @Override
4511    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4512        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4513                "setPackageAskScreenCompat");
4514        synchronized (this) {
4515            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4516        }
4517    }
4518
4519    private boolean hasUsageStatsPermission(String callingPackage) {
4520        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4521                Binder.getCallingUid(), callingPackage);
4522        if (mode == AppOpsManager.MODE_DEFAULT) {
4523            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4524                    == PackageManager.PERMISSION_GRANTED;
4525        }
4526        return mode == AppOpsManager.MODE_ALLOWED;
4527    }
4528
4529    @Override
4530    public int getPackageProcessState(String packageName, String callingPackage) {
4531        if (!hasUsageStatsPermission(callingPackage)) {
4532            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4533                    "getPackageProcessState");
4534        }
4535
4536        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4537        synchronized (this) {
4538            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4539                final ProcessRecord proc = mLruProcesses.get(i);
4540                if (procState > proc.setProcState) {
4541                    if (proc.pkgList.containsKey(packageName) ||
4542                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4543                        procState = proc.setProcState;
4544                    }
4545                }
4546            }
4547        }
4548        return procState;
4549    }
4550
4551    @Override
4552    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4553            throws RemoteException {
4554        synchronized (this) {
4555            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4556            if (app == null) {
4557                throw new IllegalArgumentException("Unknown process: " + process);
4558            }
4559            if (app.thread == null) {
4560                throw new IllegalArgumentException("Process has no app thread");
4561            }
4562            if (app.trimMemoryLevel >= level) {
4563                throw new IllegalArgumentException(
4564                        "Unable to set a higher trim level than current level");
4565            }
4566            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4567                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4568                throw new IllegalArgumentException("Unable to set a background trim level "
4569                    + "on a foreground process");
4570            }
4571            app.thread.scheduleTrimMemory(level);
4572            app.trimMemoryLevel = level;
4573            return true;
4574        }
4575    }
4576
4577    private void dispatchProcessesChanged() {
4578        int N;
4579        synchronized (this) {
4580            N = mPendingProcessChanges.size();
4581            if (mActiveProcessChanges.length < N) {
4582                mActiveProcessChanges = new ProcessChangeItem[N];
4583            }
4584            mPendingProcessChanges.toArray(mActiveProcessChanges);
4585            mPendingProcessChanges.clear();
4586            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4587                    "*** Delivering " + N + " process changes");
4588        }
4589
4590        int i = mProcessObservers.beginBroadcast();
4591        while (i > 0) {
4592            i--;
4593            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4594            if (observer != null) {
4595                try {
4596                    for (int j=0; j<N; j++) {
4597                        ProcessChangeItem item = mActiveProcessChanges[j];
4598                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4599                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4600                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4601                                    + item.uid + ": " + item.foregroundActivities);
4602                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4603                                    item.foregroundActivities);
4604                        }
4605                    }
4606                } catch (RemoteException e) {
4607                }
4608            }
4609        }
4610        mProcessObservers.finishBroadcast();
4611
4612        synchronized (this) {
4613            for (int j=0; j<N; j++) {
4614                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4615            }
4616        }
4617    }
4618
4619    private void dispatchProcessDied(int pid, int uid) {
4620        int i = mProcessObservers.beginBroadcast();
4621        while (i > 0) {
4622            i--;
4623            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4624            if (observer != null) {
4625                try {
4626                    observer.onProcessDied(pid, uid);
4627                } catch (RemoteException e) {
4628                }
4629            }
4630        }
4631        mProcessObservers.finishBroadcast();
4632    }
4633
4634    @VisibleForTesting
4635    void dispatchUidsChanged() {
4636        int N;
4637        synchronized (this) {
4638            N = mPendingUidChanges.size();
4639            if (mActiveUidChanges.length < N) {
4640                mActiveUidChanges = new UidRecord.ChangeItem[N];
4641            }
4642            for (int i=0; i<N; i++) {
4643                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4644                mActiveUidChanges[i] = change;
4645                if (change.uidRecord != null) {
4646                    change.uidRecord.pendingChange = null;
4647                    change.uidRecord = null;
4648                }
4649            }
4650            mPendingUidChanges.clear();
4651            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4652                    "*** Delivering " + N + " uid changes");
4653        }
4654
4655        int i = mUidObservers.beginBroadcast();
4656        while (i > 0) {
4657            i--;
4658            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4659                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4660        }
4661        mUidObservers.finishBroadcast();
4662
4663        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4664            for (int j = 0; j < N; ++j) {
4665                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4666                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4667                    mValidateUids.remove(item.uid);
4668                } else {
4669                    UidRecord validateUid = mValidateUids.get(item.uid);
4670                    if (validateUid == null) {
4671                        validateUid = new UidRecord(item.uid);
4672                        mValidateUids.put(item.uid, validateUid);
4673                    }
4674                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4675                        validateUid.idle = true;
4676                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4677                        validateUid.idle = false;
4678                    }
4679                    validateUid.curProcState = validateUid.setProcState = item.processState;
4680                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4681                }
4682            }
4683        }
4684
4685        synchronized (this) {
4686            for (int j = 0; j < N; j++) {
4687                mAvailUidChanges.add(mActiveUidChanges[j]);
4688            }
4689        }
4690    }
4691
4692    private void dispatchUidsChangedForObserver(IUidObserver observer,
4693            UidObserverRegistration reg, int changesSize) {
4694        if (observer == null) {
4695            return;
4696        }
4697        try {
4698            for (int j = 0; j < changesSize; j++) {
4699                UidRecord.ChangeItem item = mActiveUidChanges[j];
4700                final int change = item.change;
4701                if (change == UidRecord.CHANGE_PROCSTATE &&
4702                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4703                    // No-op common case: no significant change, the observer is not
4704                    // interested in all proc state changes.
4705                    continue;
4706                }
4707                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4708                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4709                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4710                                "UID idle uid=" + item.uid);
4711                        observer.onUidIdle(item.uid, item.ephemeral);
4712                    }
4713                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4714                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4715                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4716                                "UID active uid=" + item.uid);
4717                        observer.onUidActive(item.uid);
4718                    }
4719                }
4720                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4721                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4722                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4723                                "UID cached uid=" + item.uid);
4724                        observer.onUidCachedChanged(item.uid, true);
4725                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4726                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4727                                "UID active uid=" + item.uid);
4728                        observer.onUidCachedChanged(item.uid, false);
4729                    }
4730                }
4731                if ((change & UidRecord.CHANGE_GONE) != 0) {
4732                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4733                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4734                                "UID gone uid=" + item.uid);
4735                        observer.onUidGone(item.uid, item.ephemeral);
4736                    }
4737                    if (reg.lastProcStates != null) {
4738                        reg.lastProcStates.delete(item.uid);
4739                    }
4740                } else {
4741                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4742                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4743                                "UID CHANGED uid=" + item.uid
4744                                        + ": " + item.processState);
4745                        boolean doReport = true;
4746                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4747                            final int lastState = reg.lastProcStates.get(item.uid,
4748                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4749                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4750                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4751                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4752                                doReport = lastAboveCut != newAboveCut;
4753                            } else {
4754                                doReport = item.processState
4755                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4756                            }
4757                        }
4758                        if (doReport) {
4759                            if (reg.lastProcStates != null) {
4760                                reg.lastProcStates.put(item.uid, item.processState);
4761                            }
4762                            observer.onUidStateChanged(item.uid, item.processState,
4763                                    item.procStateSeq);
4764                        }
4765                    }
4766                }
4767            }
4768        } catch (RemoteException e) {
4769        }
4770    }
4771
4772    void dispatchOomAdjObserver(String msg) {
4773        OomAdjObserver observer;
4774        synchronized (this) {
4775            observer = mCurOomAdjObserver;
4776        }
4777
4778        if (observer != null) {
4779            observer.onOomAdjMessage(msg);
4780        }
4781    }
4782
4783    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4784        synchronized (this) {
4785            mCurOomAdjUid = uid;
4786            mCurOomAdjObserver = observer;
4787        }
4788    }
4789
4790    void clearOomAdjObserver() {
4791        synchronized (this) {
4792            mCurOomAdjUid = -1;
4793            mCurOomAdjObserver = null;
4794        }
4795    }
4796
4797    void reportOomAdjMessageLocked(String tag, String msg) {
4798        Slog.d(tag, msg);
4799        if (mCurOomAdjObserver != null) {
4800            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4801        }
4802    }
4803
4804    @Override
4805    public final int startActivity(IApplicationThread caller, String callingPackage,
4806            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4807            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4808        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4809                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4810                UserHandle.getCallingUserId());
4811    }
4812
4813    @Override
4814    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4815            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4816            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4817        enforceNotIsolatedCaller("startActivity");
4818        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4819                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4820        // TODO: Switch to user app stacks here.
4821        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
4822                .setCaller(caller)
4823                .setCallingPackage(callingPackage)
4824                .setResolvedType(resolvedType)
4825                .setResultTo(resultTo)
4826                .setResultWho(resultWho)
4827                .setRequestCode(requestCode)
4828                .setStartFlags(startFlags)
4829                .setProfilerInfo(profilerInfo)
4830                .setActivityOptions(bOptions)
4831                .setMayWait(userId)
4832                .execute();
4833
4834    }
4835
4836    @Override
4837    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4838            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4839            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4840            int userId) {
4841
4842        // This is very dangerous -- it allows you to perform a start activity (including
4843        // permission grants) as any app that may launch one of your own activities.  So
4844        // we will only allow this to be done from activities that are part of the core framework,
4845        // and then only when they are running as the system.
4846        final ActivityRecord sourceRecord;
4847        final int targetUid;
4848        final String targetPackage;
4849        synchronized (this) {
4850            if (resultTo == null) {
4851                throw new SecurityException("Must be called from an activity");
4852            }
4853            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4854            if (sourceRecord == null) {
4855                throw new SecurityException("Called with bad activity token: " + resultTo);
4856            }
4857            if (!sourceRecord.info.packageName.equals("android")) {
4858                throw new SecurityException(
4859                        "Must be called from an activity that is declared in the android package");
4860            }
4861            if (sourceRecord.app == null) {
4862                throw new SecurityException("Called without a process attached to activity");
4863            }
4864            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4865                // This is still okay, as long as this activity is running under the
4866                // uid of the original calling activity.
4867                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4868                    throw new SecurityException(
4869                            "Calling activity in uid " + sourceRecord.app.uid
4870                                    + " must be system uid or original calling uid "
4871                                    + sourceRecord.launchedFromUid);
4872                }
4873            }
4874            if (ignoreTargetSecurity) {
4875                if (intent.getComponent() == null) {
4876                    throw new SecurityException(
4877                            "Component must be specified with ignoreTargetSecurity");
4878                }
4879                if (intent.getSelector() != null) {
4880                    throw new SecurityException(
4881                            "Selector not allowed with ignoreTargetSecurity");
4882                }
4883            }
4884            targetUid = sourceRecord.launchedFromUid;
4885            targetPackage = sourceRecord.launchedFromPackage;
4886        }
4887
4888        if (userId == UserHandle.USER_NULL) {
4889            userId = UserHandle.getUserId(sourceRecord.app.uid);
4890        }
4891
4892        // TODO: Switch to user app stacks here.
4893        try {
4894            return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
4895                    .setCallingUid(targetUid)
4896                    .setCallingPackage(targetPackage)
4897                    .setResolvedType(resolvedType)
4898                    .setResultTo(resultTo)
4899                    .setResultWho(resultWho)
4900                    .setRequestCode(requestCode)
4901                    .setStartFlags(startFlags)
4902                    .setActivityOptions(bOptions)
4903                    .setMayWait(userId)
4904                    .setIgnoreTargetSecurity(ignoreTargetSecurity)
4905                    .execute();
4906        } catch (SecurityException e) {
4907            // XXX need to figure out how to propagate to original app.
4908            // A SecurityException here is generally actually a fault of the original
4909            // calling activity (such as a fairly granting permissions), so propagate it
4910            // back to them.
4911            /*
4912            StringBuilder msg = new StringBuilder();
4913            msg.append("While launching");
4914            msg.append(intent.toString());
4915            msg.append(": ");
4916            msg.append(e.getMessage());
4917            */
4918            throw e;
4919        }
4920    }
4921
4922    @Override
4923    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4924            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4925            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4926        enforceNotIsolatedCaller("startActivityAndWait");
4927        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4928                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4929        WaitResult res = new WaitResult();
4930        // TODO: Switch to user app stacks here.
4931        mActivityStartController.obtainStarter(intent, "startActivityAndWait")
4932                .setCaller(caller)
4933                .setCallingPackage(callingPackage)
4934                .setResolvedType(resolvedType)
4935                .setResultTo(resultTo)
4936                .setResultWho(resultWho)
4937                .setRequestCode(requestCode)
4938                .setStartFlags(startFlags)
4939                .setActivityOptions(bOptions)
4940                .setMayWait(userId)
4941                .setProfilerInfo(profilerInfo)
4942                .setWaitResult(res)
4943                .execute();
4944        return res;
4945    }
4946
4947    @Override
4948    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4949            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4950            int startFlags, Configuration config, Bundle bOptions, int userId) {
4951        enforceNotIsolatedCaller("startActivityWithConfig");
4952        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4953                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4954        // TODO: Switch to user app stacks here.
4955        return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
4956                .setCaller(caller)
4957                .setCallingPackage(callingPackage)
4958                .setResolvedType(resolvedType)
4959                .setResultTo(resultTo)
4960                .setResultWho(resultWho)
4961                .setRequestCode(requestCode)
4962                .setStartFlags(startFlags)
4963                .setGlobalConfiguration(config)
4964                .setActivityOptions(bOptions)
4965                .setMayWait(userId)
4966                .execute();
4967    }
4968
4969    @Override
4970    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4971            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4972            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4973            throws TransactionTooLargeException {
4974        enforceNotIsolatedCaller("startActivityIntentSender");
4975        // Refuse possible leaked file descriptors
4976        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4977            throw new IllegalArgumentException("File descriptors passed in Intent");
4978        }
4979
4980        if (!(target instanceof PendingIntentRecord)) {
4981            throw new IllegalArgumentException("Bad PendingIntent object");
4982        }
4983
4984        PendingIntentRecord pir = (PendingIntentRecord)target;
4985
4986        synchronized (this) {
4987            // If this is coming from the currently resumed activity, it is
4988            // effectively saying that app switches are allowed at this point.
4989            final ActivityStack stack = getFocusedStack();
4990            if (stack.mResumedActivity != null &&
4991                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4992                mAppSwitchesAllowedTime = 0;
4993            }
4994        }
4995        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4996                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4997        return ret;
4998    }
4999
5000    @Override
5001    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
5002            Intent intent, String resolvedType, IVoiceInteractionSession session,
5003            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
5004            Bundle bOptions, int userId) {
5005        enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
5006        if (session == null || interactor == null) {
5007            throw new NullPointerException("null session or interactor");
5008        }
5009        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5010                ALLOW_FULL_ONLY, "startVoiceActivity", null);
5011        // TODO: Switch to user app stacks here.
5012        return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
5013                .setCallingUid(callingUid)
5014                .setCallingPackage(callingPackage)
5015                .setResolvedType(resolvedType)
5016                .setVoiceSession(session)
5017                .setVoiceInteractor(interactor)
5018                .setStartFlags(startFlags)
5019                .setProfilerInfo(profilerInfo)
5020                .setActivityOptions(bOptions)
5021                .setMayWait(userId)
5022                .execute();
5023    }
5024
5025    @Override
5026    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
5027            Intent intent, String resolvedType, Bundle bOptions, int userId) {
5028        enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
5029        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5030                ALLOW_FULL_ONLY, "startAssistantActivity", null);
5031
5032        return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
5033                .setCallingUid(callingUid)
5034                .setCallingPackage(callingPackage)
5035                .setResolvedType(resolvedType)
5036                .setActivityOptions(bOptions)
5037                .setMayWait(userId)
5038                .execute();
5039    }
5040
5041    @Override
5042    public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
5043                IRecentsAnimationRunner recentsAnimationRunner) {
5044        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
5045        final long origId = Binder.clearCallingIdentity();
5046        try {
5047            synchronized (this) {
5048                final int recentsUid = mRecentTasks.getRecentsComponentUid();
5049                final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
5050                final String recentsPackage = recentsComponent.getPackageName();
5051
5052                // If provided, kick off the request for the assist data in the background before
5053                // starting the activity
5054                if (assistDataReceiver != null) {
5055                    final AppOpsManager appOpsManager = (AppOpsManager)
5056                            mContext.getSystemService(Context.APP_OPS_SERVICE);
5057                    final AssistDataReceiverProxy proxy = new AssistDataReceiverProxy(
5058                            assistDataReceiver, recentsPackage);
5059                    final AssistDataRequester requester = new AssistDataRequester(mContext, this,
5060                            mWindowManager, appOpsManager, proxy, this,
5061                            OP_ASSIST_STRUCTURE, OP_NONE);
5062                    requester.requestAssistData(mStackSupervisor.getTopVisibleActivities(),
5063                            true /* fetchData */, false /* fetchScreenshots */,
5064                            true /* allowFetchData */, false /* alloweFetchScreenshots */,
5065                            recentsUid, recentsPackage);
5066                }
5067
5068                // Start a new recents animation
5069                final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
5070                        mActivityStartController, mWindowManager, mUserController);
5071                anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
5072                        recentsUid);
5073            }
5074        } finally {
5075            Binder.restoreCallingIdentity(origId);
5076        }
5077    }
5078
5079    @Override
5080    public void cancelRecentsAnimation() {
5081        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
5082        final long origId = Binder.clearCallingIdentity();
5083        try {
5084            synchronized (this) {
5085                mWindowManager.cancelRecentsAnimation();
5086            }
5087        } finally {
5088            Binder.restoreCallingIdentity(origId);
5089        }
5090    }
5091
5092    @Override
5093    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
5094            throws RemoteException {
5095        Slog.i(TAG, "Activity tried to startVoiceInteraction");
5096        synchronized (this) {
5097            ActivityRecord activity = getFocusedStack().getTopActivity();
5098            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
5099                throw new SecurityException("Only focused activity can call startVoiceInteraction");
5100            }
5101            if (mRunningVoice != null || activity.getTask().voiceSession != null
5102                    || activity.voiceSession != null) {
5103                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
5104                return;
5105            }
5106            if (activity.pendingVoiceInteractionStart) {
5107                Slog.w(TAG, "Pending start of voice interaction already.");
5108                return;
5109            }
5110            activity.pendingVoiceInteractionStart = true;
5111        }
5112        LocalServices.getService(VoiceInteractionManagerInternal.class)
5113                .startLocalVoiceInteraction(callingActivity, options);
5114    }
5115
5116    @Override
5117    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5118        LocalServices.getService(VoiceInteractionManagerInternal.class)
5119                .stopLocalVoiceInteraction(callingActivity);
5120    }
5121
5122    @Override
5123    public boolean supportsLocalVoiceInteraction() throws RemoteException {
5124        return LocalServices.getService(VoiceInteractionManagerInternal.class)
5125                .supportsLocalVoiceInteraction();
5126    }
5127
5128    void onLocalVoiceInteractionStartedLocked(IBinder activity,
5129            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5130        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
5131        if (activityToCallback == null) return;
5132        activityToCallback.setVoiceSessionLocked(voiceSession);
5133
5134        // Inform the activity
5135        try {
5136            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5137                    voiceInteractor);
5138            long token = Binder.clearCallingIdentity();
5139            try {
5140                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5141            } finally {
5142                Binder.restoreCallingIdentity(token);
5143            }
5144            // TODO: VI Should we cache the activity so that it's easier to find later
5145            // rather than scan through all the stacks and activities?
5146        } catch (RemoteException re) {
5147            activityToCallback.clearVoiceSessionLocked();
5148            // TODO: VI Should this terminate the voice session?
5149        }
5150    }
5151
5152    @Override
5153    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5154        synchronized (this) {
5155            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5156                if (keepAwake) {
5157                    mVoiceWakeLock.acquire();
5158                } else {
5159                    mVoiceWakeLock.release();
5160                }
5161            }
5162        }
5163    }
5164
5165    @Override
5166    public boolean startNextMatchingActivity(IBinder callingActivity,
5167            Intent intent, Bundle bOptions) {
5168        // Refuse possible leaked file descriptors
5169        if (intent != null && intent.hasFileDescriptors() == true) {
5170            throw new IllegalArgumentException("File descriptors passed in Intent");
5171        }
5172        SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5173
5174        synchronized (this) {
5175            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5176            if (r == null) {
5177                SafeActivityOptions.abort(options);
5178                return false;
5179            }
5180            if (r.app == null || r.app.thread == null) {
5181                // The caller is not running...  d'oh!
5182                SafeActivityOptions.abort(options);
5183                return false;
5184            }
5185            intent = new Intent(intent);
5186            // The caller is not allowed to change the data.
5187            intent.setDataAndType(r.intent.getData(), r.intent.getType());
5188            // And we are resetting to find the next component...
5189            intent.setComponent(null);
5190
5191            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5192
5193            ActivityInfo aInfo = null;
5194            try {
5195                List<ResolveInfo> resolves =
5196                    AppGlobals.getPackageManager().queryIntentActivities(
5197                            intent, r.resolvedType,
5198                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5199                            UserHandle.getCallingUserId()).getList();
5200
5201                // Look for the original activity in the list...
5202                final int N = resolves != null ? resolves.size() : 0;
5203                for (int i=0; i<N; i++) {
5204                    ResolveInfo rInfo = resolves.get(i);
5205                    if (rInfo.activityInfo.packageName.equals(r.packageName)
5206                            && rInfo.activityInfo.name.equals(r.info.name)) {
5207                        // We found the current one...  the next matching is
5208                        // after it.
5209                        i++;
5210                        if (i<N) {
5211                            aInfo = resolves.get(i).activityInfo;
5212                        }
5213                        if (debug) {
5214                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
5215                                    + "/" + r.info.name);
5216                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5217                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
5218                        }
5219                        break;
5220                    }
5221                }
5222            } catch (RemoteException e) {
5223            }
5224
5225            if (aInfo == null) {
5226                // Nobody who is next!
5227                SafeActivityOptions.abort(options);
5228                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5229                return false;
5230            }
5231
5232            intent.setComponent(new ComponentName(
5233                    aInfo.applicationInfo.packageName, aInfo.name));
5234            intent.setFlags(intent.getFlags()&~(
5235                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5236                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
5237                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5238                    FLAG_ACTIVITY_NEW_TASK));
5239
5240            // Okay now we need to start the new activity, replacing the
5241            // currently running activity.  This is a little tricky because
5242            // we want to start the new one as if the current one is finished,
5243            // but not finish the current one first so that there is no flicker.
5244            // And thus...
5245            final boolean wasFinishing = r.finishing;
5246            r.finishing = true;
5247
5248            // Propagate reply information over to the new activity.
5249            final ActivityRecord resultTo = r.resultTo;
5250            final String resultWho = r.resultWho;
5251            final int requestCode = r.requestCode;
5252            r.resultTo = null;
5253            if (resultTo != null) {
5254                resultTo.removeResultsLocked(r, resultWho, requestCode);
5255            }
5256
5257            final long origId = Binder.clearCallingIdentity();
5258            // TODO(b/64750076): Check if calling pid should really be -1.
5259            final int res = mActivityStartController
5260                    .obtainStarter(intent, "startNextMatchingActivity")
5261                    .setCaller(r.app.thread)
5262                    .setResolvedType(r.resolvedType)
5263                    .setActivityInfo(aInfo)
5264                    .setResultTo(resultTo != null ? resultTo.appToken : null)
5265                    .setResultWho(resultWho)
5266                    .setRequestCode(requestCode)
5267                    .setCallingPid(-1)
5268                    .setCallingUid(r.launchedFromUid)
5269                    .setCallingPackage(r.launchedFromPackage)
5270                    .setRealCallingPid(-1)
5271                    .setRealCallingUid(r.launchedFromUid)
5272                    .setActivityOptions(options)
5273                    .execute();
5274            Binder.restoreCallingIdentity(origId);
5275
5276            r.finishing = wasFinishing;
5277            if (res != ActivityManager.START_SUCCESS) {
5278                return false;
5279            }
5280            return true;
5281        }
5282    }
5283
5284    @Override
5285    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5286        enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5287                "startActivityFromRecents()");
5288
5289        final int callingPid = Binder.getCallingPid();
5290        final int callingUid = Binder.getCallingUid();
5291        final long origId = Binder.clearCallingIdentity();
5292        try {
5293            synchronized (this) {
5294                return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5295                        SafeActivityOptions.fromBundle(bOptions));
5296            }
5297        } finally {
5298            Binder.restoreCallingIdentity(origId);
5299        }
5300    }
5301
5302    @Override
5303    public final int startActivities(IApplicationThread caller, String callingPackage,
5304            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5305            int userId) {
5306        final String reason = "startActivities";
5307        enforceNotIsolatedCaller(reason);
5308        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5309                userId, false, ALLOW_FULL_ONLY, reason, null);
5310        // TODO: Switch to user app stacks here.
5311        int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
5312                intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
5313                reason);
5314        return ret;
5315    }
5316
5317    @Override
5318    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5319        synchronized (this) {
5320            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5321            if (r == null) {
5322                return;
5323            }
5324            r.reportFullyDrawnLocked(restoredFromBundle);
5325        }
5326    }
5327
5328    @Override
5329    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5330        synchronized (this) {
5331            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5332            if (r == null) {
5333                return;
5334            }
5335            final long origId = Binder.clearCallingIdentity();
5336            try {
5337                r.setRequestedOrientation(requestedOrientation);
5338            } finally {
5339                Binder.restoreCallingIdentity(origId);
5340            }
5341        }
5342    }
5343
5344    @Override
5345    public int getRequestedOrientation(IBinder token) {
5346        synchronized (this) {
5347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5348            if (r == null) {
5349                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5350            }
5351            return r.getRequestedOrientation();
5352        }
5353    }
5354
5355    @Override
5356    public final void requestActivityRelaunch(IBinder token) {
5357        synchronized(this) {
5358            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5359            if (r == null) {
5360                return;
5361            }
5362            final long origId = Binder.clearCallingIdentity();
5363            try {
5364                r.forceNewConfig = true;
5365                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5366                        true /* preserveWindow */);
5367            } finally {
5368                Binder.restoreCallingIdentity(origId);
5369            }
5370        }
5371    }
5372
5373    /**
5374     * This is the internal entry point for handling Activity.finish().
5375     *
5376     * @param token The Binder token referencing the Activity we want to finish.
5377     * @param resultCode Result code, if any, from this Activity.
5378     * @param resultData Result data (Intent), if any, from this Activity.
5379     * @param finishTask Whether to finish the task associated with this Activity.
5380     *
5381     * @return Returns true if the activity successfully finished, or false if it is still running.
5382     */
5383    @Override
5384    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5385            int finishTask) {
5386        // Refuse possible leaked file descriptors
5387        if (resultData != null && resultData.hasFileDescriptors() == true) {
5388            throw new IllegalArgumentException("File descriptors passed in Intent");
5389        }
5390
5391        synchronized(this) {
5392            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5393            if (r == null) {
5394                return true;
5395            }
5396            // Keep track of the root activity of the task before we finish it
5397            TaskRecord tr = r.getTask();
5398            ActivityRecord rootR = tr.getRootActivity();
5399            if (rootR == null) {
5400                Slog.w(TAG, "Finishing task with all activities already finished");
5401            }
5402            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5403            // finish.
5404            if (mLockTaskController.activityBlockedFromFinish(r)) {
5405                return false;
5406            }
5407
5408            if (mController != null) {
5409                // Find the first activity that is not finishing.
5410                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5411                if (next != null) {
5412                    // ask watcher if this is allowed
5413                    boolean resumeOK = true;
5414                    try {
5415                        resumeOK = mController.activityResuming(next.packageName);
5416                    } catch (RemoteException e) {
5417                        mController = null;
5418                        Watchdog.getInstance().setActivityController(null);
5419                    }
5420
5421                    if (!resumeOK) {
5422                        Slog.i(TAG, "Not finishing activity because controller resumed");
5423                        return false;
5424                    }
5425                }
5426            }
5427            final long origId = Binder.clearCallingIdentity();
5428            try {
5429                boolean res;
5430                final boolean finishWithRootActivity =
5431                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5432                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5433                        || (finishWithRootActivity && r == rootR)) {
5434                    // If requested, remove the task that is associated to this activity only if it
5435                    // was the root activity in the task. The result code and data is ignored
5436                    // because we don't support returning them across task boundaries. Also, to
5437                    // keep backwards compatibility we remove the task from recents when finishing
5438                    // task with root activity.
5439                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5440                            finishWithRootActivity, "finish-activity");
5441                    if (!res) {
5442                        Slog.i(TAG, "Removing task failed to finish activity");
5443                    }
5444                } else {
5445                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5446                            resultData, "app-request", true);
5447                    if (!res) {
5448                        Slog.i(TAG, "Failed to finish by app-request");
5449                    }
5450                }
5451                return res;
5452            } finally {
5453                Binder.restoreCallingIdentity(origId);
5454            }
5455        }
5456    }
5457
5458    @Override
5459    public final void finishHeavyWeightApp() {
5460        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5461                != PackageManager.PERMISSION_GRANTED) {
5462            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5463                    + Binder.getCallingPid()
5464                    + ", uid=" + Binder.getCallingUid()
5465                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5466            Slog.w(TAG, msg);
5467            throw new SecurityException(msg);
5468        }
5469
5470        synchronized(this) {
5471            final ProcessRecord proc = mHeavyWeightProcess;
5472            if (proc == null) {
5473                return;
5474            }
5475
5476            ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5477            for (int i = 0; i < activities.size(); i++) {
5478                ActivityRecord r = activities.get(i);
5479                if (!r.finishing && r.isInStackLocked()) {
5480                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5481                            null, "finish-heavy", true);
5482                }
5483            }
5484
5485            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5486                    proc.userId, 0));
5487            mHeavyWeightProcess = null;
5488        }
5489    }
5490
5491    @Override
5492    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5493            String message) {
5494        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5495                != PackageManager.PERMISSION_GRANTED) {
5496            String msg = "Permission Denial: crashApplication() from pid="
5497                    + Binder.getCallingPid()
5498                    + ", uid=" + Binder.getCallingUid()
5499                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5500            Slog.w(TAG, msg);
5501            throw new SecurityException(msg);
5502        }
5503
5504        synchronized(this) {
5505            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5506        }
5507    }
5508
5509    @Override
5510    public final void finishSubActivity(IBinder token, String resultWho,
5511            int requestCode) {
5512        synchronized(this) {
5513            final long origId = Binder.clearCallingIdentity();
5514            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5515            if (r != null) {
5516                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5517            }
5518            Binder.restoreCallingIdentity(origId);
5519        }
5520    }
5521
5522    @Override
5523    public boolean finishActivityAffinity(IBinder token) {
5524        synchronized(this) {
5525            final long origId = Binder.clearCallingIdentity();
5526            try {
5527                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5528                if (r == null) {
5529                    return false;
5530                }
5531
5532                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5533                // can finish.
5534                final TaskRecord task = r.getTask();
5535                if (mLockTaskController.activityBlockedFromFinish(r)) {
5536                    return false;
5537                }
5538                return task.getStack().finishActivityAffinityLocked(r);
5539            } finally {
5540                Binder.restoreCallingIdentity(origId);
5541            }
5542        }
5543    }
5544
5545    @Override
5546    public void finishVoiceTask(IVoiceInteractionSession session) {
5547        synchronized (this) {
5548            final long origId = Binder.clearCallingIdentity();
5549            try {
5550                // TODO: VI Consider treating local voice interactions and voice tasks
5551                // differently here
5552                mStackSupervisor.finishVoiceTask(session);
5553            } finally {
5554                Binder.restoreCallingIdentity(origId);
5555            }
5556        }
5557
5558    }
5559
5560    @Override
5561    public boolean releaseActivityInstance(IBinder token) {
5562        synchronized(this) {
5563            final long origId = Binder.clearCallingIdentity();
5564            try {
5565                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5566                if (r == null) {
5567                    return false;
5568                }
5569                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5570            } finally {
5571                Binder.restoreCallingIdentity(origId);
5572            }
5573        }
5574    }
5575
5576    @Override
5577    public void releaseSomeActivities(IApplicationThread appInt) {
5578        synchronized(this) {
5579            final long origId = Binder.clearCallingIdentity();
5580            try {
5581                ProcessRecord app = getRecordForAppLocked(appInt);
5582                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5583            } finally {
5584                Binder.restoreCallingIdentity(origId);
5585            }
5586        }
5587    }
5588
5589    @Override
5590    public boolean willActivityBeVisible(IBinder token) {
5591        synchronized(this) {
5592            ActivityStack stack = ActivityRecord.getStackLocked(token);
5593            if (stack != null) {
5594                return stack.willActivityBeVisibleLocked(token);
5595            }
5596            return false;
5597        }
5598    }
5599
5600    @Override
5601    public void overridePendingTransition(IBinder token, String packageName,
5602            int enterAnim, int exitAnim) {
5603        synchronized(this) {
5604            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5605            if (self == null) {
5606                return;
5607            }
5608
5609            final long origId = Binder.clearCallingIdentity();
5610
5611            if (self.state == ActivityState.RESUMED
5612                    || self.state == ActivityState.PAUSING) {
5613                mWindowManager.overridePendingAppTransition(packageName,
5614                        enterAnim, exitAnim, null);
5615            }
5616
5617            Binder.restoreCallingIdentity(origId);
5618        }
5619    }
5620
5621    /**
5622     * Main function for removing an existing process from the activity manager
5623     * as a result of that process going away.  Clears out all connections
5624     * to the process.
5625     */
5626    private final void handleAppDiedLocked(ProcessRecord app,
5627            boolean restarting, boolean allowRestart) {
5628        int pid = app.pid;
5629        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5630                false /*replacingPid*/);
5631        if (!kept && !restarting) {
5632            removeLruProcessLocked(app);
5633            if (pid > 0) {
5634                ProcessList.remove(pid);
5635            }
5636        }
5637
5638        if (mProfileProc == app) {
5639            clearProfilerLocked();
5640        }
5641
5642        // Remove this application's activities from active lists.
5643        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5644
5645        app.clearRecentTasks();
5646
5647        app.activities.clear();
5648
5649        if (app.instr != null) {
5650            Slog.w(TAG, "Crash of app " + app.processName
5651                  + " running instrumentation " + app.instr.mClass);
5652            Bundle info = new Bundle();
5653            info.putString("shortMsg", "Process crashed.");
5654            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5655        }
5656
5657        mWindowManager.deferSurfaceLayout();
5658        try {
5659            if (!restarting && hasVisibleActivities
5660                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5661                // If there was nothing to resume, and we are not already restarting this process, but
5662                // there is a visible activity that is hosted by the process...  then make sure all
5663                // visible activities are running, taking care of restarting this process.
5664                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5665            }
5666        } finally {
5667            mWindowManager.continueSurfaceLayout();
5668        }
5669    }
5670
5671    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5672        final IBinder threadBinder = thread.asBinder();
5673        // Find the application record.
5674        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5675            final ProcessRecord rec = mLruProcesses.get(i);
5676            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5677                return i;
5678            }
5679        }
5680        return -1;
5681    }
5682
5683    ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5684        if (thread == null) {
5685            return null;
5686        }
5687
5688        int appIndex = getLRURecordIndexForAppLocked(thread);
5689        if (appIndex >= 0) {
5690            return mLruProcesses.get(appIndex);
5691        }
5692
5693        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5694        // double-check that.
5695        final IBinder threadBinder = thread.asBinder();
5696        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5697        for (int i = pmap.size()-1; i >= 0; i--) {
5698            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5699            for (int j = procs.size()-1; j >= 0; j--) {
5700                final ProcessRecord proc = procs.valueAt(j);
5701                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5702                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5703                            + proc);
5704                    return proc;
5705                }
5706            }
5707        }
5708
5709        return null;
5710    }
5711
5712    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5713        // If there are no longer any background processes running,
5714        // and the app that died was not running instrumentation,
5715        // then tell everyone we are now low on memory.
5716        boolean haveBg = false;
5717        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5718            ProcessRecord rec = mLruProcesses.get(i);
5719            if (rec.thread != null
5720                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5721                haveBg = true;
5722                break;
5723            }
5724        }
5725
5726        if (!haveBg) {
5727            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5728            if (doReport) {
5729                long now = SystemClock.uptimeMillis();
5730                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5731                    doReport = false;
5732                } else {
5733                    mLastMemUsageReportTime = now;
5734                }
5735            }
5736            final ArrayList<ProcessMemInfo> memInfos
5737                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5738            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5739            long now = SystemClock.uptimeMillis();
5740            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5741                ProcessRecord rec = mLruProcesses.get(i);
5742                if (rec == dyingProc || rec.thread == null) {
5743                    continue;
5744                }
5745                if (doReport) {
5746                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5747                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5748                }
5749                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5750                    // The low memory report is overriding any current
5751                    // state for a GC request.  Make sure to do
5752                    // heavy/important/visible/foreground processes first.
5753                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5754                        rec.lastRequestedGc = 0;
5755                    } else {
5756                        rec.lastRequestedGc = rec.lastLowMemory;
5757                    }
5758                    rec.reportLowMemory = true;
5759                    rec.lastLowMemory = now;
5760                    mProcessesToGc.remove(rec);
5761                    addProcessToGcListLocked(rec);
5762                }
5763            }
5764            if (doReport) {
5765                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5766                mHandler.sendMessage(msg);
5767            }
5768            scheduleAppGcsLocked();
5769        }
5770    }
5771
5772    final void appDiedLocked(ProcessRecord app) {
5773       appDiedLocked(app, app.pid, app.thread, false);
5774    }
5775
5776    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5777            boolean fromBinderDied) {
5778        // First check if this ProcessRecord is actually active for the pid.
5779        synchronized (mPidsSelfLocked) {
5780            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5781            if (curProc != app) {
5782                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5783                return;
5784            }
5785        }
5786
5787        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5788        synchronized (stats) {
5789            stats.noteProcessDiedLocked(app.info.uid, pid);
5790        }
5791
5792        if (!app.killed) {
5793            if (!fromBinderDied) {
5794                killProcessQuiet(pid);
5795            }
5796            killProcessGroup(app.uid, pid);
5797            app.killed = true;
5798        }
5799
5800        // Clean up already done if the process has been re-started.
5801        if (app.pid == pid && app.thread != null &&
5802                app.thread.asBinder() == thread.asBinder()) {
5803            boolean doLowMem = app.instr == null;
5804            boolean doOomAdj = doLowMem;
5805            if (!app.killedByAm) {
5806                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5807                        + ProcessList.makeOomAdjString(app.setAdj)
5808                        + ProcessList.makeProcStateString(app.setProcState));
5809                mAllowLowerMemLevel = true;
5810            } else {
5811                // Note that we always want to do oom adj to update our state with the
5812                // new number of procs.
5813                mAllowLowerMemLevel = false;
5814                doLowMem = false;
5815            }
5816            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5817                    app.setAdj, app.setProcState);
5818            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5819                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5820            handleAppDiedLocked(app, false, true);
5821
5822            if (doOomAdj) {
5823                updateOomAdjLocked();
5824            }
5825            if (doLowMem) {
5826                doLowMemReportIfNeededLocked(app);
5827            }
5828        } else if (app.pid != pid) {
5829            // A new process has already been started.
5830            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5831                    + ") has died and restarted (pid " + app.pid + ").");
5832            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5833        } else if (DEBUG_PROCESSES) {
5834            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5835                    + thread.asBinder());
5836        }
5837    }
5838
5839    /**
5840     * If a stack trace dump file is configured, dump process stack traces.
5841     * @param clearTraces causes the dump file to be erased prior to the new
5842     *    traces being written, if true; when false, the new traces will be
5843     *    appended to any existing file content.
5844     * @param firstPids of dalvik VM processes to dump stack traces for first
5845     * @param lastPids of dalvik VM processes to dump stack traces for last
5846     * @param nativePids optional list of native pids to dump stack crawls
5847     */
5848    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5849            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5850            ArrayList<Integer> nativePids) {
5851        ArrayList<Integer> extraPids = null;
5852
5853        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5854        // of the top users at the time of the request.
5855        if (processCpuTracker != null) {
5856            processCpuTracker.init();
5857            try {
5858                Thread.sleep(200);
5859            } catch (InterruptedException ignored) {
5860            }
5861
5862            processCpuTracker.update();
5863
5864            // We'll take the stack crawls of just the top apps using CPU.
5865            final int N = processCpuTracker.countWorkingStats();
5866            extraPids = new ArrayList<>();
5867            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5868                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5869                if (lastPids.indexOfKey(stats.pid) >= 0) {
5870                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5871
5872                    extraPids.add(stats.pid);
5873                } else if (DEBUG_ANR) {
5874                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5875                            + stats.pid);
5876                }
5877            }
5878        }
5879
5880        boolean useTombstonedForJavaTraces = false;
5881        File tracesFile;
5882
5883        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5884        if (tracesDirProp.isEmpty()) {
5885            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5886            // dumping scheme. All traces are written to a global trace file (usually
5887            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5888            // the file if requested.
5889            //
5890            // This mode of operation will be removed in the near future.
5891
5892
5893            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5894            if (globalTracesPath.isEmpty()) {
5895                Slog.w(TAG, "dumpStackTraces: no trace path configured");
5896                return null;
5897            }
5898
5899            tracesFile = new File(globalTracesPath);
5900            try {
5901                if (clearTraces && tracesFile.exists()) {
5902                    tracesFile.delete();
5903                }
5904
5905                tracesFile.createNewFile();
5906                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5907            } catch (IOException e) {
5908                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5909                return null;
5910            }
5911        } else {
5912            File tracesDir = new File(tracesDirProp);
5913            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5914            // Each set of ANR traces is written to a separate file and dumpstate will process
5915            // all such files and add them to a captured bug report if they're recent enough.
5916            maybePruneOldTraces(tracesDir);
5917
5918            // NOTE: We should consider creating the file in native code atomically once we've
5919            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5920            // can be removed.
5921            tracesFile = createAnrDumpFile(tracesDir);
5922            if (tracesFile == null) {
5923                return null;
5924            }
5925
5926            useTombstonedForJavaTraces = true;
5927        }
5928
5929        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5930                useTombstonedForJavaTraces);
5931        return tracesFile;
5932    }
5933
5934    @GuardedBy("ActivityManagerService.class")
5935    private static SimpleDateFormat sAnrFileDateFormat;
5936
5937    private static synchronized File createAnrDumpFile(File tracesDir) {
5938        if (sAnrFileDateFormat == null) {
5939            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5940        }
5941
5942        final String formattedDate = sAnrFileDateFormat.format(new Date());
5943        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5944
5945        try {
5946            if (anrFile.createNewFile()) {
5947                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5948                return anrFile;
5949            } else {
5950                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5951            }
5952        } catch (IOException ioe) {
5953            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5954        }
5955
5956        return null;
5957    }
5958
5959    /**
5960     * Prune all trace files that are more than a day old.
5961     *
5962     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5963     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5964     * since it's the system_server that creates trace files for most ANRs.
5965     */
5966    private static void maybePruneOldTraces(File tracesDir) {
5967        final long now = System.currentTimeMillis();
5968        final File[] traceFiles = tracesDir.listFiles();
5969
5970        if (traceFiles != null) {
5971            for (File file : traceFiles) {
5972                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5973                    if (!file.delete()) {
5974                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
5975                    }
5976                }
5977            }
5978        }
5979    }
5980
5981    /**
5982     * Legacy code, do not use. Existing users will be deleted.
5983     *
5984     * @deprecated
5985     */
5986    @Deprecated
5987    public static class DumpStackFileObserver extends FileObserver {
5988        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5989        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5990
5991        private final String mTracesPath;
5992        private boolean mClosed;
5993
5994        public DumpStackFileObserver(String tracesPath) {
5995            super(tracesPath, FileObserver.CLOSE_WRITE);
5996            mTracesPath = tracesPath;
5997        }
5998
5999        @Override
6000        public synchronized void onEvent(int event, String path) {
6001            mClosed = true;
6002            notify();
6003        }
6004
6005        public long dumpWithTimeout(int pid, long timeout) {
6006            sendSignal(pid, SIGNAL_QUIT);
6007            final long start = SystemClock.elapsedRealtime();
6008
6009            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
6010            synchronized (this) {
6011                try {
6012                    wait(waitTime); // Wait for traces file to be closed.
6013                } catch (InterruptedException e) {
6014                    Slog.wtf(TAG, e);
6015                }
6016            }
6017
6018            // This avoids a corner case of passing a negative time to the native
6019            // trace in case we've already hit the overall timeout.
6020            final long timeWaited = SystemClock.elapsedRealtime() - start;
6021            if (timeWaited >= timeout) {
6022                return timeWaited;
6023            }
6024
6025            if (!mClosed) {
6026                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
6027                       ". Attempting native stack collection.");
6028
6029                final long nativeDumpTimeoutMs = Math.min(
6030                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
6031
6032                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
6033                        (int) (nativeDumpTimeoutMs / 1000));
6034            }
6035
6036            final long end = SystemClock.elapsedRealtime();
6037            mClosed = false;
6038
6039            return (end - start);
6040        }
6041    }
6042
6043    /**
6044     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
6045     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
6046     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
6047     * attempting to obtain native traces in the case of a failure. Returns the total time spent
6048     * capturing traces.
6049     */
6050    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
6051        final long timeStart = SystemClock.elapsedRealtime();
6052        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
6053            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
6054                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
6055        }
6056
6057        return SystemClock.elapsedRealtime() - timeStart;
6058    }
6059
6060    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6061            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6062            boolean useTombstonedForJavaTraces) {
6063
6064        // We don't need any sort of inotify based monitoring when we're dumping traces via
6065        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
6066        // control of all writes to the file in question.
6067        final DumpStackFileObserver observer;
6068        if (useTombstonedForJavaTraces) {
6069            observer = null;
6070        } else {
6071            // Use a FileObserver to detect when traces finish writing.
6072            // The order of traces is considered important to maintain for legibility.
6073            observer = new DumpStackFileObserver(tracesFile);
6074        }
6075
6076        // We must complete all stack dumps within 20 seconds.
6077        long remainingTime = 20 * 1000;
6078        try {
6079            if (observer != null) {
6080                observer.startWatching();
6081            }
6082
6083            // First collect all of the stacks of the most important pids.
6084            if (firstPids != null) {
6085                int num = firstPids.size();
6086                for (int i = 0; i < num; i++) {
6087                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
6088                            + firstPids.get(i));
6089                    final long timeTaken;
6090                    if (useTombstonedForJavaTraces) {
6091                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
6092                    } else {
6093                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6094                    }
6095
6096                    remainingTime -= timeTaken;
6097                    if (remainingTime <= 0) {
6098                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6099                            "); deadline exceeded.");
6100                        return;
6101                    }
6102
6103                    if (DEBUG_ANR) {
6104                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
6105                    }
6106                }
6107            }
6108
6109            // Next collect the stacks of the native pids
6110            if (nativePids != null) {
6111                for (int pid : nativePids) {
6112                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
6113                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
6114
6115                    final long start = SystemClock.elapsedRealtime();
6116                    Debug.dumpNativeBacktraceToFileTimeout(
6117                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6118                    final long timeTaken = SystemClock.elapsedRealtime() - start;
6119
6120                    remainingTime -= timeTaken;
6121                    if (remainingTime <= 0) {
6122                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6123                            "); deadline exceeded.");
6124                        return;
6125                    }
6126
6127                    if (DEBUG_ANR) {
6128                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
6129                    }
6130                }
6131            }
6132
6133            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
6134            if (extraPids != null) {
6135                for (int pid : extraPids) {
6136                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6137
6138                    final long timeTaken;
6139                    if (useTombstonedForJavaTraces) {
6140                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6141                    } else {
6142                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6143                    }
6144
6145                    remainingTime -= timeTaken;
6146                    if (remainingTime <= 0) {
6147                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6148                                "); deadline exceeded.");
6149                        return;
6150                    }
6151
6152                    if (DEBUG_ANR) {
6153                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6154                    }
6155                }
6156            }
6157        } finally {
6158            if (observer != null) {
6159                observer.stopWatching();
6160            }
6161        }
6162    }
6163
6164    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6165        if (true || Build.IS_USER) {
6166            return;
6167        }
6168        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6169        if (tracesPath == null || tracesPath.length() == 0) {
6170            return;
6171        }
6172
6173        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6174        StrictMode.allowThreadDiskWrites();
6175        try {
6176            final File tracesFile = new File(tracesPath);
6177            final File tracesDir = tracesFile.getParentFile();
6178            final File tracesTmp = new File(tracesDir, "__tmp__");
6179            try {
6180                if (tracesFile.exists()) {
6181                    tracesTmp.delete();
6182                    tracesFile.renameTo(tracesTmp);
6183                }
6184                StringBuilder sb = new StringBuilder();
6185                Time tobj = new Time();
6186                tobj.set(System.currentTimeMillis());
6187                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6188                sb.append(": ");
6189                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6190                sb.append(" since ");
6191                sb.append(msg);
6192                FileOutputStream fos = new FileOutputStream(tracesFile);
6193                fos.write(sb.toString().getBytes());
6194                if (app == null) {
6195                    fos.write("\n*** No application process!".getBytes());
6196                }
6197                fos.close();
6198                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6199            } catch (IOException e) {
6200                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6201                return;
6202            }
6203
6204            if (app != null && app.pid > 0) {
6205                ArrayList<Integer> firstPids = new ArrayList<Integer>();
6206                firstPids.add(app.pid);
6207                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6208            }
6209
6210            File lastTracesFile = null;
6211            File curTracesFile = null;
6212            for (int i=9; i>=0; i--) {
6213                String name = String.format(Locale.US, "slow%02d.txt", i);
6214                curTracesFile = new File(tracesDir, name);
6215                if (curTracesFile.exists()) {
6216                    if (lastTracesFile != null) {
6217                        curTracesFile.renameTo(lastTracesFile);
6218                    } else {
6219                        curTracesFile.delete();
6220                    }
6221                }
6222                lastTracesFile = curTracesFile;
6223            }
6224            tracesFile.renameTo(curTracesFile);
6225            if (tracesTmp.exists()) {
6226                tracesTmp.renameTo(tracesFile);
6227            }
6228        } finally {
6229            StrictMode.setThreadPolicy(oldPolicy);
6230        }
6231    }
6232
6233    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6234        if (!mLaunchWarningShown) {
6235            mLaunchWarningShown = true;
6236            mUiHandler.post(new Runnable() {
6237                @Override
6238                public void run() {
6239                    synchronized (ActivityManagerService.this) {
6240                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6241                        d.show();
6242                        mUiHandler.postDelayed(new Runnable() {
6243                            @Override
6244                            public void run() {
6245                                synchronized (ActivityManagerService.this) {
6246                                    d.dismiss();
6247                                    mLaunchWarningShown = false;
6248                                }
6249                            }
6250                        }, 4000);
6251                    }
6252                }
6253            });
6254        }
6255    }
6256
6257    @Override
6258    public boolean clearApplicationUserData(final String packageName, boolean keepState,
6259            final IPackageDataObserver observer, int userId) {
6260        enforceNotIsolatedCaller("clearApplicationUserData");
6261        int uid = Binder.getCallingUid();
6262        int pid = Binder.getCallingPid();
6263        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6264                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6265
6266        final ApplicationInfo appInfo;
6267        final boolean isInstantApp;
6268
6269        long callingId = Binder.clearCallingIdentity();
6270        try {
6271            IPackageManager pm = AppGlobals.getPackageManager();
6272            synchronized(this) {
6273                // Instant packages are not protected
6274                if (getPackageManagerInternalLocked().isPackageDataProtected(
6275                        resolvedUserId, packageName)) {
6276                    throw new SecurityException(
6277                            "Cannot clear data for a protected package: " + packageName);
6278                }
6279
6280                ApplicationInfo applicationInfo = null;
6281                try {
6282                    applicationInfo = pm.getApplicationInfo(packageName,
6283                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6284                } catch (RemoteException e) {
6285                    /* ignore */
6286                }
6287                appInfo = applicationInfo;
6288
6289                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6290
6291                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6292                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6293                    throw new SecurityException("PID " + pid + " does not have permission "
6294                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6295                            + " of package " + packageName);
6296                }
6297
6298                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6299                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
6300                final boolean isUninstalledAppWithoutInstantMetadata =
6301                        (appInfo == null && !hasInstantMetadata);
6302                isInstantApp = (appInfo != null && appInfo.isInstantApp())
6303                        || hasInstantMetadata;
6304                final boolean canAccessInstantApps = checkComponentPermission(
6305                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6306                        == PackageManager.PERMISSION_GRANTED;
6307
6308                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6309                        && !canAccessInstantApps)) {
6310                    Slog.w(TAG, "Invalid packageName: " + packageName);
6311                    if (observer != null) {
6312                        try {
6313                            observer.onRemoveCompleted(packageName, false);
6314                        } catch (RemoteException e) {
6315                            Slog.i(TAG, "Observer no longer exists.");
6316                        }
6317                    }
6318                    return false;
6319                }
6320
6321                if (appInfo != null) {
6322                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6323                    mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6324                }
6325            }
6326
6327            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6328                @Override
6329                public void onRemoveCompleted(String packageName, boolean succeeded)
6330                        throws RemoteException {
6331                    if (appInfo != null) {
6332                        synchronized (ActivityManagerService.this) {
6333                            finishForceStopPackageLocked(packageName, appInfo.uid);
6334                        }
6335                    }
6336                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6337                            Uri.fromParts("package", packageName, null));
6338                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6339                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6340                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6341                    if (isInstantApp) {
6342                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6343                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6344                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6345                                resolvedUserId);
6346                    } else {
6347                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6348                                null, null, null, null, false, false, resolvedUserId);
6349                    }
6350
6351                    if (observer != null) {
6352                        observer.onRemoveCompleted(packageName, succeeded);
6353                    }
6354                }
6355            };
6356
6357            try {
6358                // Clear application user data
6359                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6360
6361                if (appInfo != null) {
6362                    // Restore already established notification state and permission grants,
6363                    // so it told us to keep those intact -- it's about to emplace app data
6364                    // that is appropriate for those bits of system state.
6365                    if (!keepState) {
6366                        synchronized (this) {
6367                            // Remove all permissions granted from/to this package
6368                            removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
6369                                    false);
6370                        }
6371
6372                        // Reset notification state
6373                        INotificationManager inm = NotificationManager.getService();
6374                        inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6375                    }
6376
6377                    // Clear its scheduled jobs
6378                    JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6379                    js.cancelJobsForUid(appInfo.uid, "clear data");
6380
6381                    // Clear its pending alarms
6382                    AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6383                    ami.removeAlarmsForUid(appInfo.uid);
6384                }
6385            } catch (RemoteException e) {
6386            }
6387        } finally {
6388            Binder.restoreCallingIdentity(callingId);
6389        }
6390        return true;
6391    }
6392
6393    @Override
6394    public void killBackgroundProcesses(final String packageName, int userId) {
6395        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6396                != PackageManager.PERMISSION_GRANTED &&
6397                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6398                        != PackageManager.PERMISSION_GRANTED) {
6399            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6400                    + Binder.getCallingPid()
6401                    + ", uid=" + Binder.getCallingUid()
6402                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6403            Slog.w(TAG, msg);
6404            throw new SecurityException(msg);
6405        }
6406
6407        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6408                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6409        long callingId = Binder.clearCallingIdentity();
6410        try {
6411            IPackageManager pm = AppGlobals.getPackageManager();
6412            synchronized(this) {
6413                int appId = -1;
6414                try {
6415                    appId = UserHandle.getAppId(
6416                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6417                } catch (RemoteException e) {
6418                }
6419                if (appId == -1) {
6420                    Slog.w(TAG, "Invalid packageName: " + packageName);
6421                    return;
6422                }
6423                killPackageProcessesLocked(packageName, appId, userId,
6424                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6425            }
6426        } finally {
6427            Binder.restoreCallingIdentity(callingId);
6428        }
6429    }
6430
6431    @Override
6432    public void killAllBackgroundProcesses() {
6433        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6434                != PackageManager.PERMISSION_GRANTED) {
6435            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6436                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6437                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6438            Slog.w(TAG, msg);
6439            throw new SecurityException(msg);
6440        }
6441
6442        final long callingId = Binder.clearCallingIdentity();
6443        try {
6444            synchronized (this) {
6445                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6446                final int NP = mProcessNames.getMap().size();
6447                for (int ip = 0; ip < NP; ip++) {
6448                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6449                    final int NA = apps.size();
6450                    for (int ia = 0; ia < NA; ia++) {
6451                        final ProcessRecord app = apps.valueAt(ia);
6452                        if (app.persistent) {
6453                            // We don't kill persistent processes.
6454                            continue;
6455                        }
6456                        if (app.removed) {
6457                            procs.add(app);
6458                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6459                            app.removed = true;
6460                            procs.add(app);
6461                        }
6462                    }
6463                }
6464
6465                final int N = procs.size();
6466                for (int i = 0; i < N; i++) {
6467                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6468                }
6469
6470                mAllowLowerMemLevel = true;
6471
6472                updateOomAdjLocked();
6473                doLowMemReportIfNeededLocked(null);
6474            }
6475        } finally {
6476            Binder.restoreCallingIdentity(callingId);
6477        }
6478    }
6479
6480    /**
6481     * Kills all background processes, except those matching any of the
6482     * specified properties.
6483     *
6484     * @param minTargetSdk the target SDK version at or above which to preserve
6485     *                     processes, or {@code -1} to ignore the target SDK
6486     * @param maxProcState the process state at or below which to preserve
6487     *                     processes, or {@code -1} to ignore the process state
6488     */
6489    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6490        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6491                != PackageManager.PERMISSION_GRANTED) {
6492            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6493                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6494                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6495            Slog.w(TAG, msg);
6496            throw new SecurityException(msg);
6497        }
6498
6499        final long callingId = Binder.clearCallingIdentity();
6500        try {
6501            synchronized (this) {
6502                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6503                final int NP = mProcessNames.getMap().size();
6504                for (int ip = 0; ip < NP; ip++) {
6505                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6506                    final int NA = apps.size();
6507                    for (int ia = 0; ia < NA; ia++) {
6508                        final ProcessRecord app = apps.valueAt(ia);
6509                        if (app.removed) {
6510                            procs.add(app);
6511                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6512                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6513                            app.removed = true;
6514                            procs.add(app);
6515                        }
6516                    }
6517                }
6518
6519                final int N = procs.size();
6520                for (int i = 0; i < N; i++) {
6521                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6522                }
6523            }
6524        } finally {
6525            Binder.restoreCallingIdentity(callingId);
6526        }
6527    }
6528
6529    @Override
6530    public void forceStopPackage(final String packageName, int userId) {
6531        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6532                != PackageManager.PERMISSION_GRANTED) {
6533            String msg = "Permission Denial: forceStopPackage() from pid="
6534                    + Binder.getCallingPid()
6535                    + ", uid=" + Binder.getCallingUid()
6536                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6537            Slog.w(TAG, msg);
6538            throw new SecurityException(msg);
6539        }
6540        final int callingPid = Binder.getCallingPid();
6541        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6542                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6543        long callingId = Binder.clearCallingIdentity();
6544        try {
6545            IPackageManager pm = AppGlobals.getPackageManager();
6546            synchronized(this) {
6547                int[] users = userId == UserHandle.USER_ALL
6548                        ? mUserController.getUsers() : new int[] { userId };
6549                for (int user : users) {
6550                    int pkgUid = -1;
6551                    try {
6552                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6553                                user);
6554                    } catch (RemoteException e) {
6555                    }
6556                    if (pkgUid == -1) {
6557                        Slog.w(TAG, "Invalid packageName: " + packageName);
6558                        continue;
6559                    }
6560                    try {
6561                        pm.setPackageStoppedState(packageName, true, user);
6562                    } catch (RemoteException e) {
6563                    } catch (IllegalArgumentException e) {
6564                        Slog.w(TAG, "Failed trying to unstop package "
6565                                + packageName + ": " + e);
6566                    }
6567                    if (mUserController.isUserRunning(user, 0)) {
6568                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6569                        finishForceStopPackageLocked(packageName, pkgUid);
6570                    }
6571                }
6572            }
6573        } finally {
6574            Binder.restoreCallingIdentity(callingId);
6575        }
6576    }
6577
6578    @Override
6579    public void addPackageDependency(String packageName) {
6580        synchronized (this) {
6581            int callingPid = Binder.getCallingPid();
6582            if (callingPid == myPid()) {
6583                //  Yeah, um, no.
6584                return;
6585            }
6586            ProcessRecord proc;
6587            synchronized (mPidsSelfLocked) {
6588                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6589            }
6590            if (proc != null) {
6591                if (proc.pkgDeps == null) {
6592                    proc.pkgDeps = new ArraySet<String>(1);
6593                }
6594                proc.pkgDeps.add(packageName);
6595            }
6596        }
6597    }
6598
6599    /*
6600     * The pkg name and app id have to be specified.
6601     */
6602    @Override
6603    public void killApplication(String pkg, int appId, int userId, String reason) {
6604        if (pkg == null) {
6605            return;
6606        }
6607        // Make sure the uid is valid.
6608        if (appId < 0) {
6609            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6610            return;
6611        }
6612        int callerUid = Binder.getCallingUid();
6613        // Only the system server can kill an application
6614        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6615            // Post an aysnc message to kill the application
6616            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6617            msg.arg1 = appId;
6618            msg.arg2 = userId;
6619            Bundle bundle = new Bundle();
6620            bundle.putString("pkg", pkg);
6621            bundle.putString("reason", reason);
6622            msg.obj = bundle;
6623            mHandler.sendMessage(msg);
6624        } else {
6625            throw new SecurityException(callerUid + " cannot kill pkg: " +
6626                    pkg);
6627        }
6628    }
6629
6630    @Override
6631    public void closeSystemDialogs(String reason) {
6632        enforceNotIsolatedCaller("closeSystemDialogs");
6633
6634        final int pid = Binder.getCallingPid();
6635        final int uid = Binder.getCallingUid();
6636        final long origId = Binder.clearCallingIdentity();
6637        try {
6638            synchronized (this) {
6639                // Only allow this from foreground processes, so that background
6640                // applications can't abuse it to prevent system UI from being shown.
6641                if (uid >= FIRST_APPLICATION_UID) {
6642                    ProcessRecord proc;
6643                    synchronized (mPidsSelfLocked) {
6644                        proc = mPidsSelfLocked.get(pid);
6645                    }
6646                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6647                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6648                                + " from background process " + proc);
6649                        return;
6650                    }
6651                }
6652                closeSystemDialogsLocked(reason);
6653            }
6654        } finally {
6655            Binder.restoreCallingIdentity(origId);
6656        }
6657    }
6658
6659    void closeSystemDialogsLocked(String reason) {
6660        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6661        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6662                | Intent.FLAG_RECEIVER_FOREGROUND);
6663        if (reason != null) {
6664            intent.putExtra("reason", reason);
6665        }
6666        mWindowManager.closeSystemDialogs(reason);
6667
6668        mStackSupervisor.closeSystemDialogsLocked();
6669
6670        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6671                OP_NONE, null, false, false,
6672                -1, SYSTEM_UID, UserHandle.USER_ALL);
6673    }
6674
6675    @Override
6676    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6677        enforceNotIsolatedCaller("getProcessMemoryInfo");
6678        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6679        for (int i=pids.length-1; i>=0; i--) {
6680            ProcessRecord proc;
6681            int oomAdj;
6682            synchronized (this) {
6683                synchronized (mPidsSelfLocked) {
6684                    proc = mPidsSelfLocked.get(pids[i]);
6685                    oomAdj = proc != null ? proc.setAdj : 0;
6686                }
6687            }
6688            infos[i] = new Debug.MemoryInfo();
6689            long startTime = SystemClock.currentThreadTimeMillis();
6690            Debug.getMemoryInfo(pids[i], infos[i]);
6691            long endTime = SystemClock.currentThreadTimeMillis();
6692            if (proc != null) {
6693                synchronized (this) {
6694                    if (proc.thread != null && proc.setAdj == oomAdj) {
6695                        // Record this for posterity if the process has been stable.
6696                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6697                                infos[i].getTotalUss(), infos[i].getTotalRss(), false,
6698                                ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
6699                                proc.pkgList);
6700                    }
6701                }
6702            }
6703        }
6704        return infos;
6705    }
6706
6707    @Override
6708    public long[] getProcessPss(int[] pids) {
6709        enforceNotIsolatedCaller("getProcessPss");
6710        long[] pss = new long[pids.length];
6711        for (int i=pids.length-1; i>=0; i--) {
6712            ProcessRecord proc;
6713            int oomAdj;
6714            synchronized (this) {
6715                synchronized (mPidsSelfLocked) {
6716                    proc = mPidsSelfLocked.get(pids[i]);
6717                    oomAdj = proc != null ? proc.setAdj : 0;
6718                }
6719            }
6720            long[] tmpUss = new long[3];
6721            long startTime = SystemClock.currentThreadTimeMillis();
6722            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6723            long endTime = SystemClock.currentThreadTimeMillis();
6724            if (proc != null) {
6725                synchronized (this) {
6726                    if (proc.thread != null && proc.setAdj == oomAdj) {
6727                        // Record this for posterity if the process has been stable.
6728                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
6729                                ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
6730                    }
6731                }
6732            }
6733        }
6734        return pss;
6735    }
6736
6737    @Override
6738    public void killApplicationProcess(String processName, int uid) {
6739        if (processName == null) {
6740            return;
6741        }
6742
6743        int callerUid = Binder.getCallingUid();
6744        // Only the system server can kill an application
6745        if (callerUid == SYSTEM_UID) {
6746            synchronized (this) {
6747                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6748                if (app != null && app.thread != null) {
6749                    try {
6750                        app.thread.scheduleSuicide();
6751                    } catch (RemoteException e) {
6752                        // If the other end already died, then our work here is done.
6753                    }
6754                } else {
6755                    Slog.w(TAG, "Process/uid not found attempting kill of "
6756                            + processName + " / " + uid);
6757                }
6758            }
6759        } else {
6760            throw new SecurityException(callerUid + " cannot kill app process: " +
6761                    processName);
6762        }
6763    }
6764
6765    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6766        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6767                false, true, false, false, UserHandle.getUserId(uid), reason);
6768    }
6769
6770    private void finishForceStopPackageLocked(final String packageName, int uid) {
6771        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6772                Uri.fromParts("package", packageName, null));
6773        if (!mProcessesReady) {
6774            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6775                    | Intent.FLAG_RECEIVER_FOREGROUND);
6776        }
6777        intent.putExtra(Intent.EXTRA_UID, uid);
6778        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6779        broadcastIntentLocked(null, null, intent,
6780                null, null, 0, null, null, null, OP_NONE,
6781                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6782    }
6783
6784
6785    private final boolean killPackageProcessesLocked(String packageName, int appId,
6786            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6787            boolean doit, boolean evenPersistent, String reason) {
6788        ArrayList<ProcessRecord> procs = new ArrayList<>();
6789
6790        // Remove all processes this package may have touched: all with the
6791        // same UID (except for the system or root user), and all whose name
6792        // matches the package name.
6793        final int NP = mProcessNames.getMap().size();
6794        for (int ip=0; ip<NP; ip++) {
6795            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6796            final int NA = apps.size();
6797            for (int ia=0; ia<NA; ia++) {
6798                ProcessRecord app = apps.valueAt(ia);
6799                if (app.persistent && !evenPersistent) {
6800                    // we don't kill persistent processes
6801                    continue;
6802                }
6803                if (app.removed) {
6804                    if (doit) {
6805                        procs.add(app);
6806                    }
6807                    continue;
6808                }
6809
6810                // Skip process if it doesn't meet our oom adj requirement.
6811                if (app.setAdj < minOomAdj) {
6812                    continue;
6813                }
6814
6815                // If no package is specified, we call all processes under the
6816                // give user id.
6817                if (packageName == null) {
6818                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6819                        continue;
6820                    }
6821                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6822                        continue;
6823                    }
6824                // Package has been specified, we want to hit all processes
6825                // that match it.  We need to qualify this by the processes
6826                // that are running under the specified app and user ID.
6827                } else {
6828                    final boolean isDep = app.pkgDeps != null
6829                            && app.pkgDeps.contains(packageName);
6830                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6831                        continue;
6832                    }
6833                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6834                        continue;
6835                    }
6836                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6837                        continue;
6838                    }
6839                }
6840
6841                // Process has passed all conditions, kill it!
6842                if (!doit) {
6843                    return true;
6844                }
6845                app.removed = true;
6846                procs.add(app);
6847            }
6848        }
6849
6850        int N = procs.size();
6851        for (int i=0; i<N; i++) {
6852            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6853        }
6854        updateOomAdjLocked();
6855        return N > 0;
6856    }
6857
6858    private void cleanupDisabledPackageComponentsLocked(
6859            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6860
6861        Set<String> disabledClasses = null;
6862        boolean packageDisabled = false;
6863        IPackageManager pm = AppGlobals.getPackageManager();
6864
6865        if (changedClasses == null) {
6866            // Nothing changed...
6867            return;
6868        }
6869
6870        // Determine enable/disable state of the package and its components.
6871        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6872        for (int i = changedClasses.length - 1; i >= 0; i--) {
6873            final String changedClass = changedClasses[i];
6874
6875            if (changedClass.equals(packageName)) {
6876                try {
6877                    // Entire package setting changed
6878                    enabled = pm.getApplicationEnabledSetting(packageName,
6879                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6880                } catch (Exception e) {
6881                    // No such package/component; probably racing with uninstall.  In any
6882                    // event it means we have nothing further to do here.
6883                    return;
6884                }
6885                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6886                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6887                if (packageDisabled) {
6888                    // Entire package is disabled.
6889                    // No need to continue to check component states.
6890                    disabledClasses = null;
6891                    break;
6892                }
6893            } else {
6894                try {
6895                    enabled = pm.getComponentEnabledSetting(
6896                            new ComponentName(packageName, changedClass),
6897                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6898                } catch (Exception e) {
6899                    // As above, probably racing with uninstall.
6900                    return;
6901                }
6902                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6903                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6904                    if (disabledClasses == null) {
6905                        disabledClasses = new ArraySet<>(changedClasses.length);
6906                    }
6907                    disabledClasses.add(changedClass);
6908                }
6909            }
6910        }
6911
6912        if (!packageDisabled && disabledClasses == null) {
6913            // Nothing to do here...
6914            return;
6915        }
6916
6917        // Clean-up disabled activities.
6918        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6919                packageName, disabledClasses, true, false, userId) && mBooted) {
6920            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6921            mStackSupervisor.scheduleIdleLocked();
6922        }
6923
6924        // Clean-up disabled tasks
6925        mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6926
6927        // Clean-up disabled services.
6928        mServices.bringDownDisabledPackageServicesLocked(
6929                packageName, disabledClasses, userId, false, killProcess, true);
6930
6931        // Clean-up disabled providers.
6932        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6933        mProviderMap.collectPackageProvidersLocked(
6934                packageName, disabledClasses, true, false, userId, providers);
6935        for (int i = providers.size() - 1; i >= 0; i--) {
6936            removeDyingProviderLocked(null, providers.get(i), true);
6937        }
6938
6939        // Clean-up disabled broadcast receivers.
6940        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6941            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6942                    packageName, disabledClasses, userId, true);
6943        }
6944
6945    }
6946
6947    final boolean clearBroadcastQueueForUserLocked(int userId) {
6948        boolean didSomething = false;
6949        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6950            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6951                    null, null, userId, true);
6952        }
6953        return didSomething;
6954    }
6955
6956    final boolean forceStopPackageLocked(String packageName, int appId,
6957            boolean callerWillRestart, boolean purgeCache, boolean doit,
6958            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6959        int i;
6960
6961        if (userId == UserHandle.USER_ALL && packageName == null) {
6962            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6963        }
6964
6965        if (appId < 0 && packageName != null) {
6966            try {
6967                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6968                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6969            } catch (RemoteException e) {
6970            }
6971        }
6972
6973        if (doit) {
6974            if (packageName != null) {
6975                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6976                        + " user=" + userId + ": " + reason);
6977            } else {
6978                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6979            }
6980
6981            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6982        }
6983
6984        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6985                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6986                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6987
6988        didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
6989
6990        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6991                packageName, null, doit, evenPersistent, userId)) {
6992            if (!doit) {
6993                return true;
6994            }
6995            didSomething = true;
6996        }
6997
6998        if (mServices.bringDownDisabledPackageServicesLocked(
6999                packageName, null, userId, evenPersistent, true, doit)) {
7000            if (!doit) {
7001                return true;
7002            }
7003            didSomething = true;
7004        }
7005
7006        if (packageName == null) {
7007            // Remove all sticky broadcasts from this user.
7008            mStickyBroadcasts.remove(userId);
7009        }
7010
7011        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7012        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
7013                userId, providers)) {
7014            if (!doit) {
7015                return true;
7016            }
7017            didSomething = true;
7018        }
7019        for (i = providers.size() - 1; i >= 0; i--) {
7020            removeDyingProviderLocked(null, providers.get(i), true);
7021        }
7022
7023        // Remove transient permissions granted from/to this package/user
7024        removeUriPermissionsForPackageLocked(packageName, userId, false, false);
7025
7026        if (doit) {
7027            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
7028                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7029                        packageName, null, userId, doit);
7030            }
7031        }
7032
7033        if (packageName == null || uninstalling) {
7034            // Remove pending intents.  For now we only do this when force
7035            // stopping users, because we have some problems when doing this
7036            // for packages -- app widgets are not currently cleaned up for
7037            // such packages, so they can be left with bad pending intents.
7038            if (mIntentSenderRecords.size() > 0) {
7039                Iterator<WeakReference<PendingIntentRecord>> it
7040                        = mIntentSenderRecords.values().iterator();
7041                while (it.hasNext()) {
7042                    WeakReference<PendingIntentRecord> wpir = it.next();
7043                    if (wpir == null) {
7044                        it.remove();
7045                        continue;
7046                    }
7047                    PendingIntentRecord pir = wpir.get();
7048                    if (pir == null) {
7049                        it.remove();
7050                        continue;
7051                    }
7052                    if (packageName == null) {
7053                        // Stopping user, remove all objects for the user.
7054                        if (pir.key.userId != userId) {
7055                            // Not the same user, skip it.
7056                            continue;
7057                        }
7058                    } else {
7059                        if (UserHandle.getAppId(pir.uid) != appId) {
7060                            // Different app id, skip it.
7061                            continue;
7062                        }
7063                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7064                            // Different user, skip it.
7065                            continue;
7066                        }
7067                        if (!pir.key.packageName.equals(packageName)) {
7068                            // Different package, skip it.
7069                            continue;
7070                        }
7071                    }
7072                    if (!doit) {
7073                        return true;
7074                    }
7075                    didSomething = true;
7076                    it.remove();
7077                    makeIntentSenderCanceledLocked(pir);
7078                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7079                        pir.key.activity.pendingResults.remove(pir.ref);
7080                    }
7081                }
7082            }
7083        }
7084
7085        if (doit) {
7086            if (purgeCache && packageName != null) {
7087                AttributeCache ac = AttributeCache.instance();
7088                if (ac != null) {
7089                    ac.removePackage(packageName);
7090                }
7091            }
7092            if (mBooted) {
7093                mStackSupervisor.resumeFocusedStackTopActivityLocked();
7094                mStackSupervisor.scheduleIdleLocked();
7095            }
7096        }
7097
7098        return didSomething;
7099    }
7100
7101    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7102        return removeProcessNameLocked(name, uid, null);
7103    }
7104
7105    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
7106            final ProcessRecord expecting) {
7107        ProcessRecord old = mProcessNames.get(name, uid);
7108        // Only actually remove when the currently recorded value matches the
7109        // record that we expected; if it doesn't match then we raced with a
7110        // newly created process and we don't want to destroy the new one.
7111        if ((expecting == null) || (old == expecting)) {
7112            mProcessNames.remove(name, uid);
7113        }
7114        if (old != null && old.uidRecord != null) {
7115            old.uidRecord.numProcs--;
7116            if (old.uidRecord.numProcs == 0) {
7117                // No more processes using this uid, tell clients it is gone.
7118                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7119                        "No more processes in " + old.uidRecord);
7120                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
7121                EventLogTags.writeAmUidStopped(uid);
7122                mActiveUids.remove(uid);
7123                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
7124            }
7125            old.uidRecord = null;
7126        }
7127        mIsolatedProcesses.remove(uid);
7128        return old;
7129    }
7130
7131    private final void addProcessNameLocked(ProcessRecord proc) {
7132        // We shouldn't already have a process under this name, but just in case we
7133        // need to clean up whatever may be there now.
7134        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
7135        if (old == proc && proc.persistent) {
7136            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
7137            Slog.w(TAG, "Re-adding persistent process " + proc);
7138        } else if (old != null) {
7139            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7140        }
7141        UidRecord uidRec = mActiveUids.get(proc.uid);
7142        if (uidRec == null) {
7143            uidRec = new UidRecord(proc.uid);
7144            // This is the first appearance of the uid, report it now!
7145            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7146                    "Creating new process uid: " + uidRec);
7147            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7148                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7149                uidRec.setWhitelist = uidRec.curWhitelist = true;
7150            }
7151            uidRec.updateHasInternetPermission();
7152            mActiveUids.put(proc.uid, uidRec);
7153            EventLogTags.writeAmUidRunning(uidRec.uid);
7154            noteUidProcessState(uidRec.uid, uidRec.curProcState);
7155        }
7156        proc.uidRecord = uidRec;
7157
7158        // Reset render thread tid if it was already set, so new process can set it again.
7159        proc.renderThreadTid = 0;
7160        uidRec.numProcs++;
7161        mProcessNames.put(proc.processName, proc.uid, proc);
7162        if (proc.isolated) {
7163            mIsolatedProcesses.put(proc.uid, proc);
7164        }
7165    }
7166
7167    boolean removeProcessLocked(ProcessRecord app,
7168            boolean callerWillRestart, boolean allowRestart, String reason) {
7169        final String name = app.processName;
7170        final int uid = app.uid;
7171        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7172            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7173
7174        ProcessRecord old = mProcessNames.get(name, uid);
7175        if (old != app) {
7176            // This process is no longer active, so nothing to do.
7177            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7178            return false;
7179        }
7180        removeProcessNameLocked(name, uid);
7181        if (mHeavyWeightProcess == app) {
7182            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7183                    mHeavyWeightProcess.userId, 0));
7184            mHeavyWeightProcess = null;
7185        }
7186        boolean needRestart = false;
7187        if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7188            int pid = app.pid;
7189            if (pid > 0) {
7190                synchronized (mPidsSelfLocked) {
7191                    mPidsSelfLocked.remove(pid);
7192                    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7193                }
7194                mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7195                if (app.isolated) {
7196                    mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7197                    getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7198                }
7199            }
7200            boolean willRestart = false;
7201            if (app.persistent && !app.isolated) {
7202                if (!callerWillRestart) {
7203                    willRestart = true;
7204                } else {
7205                    needRestart = true;
7206                }
7207            }
7208            app.kill(reason, true);
7209            handleAppDiedLocked(app, willRestart, allowRestart);
7210            if (willRestart) {
7211                removeLruProcessLocked(app);
7212                addAppLocked(app.info, null, false, null /* ABI override */);
7213            }
7214        } else {
7215            mRemovedProcesses.add(app);
7216        }
7217
7218        return needRestart;
7219    }
7220
7221    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7222        cleanupAppInLaunchingProvidersLocked(app, true);
7223        removeProcessLocked(app, false, true, "timeout publishing content providers");
7224    }
7225
7226    private final void processStartTimedOutLocked(ProcessRecord app) {
7227        final int pid = app.pid;
7228        boolean gone = false;
7229        synchronized (mPidsSelfLocked) {
7230            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7231            if (knownApp != null && knownApp.thread == null) {
7232                mPidsSelfLocked.remove(pid);
7233                gone = true;
7234            }
7235        }
7236
7237        if (gone) {
7238            Slog.w(TAG, "Process " + app + " failed to attach");
7239            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7240                    pid, app.uid, app.processName);
7241            removeProcessNameLocked(app.processName, app.uid);
7242            if (mHeavyWeightProcess == app) {
7243                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7244                        mHeavyWeightProcess.userId, 0));
7245                mHeavyWeightProcess = null;
7246            }
7247            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7248            // Take care of any launching providers waiting for this process.
7249            cleanupAppInLaunchingProvidersLocked(app, true);
7250            // Take care of any services that are waiting for the process.
7251            mServices.processStartTimedOutLocked(app);
7252            app.kill("start timeout", true);
7253            if (app.isolated) {
7254                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7255            }
7256            removeLruProcessLocked(app);
7257            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7258                Slog.w(TAG, "Unattached app died before backup, skipping");
7259                mHandler.post(new Runnable() {
7260                @Override
7261                    public void run(){
7262                        try {
7263                            IBackupManager bm = IBackupManager.Stub.asInterface(
7264                                    ServiceManager.getService(Context.BACKUP_SERVICE));
7265                            bm.agentDisconnected(app.info.packageName);
7266                        } catch (RemoteException e) {
7267                            // Can't happen; the backup manager is local
7268                        }
7269                    }
7270                });
7271            }
7272            if (isPendingBroadcastProcessLocked(pid)) {
7273                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7274                skipPendingBroadcastLocked(pid);
7275            }
7276        } else {
7277            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7278        }
7279    }
7280
7281    private final boolean attachApplicationLocked(IApplicationThread thread,
7282            int pid, int callingUid, long startSeq) {
7283
7284        // Find the application record that is being attached...  either via
7285        // the pid if we are running in multiple processes, or just pull the
7286        // next app record if we are emulating process with anonymous threads.
7287        ProcessRecord app;
7288        long startTime = SystemClock.uptimeMillis();
7289        if (pid != MY_PID && pid >= 0) {
7290            synchronized (mPidsSelfLocked) {
7291                app = mPidsSelfLocked.get(pid);
7292            }
7293        } else {
7294            app = null;
7295        }
7296
7297        // It's possible that process called attachApplication before we got a chance to
7298        // update the internal state.
7299        if (app == null && startSeq > 0) {
7300            final ProcessRecord pending = mPendingStarts.get(startSeq);
7301            if (pending != null && pending.startUid == callingUid
7302                    && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7303                            startSeq, true)) {
7304                app = pending;
7305            }
7306        }
7307
7308        if (app == null) {
7309            Slog.w(TAG, "No pending application record for pid " + pid
7310                    + " (IApplicationThread " + thread + "); dropping process");
7311            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7312            if (pid > 0 && pid != MY_PID) {
7313                killProcessQuiet(pid);
7314                //TODO: killProcessGroup(app.info.uid, pid);
7315            } else {
7316                try {
7317                    thread.scheduleExit();
7318                } catch (Exception e) {
7319                    // Ignore exceptions.
7320                }
7321            }
7322            return false;
7323        }
7324
7325        // If this application record is still attached to a previous
7326        // process, clean it up now.
7327        if (app.thread != null) {
7328            handleAppDiedLocked(app, true, true);
7329        }
7330
7331        // Tell the process all about itself.
7332
7333        if (DEBUG_ALL) Slog.v(
7334                TAG, "Binding process pid " + pid + " to record " + app);
7335
7336        final String processName = app.processName;
7337        try {
7338            AppDeathRecipient adr = new AppDeathRecipient(
7339                    app, pid, thread);
7340            thread.asBinder().linkToDeath(adr, 0);
7341            app.deathRecipient = adr;
7342        } catch (RemoteException e) {
7343            app.resetPackageList(mProcessStats);
7344            startProcessLocked(app, "link fail", processName);
7345            return false;
7346        }
7347
7348        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7349
7350        app.makeActive(thread, mProcessStats);
7351        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7352        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7353        app.forcingToImportant = null;
7354        updateProcessForegroundLocked(app, false, false);
7355        app.hasShownUi = false;
7356        app.debugging = false;
7357        app.cached = false;
7358        app.killedByAm = false;
7359        app.killed = false;
7360
7361
7362        // We carefully use the same state that PackageManager uses for
7363        // filtering, since we use this flag to decide if we need to install
7364        // providers when user is unlocked later
7365        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7366
7367        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7368
7369        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7370        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7371
7372        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7373            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7374            msg.obj = app;
7375            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7376        }
7377
7378        checkTime(startTime, "attachApplicationLocked: before bindApplication");
7379
7380        if (!normalMode) {
7381            Slog.i(TAG, "Launching preboot mode app: " + app);
7382        }
7383
7384        if (DEBUG_ALL) Slog.v(
7385            TAG, "New app record " + app
7386            + " thread=" + thread.asBinder() + " pid=" + pid);
7387        try {
7388            int testMode = ApplicationThreadConstants.DEBUG_OFF;
7389            if (mDebugApp != null && mDebugApp.equals(processName)) {
7390                testMode = mWaitForDebugger
7391                    ? ApplicationThreadConstants.DEBUG_WAIT
7392                    : ApplicationThreadConstants.DEBUG_ON;
7393                app.debugging = true;
7394                if (mDebugTransient) {
7395                    mDebugApp = mOrigDebugApp;
7396                    mWaitForDebugger = mOrigWaitForDebugger;
7397                }
7398            }
7399
7400            boolean enableTrackAllocation = false;
7401            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7402                enableTrackAllocation = true;
7403                mTrackAllocationApp = null;
7404            }
7405
7406            // If the app is being launched for restore or full backup, set it up specially
7407            boolean isRestrictedBackupMode = false;
7408            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7409                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7410                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7411                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7412                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7413            }
7414
7415            if (app.instr != null) {
7416                notifyPackageUse(app.instr.mClass.getPackageName(),
7417                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7418            }
7419            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7420                    + processName + " with config " + getGlobalConfiguration());
7421            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7422            app.compat = compatibilityInfoForPackageLocked(appInfo);
7423
7424            ProfilerInfo profilerInfo = null;
7425            String preBindAgent = null;
7426            if (mProfileApp != null && mProfileApp.equals(processName)) {
7427                mProfileProc = app;
7428                if (mProfilerInfo != null) {
7429                    // Send a profiler info object to the app if either a file is given, or
7430                    // an agent should be loaded at bind-time.
7431                    boolean needsInfo = mProfilerInfo.profileFile != null
7432                            || mProfilerInfo.attachAgentDuringBind;
7433                    profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7434                    if (mProfilerInfo.agent != null) {
7435                        preBindAgent = mProfilerInfo.agent;
7436                    }
7437                }
7438            } else if (app.instr != null && app.instr.mProfileFile != null) {
7439                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7440                        null, false);
7441            }
7442            if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7443                // We need to do a debuggable check here. See setAgentApp for why the check is
7444                // postponed to here.
7445                if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7446                    String agent = mAppAgentMap.get(processName);
7447                    // Do not overwrite already requested agent.
7448                    if (profilerInfo == null) {
7449                        profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7450                                mAppAgentMap.get(processName), true);
7451                    } else if (profilerInfo.agent == null) {
7452                        profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7453                    }
7454                }
7455            }
7456
7457            if (profilerInfo != null && profilerInfo.profileFd != null) {
7458                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7459            }
7460
7461            // We deprecated Build.SERIAL and it is not accessible to
7462            // apps that target the v2 security sandbox and to apps that
7463            // target APIs higher than O MR1. Since access to the serial
7464            // is now behind a permission we push down the value.
7465            final String buildSerial = (appInfo.targetSandboxVersion < 2
7466                    && appInfo.targetSdkVersion <= Build.VERSION_CODES.O_MR1)
7467                            ? sTheRealBuildSerial : Build.UNKNOWN;
7468
7469            // Check if this is a secondary process that should be incorporated into some
7470            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7471            // stuff above because profiling can currently happen only in the primary
7472            // instrumentation process.)
7473            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7474                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7475                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7476                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7477                        if (aInstr.mTargetProcesses.length == 0) {
7478                            // This is the wildcard mode, where every process brought up for
7479                            // the target instrumentation should be included.
7480                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7481                                app.instr = aInstr;
7482                                aInstr.mRunningProcesses.add(app);
7483                            }
7484                        } else {
7485                            for (String proc : aInstr.mTargetProcesses) {
7486                                if (proc.equals(app.processName)) {
7487                                    app.instr = aInstr;
7488                                    aInstr.mRunningProcesses.add(app);
7489                                    break;
7490                                }
7491                            }
7492                        }
7493                    }
7494                }
7495            }
7496
7497            // If we were asked to attach an agent on startup, do so now, before we're binding
7498            // application code.
7499            if (preBindAgent != null) {
7500                thread.attachAgent(preBindAgent);
7501            }
7502
7503
7504            // Figure out whether the app needs to run in autofill compat mode.
7505            boolean isAutofillCompatEnabled = false;
7506            if (UserHandle.getAppId(app.info.uid) >= Process.FIRST_APPLICATION_UID) {
7507                final AutofillManagerInternal afm = LocalServices.getService(
7508                        AutofillManagerInternal.class);
7509                if (afm != null) {
7510                    isAutofillCompatEnabled = afm.isCompatibilityModeRequested(
7511                            app.info.packageName, app.info.versionCode, app.userId);
7512                }
7513            }
7514
7515            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7516            mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7517            if (app.isolatedEntryPoint != null) {
7518                // This is an isolated process which should just call an entry point instead of
7519                // being bound to an application.
7520                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7521            } else if (app.instr != null) {
7522                thread.bindApplication(processName, appInfo, providers,
7523                        app.instr.mClass,
7524                        profilerInfo, app.instr.mArguments,
7525                        app.instr.mWatcher,
7526                        app.instr.mUiAutomationConnection, testMode,
7527                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7528                        isRestrictedBackupMode || !normalMode, app.persistent,
7529                        new Configuration(getGlobalConfiguration()), app.compat,
7530                        getCommonServicesLocked(app.isolated),
7531                        mCoreSettingsObserver.getCoreSettingsLocked(),
7532                        buildSerial, isAutofillCompatEnabled);
7533            } else {
7534                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7535                        null, null, null, testMode,
7536                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7537                        isRestrictedBackupMode || !normalMode, app.persistent,
7538                        new Configuration(getGlobalConfiguration()), app.compat,
7539                        getCommonServicesLocked(app.isolated),
7540                        mCoreSettingsObserver.getCoreSettingsLocked(),
7541                        buildSerial, isAutofillCompatEnabled);
7542            }
7543
7544            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7545            updateLruProcessLocked(app, false, null);
7546            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7547            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7548        } catch (Exception e) {
7549            // todo: Yikes!  What should we do?  For now we will try to
7550            // start another process, but that could easily get us in
7551            // an infinite loop of restarting processes...
7552            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7553
7554            app.resetPackageList(mProcessStats);
7555            app.unlinkDeathRecipient();
7556            startProcessLocked(app, "bind fail", processName);
7557            return false;
7558        }
7559
7560        // Remove this record from the list of starting applications.
7561        mPersistentStartingProcesses.remove(app);
7562        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7563                "Attach application locked removing on hold: " + app);
7564        mProcessesOnHold.remove(app);
7565
7566        boolean badApp = false;
7567        boolean didSomething = false;
7568
7569        // See if the top visible activity is waiting to run in this process...
7570        if (normalMode) {
7571            try {
7572                if (mStackSupervisor.attachApplicationLocked(app)) {
7573                    didSomething = true;
7574                }
7575            } catch (Exception e) {
7576                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7577                badApp = true;
7578            }
7579        }
7580
7581        // Find any services that should be running in this process...
7582        if (!badApp) {
7583            try {
7584                didSomething |= mServices.attachApplicationLocked(app, processName);
7585                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7586            } catch (Exception e) {
7587                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7588                badApp = true;
7589            }
7590        }
7591
7592        // Check if a next-broadcast receiver is in this process...
7593        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7594            try {
7595                didSomething |= sendPendingBroadcastsLocked(app);
7596                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7597            } catch (Exception e) {
7598                // If the app died trying to launch the receiver we declare it 'bad'
7599                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7600                badApp = true;
7601            }
7602        }
7603
7604        // Check whether the next backup agent is in this process...
7605        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7606            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7607                    "New app is backup target, launching agent for " + app);
7608            notifyPackageUse(mBackupTarget.appInfo.packageName,
7609                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7610            try {
7611                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7612                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7613                        mBackupTarget.backupMode);
7614            } catch (Exception e) {
7615                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7616                badApp = true;
7617            }
7618        }
7619
7620        if (badApp) {
7621            app.kill("error during init", true);
7622            handleAppDiedLocked(app, false, true);
7623            return false;
7624        }
7625
7626        if (!didSomething) {
7627            updateOomAdjLocked();
7628            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7629        }
7630
7631        return true;
7632    }
7633
7634    @Override
7635    public final void attachApplication(IApplicationThread thread, long startSeq) {
7636        synchronized (this) {
7637            int callingPid = Binder.getCallingPid();
7638            final int callingUid = Binder.getCallingUid();
7639            final long origId = Binder.clearCallingIdentity();
7640            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7641            Binder.restoreCallingIdentity(origId);
7642        }
7643    }
7644
7645    @Override
7646    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7647        final long origId = Binder.clearCallingIdentity();
7648        synchronized (this) {
7649            ActivityStack stack = ActivityRecord.getStackLocked(token);
7650            if (stack != null) {
7651                ActivityRecord r =
7652                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7653                                false /* processPausingActivities */, config);
7654                if (stopProfiling) {
7655                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7656                        clearProfilerLocked();
7657                    }
7658                }
7659            }
7660        }
7661        Binder.restoreCallingIdentity(origId);
7662    }
7663
7664    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7665        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7666                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7667    }
7668
7669    void enableScreenAfterBoot() {
7670        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7671                SystemClock.uptimeMillis());
7672        mWindowManager.enableScreenAfterBoot();
7673
7674        synchronized (this) {
7675            updateEventDispatchingLocked();
7676        }
7677    }
7678
7679    @Override
7680    public void showBootMessage(final CharSequence msg, final boolean always) {
7681        if (Binder.getCallingUid() != myUid()) {
7682            throw new SecurityException();
7683        }
7684        mWindowManager.showBootMessage(msg, always);
7685    }
7686
7687    @Override
7688    public void keyguardGoingAway(int flags) {
7689        enforceNotIsolatedCaller("keyguardGoingAway");
7690        final long token = Binder.clearCallingIdentity();
7691        try {
7692            synchronized (this) {
7693                mKeyguardController.keyguardGoingAway(flags);
7694            }
7695        } finally {
7696            Binder.restoreCallingIdentity(token);
7697        }
7698    }
7699
7700    /**
7701     * @return whther the keyguard is currently locked.
7702     */
7703    boolean isKeyguardLocked() {
7704        return mKeyguardController.isKeyguardLocked();
7705    }
7706
7707    final void finishBooting() {
7708        synchronized (this) {
7709            if (!mBootAnimationComplete) {
7710                mCallFinishBooting = true;
7711                return;
7712            }
7713            mCallFinishBooting = false;
7714        }
7715
7716        ArraySet<String> completedIsas = new ArraySet<String>();
7717        for (String abi : Build.SUPPORTED_ABIS) {
7718            zygoteProcess.establishZygoteConnectionForAbi(abi);
7719            final String instructionSet = VMRuntime.getInstructionSet(abi);
7720            if (!completedIsas.contains(instructionSet)) {
7721                try {
7722                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7723                } catch (InstallerException e) {
7724                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7725                            e.getMessage() +")");
7726                }
7727                completedIsas.add(instructionSet);
7728            }
7729        }
7730
7731        IntentFilter pkgFilter = new IntentFilter();
7732        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7733        pkgFilter.addDataScheme("package");
7734        mContext.registerReceiver(new BroadcastReceiver() {
7735            @Override
7736            public void onReceive(Context context, Intent intent) {
7737                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7738                if (pkgs != null) {
7739                    for (String pkg : pkgs) {
7740                        synchronized (ActivityManagerService.this) {
7741                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7742                                    0, "query restart")) {
7743                                setResultCode(Activity.RESULT_OK);
7744                                return;
7745                            }
7746                        }
7747                    }
7748                }
7749            }
7750        }, pkgFilter);
7751
7752        IntentFilter dumpheapFilter = new IntentFilter();
7753        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7754        mContext.registerReceiver(new BroadcastReceiver() {
7755            @Override
7756            public void onReceive(Context context, Intent intent) {
7757                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7758                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7759                } else {
7760                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7761                }
7762            }
7763        }, dumpheapFilter);
7764
7765        // Let system services know.
7766        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7767
7768        synchronized (this) {
7769            // Ensure that any processes we had put on hold are now started
7770            // up.
7771            final int NP = mProcessesOnHold.size();
7772            if (NP > 0) {
7773                ArrayList<ProcessRecord> procs =
7774                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7775                for (int ip=0; ip<NP; ip++) {
7776                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7777                            + procs.get(ip));
7778                    startProcessLocked(procs.get(ip), "on-hold", null);
7779                }
7780            }
7781            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7782                return;
7783            }
7784            // Start looking for apps that are abusing wake locks.
7785            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7786            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7787            // Tell anyone interested that we are done booting!
7788            SystemProperties.set("sys.boot_completed", "1");
7789
7790            // And trigger dev.bootcomplete if we are not showing encryption progress
7791            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7792                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7793                SystemProperties.set("dev.bootcomplete", "1");
7794            }
7795            mUserController.sendBootCompleted(
7796                    new IIntentReceiver.Stub() {
7797                        @Override
7798                        public void performReceive(Intent intent, int resultCode,
7799                                String data, Bundle extras, boolean ordered,
7800                                boolean sticky, int sendingUser) {
7801                            synchronized (ActivityManagerService.this) {
7802                                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
7803                            }
7804                        }
7805                    });
7806            mUserController.scheduleStartProfiles();
7807        }
7808    }
7809
7810    @Override
7811    public void bootAnimationComplete() {
7812        final boolean callFinishBooting;
7813        synchronized (this) {
7814            callFinishBooting = mCallFinishBooting;
7815            mBootAnimationComplete = true;
7816        }
7817        if (callFinishBooting) {
7818            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7819            finishBooting();
7820            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7821        }
7822    }
7823
7824    final void ensureBootCompleted() {
7825        boolean booting;
7826        boolean enableScreen;
7827        synchronized (this) {
7828            booting = mBooting;
7829            mBooting = false;
7830            enableScreen = !mBooted;
7831            mBooted = true;
7832        }
7833
7834        if (booting) {
7835            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7836            finishBooting();
7837            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7838        }
7839
7840        if (enableScreen) {
7841            enableScreenAfterBoot();
7842        }
7843    }
7844
7845    @Override
7846    public final void activityResumed(IBinder token) {
7847        final long origId = Binder.clearCallingIdentity();
7848        synchronized(this) {
7849            ActivityRecord.activityResumedLocked(token);
7850            mWindowManager.notifyAppResumedFinished(token);
7851        }
7852        Binder.restoreCallingIdentity(origId);
7853    }
7854
7855    @Override
7856    public final void activityPaused(IBinder token) {
7857        final long origId = Binder.clearCallingIdentity();
7858        synchronized(this) {
7859            ActivityStack stack = ActivityRecord.getStackLocked(token);
7860            if (stack != null) {
7861                stack.activityPausedLocked(token, false);
7862            }
7863        }
7864        Binder.restoreCallingIdentity(origId);
7865    }
7866
7867    @Override
7868    public final void activityStopped(IBinder token, Bundle icicle,
7869            PersistableBundle persistentState, CharSequence description) {
7870        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7871
7872        // Refuse possible leaked file descriptors
7873        if (icicle != null && icicle.hasFileDescriptors()) {
7874            throw new IllegalArgumentException("File descriptors passed in Bundle");
7875        }
7876
7877        final long origId = Binder.clearCallingIdentity();
7878
7879        synchronized (this) {
7880            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7881            if (r != null) {
7882                r.activityStoppedLocked(icicle, persistentState, description);
7883            }
7884        }
7885
7886        trimApplications();
7887
7888        Binder.restoreCallingIdentity(origId);
7889    }
7890
7891    @Override
7892    public final void activityDestroyed(IBinder token) {
7893        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7894        synchronized (this) {
7895            ActivityStack stack = ActivityRecord.getStackLocked(token);
7896            if (stack != null) {
7897                stack.activityDestroyedLocked(token, "activityDestroyed");
7898            }
7899        }
7900    }
7901
7902    @Override
7903    public final void activityRelaunched(IBinder token) {
7904        final long origId = Binder.clearCallingIdentity();
7905        synchronized (this) {
7906            mStackSupervisor.activityRelaunchedLocked(token);
7907        }
7908        Binder.restoreCallingIdentity(origId);
7909    }
7910
7911    @Override
7912    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7913            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7914        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7915                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7916        synchronized (this) {
7917            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7918            if (record == null) {
7919                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7920                        + "found for: " + token);
7921            }
7922            record.setSizeConfigurations(horizontalSizeConfiguration,
7923                    verticalSizeConfigurations, smallestSizeConfigurations);
7924        }
7925    }
7926
7927    @Override
7928    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7929        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7930    }
7931
7932    @Override
7933    public final void notifyEnterAnimationComplete(IBinder token) {
7934        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7935    }
7936
7937    @Override
7938    public String getCallingPackage(IBinder token) {
7939        synchronized (this) {
7940            ActivityRecord r = getCallingRecordLocked(token);
7941            return r != null ? r.info.packageName : null;
7942        }
7943    }
7944
7945    @Override
7946    public ComponentName getCallingActivity(IBinder token) {
7947        synchronized (this) {
7948            ActivityRecord r = getCallingRecordLocked(token);
7949            return r != null ? r.intent.getComponent() : null;
7950        }
7951    }
7952
7953    private ActivityRecord getCallingRecordLocked(IBinder token) {
7954        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7955        if (r == null) {
7956            return null;
7957        }
7958        return r.resultTo;
7959    }
7960
7961    @Override
7962    public ComponentName getActivityClassForToken(IBinder token) {
7963        synchronized(this) {
7964            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7965            if (r == null) {
7966                return null;
7967            }
7968            return r.intent.getComponent();
7969        }
7970    }
7971
7972    @Override
7973    public String getPackageForToken(IBinder token) {
7974        synchronized(this) {
7975            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7976            if (r == null) {
7977                return null;
7978            }
7979            return r.packageName;
7980        }
7981    }
7982
7983    @Override
7984    public boolean isRootVoiceInteraction(IBinder token) {
7985        synchronized(this) {
7986            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7987            if (r == null) {
7988                return false;
7989            }
7990            return r.rootVoiceInteraction;
7991        }
7992    }
7993
7994    @Override
7995    public IIntentSender getIntentSender(int type,
7996            String packageName, IBinder token, String resultWho,
7997            int requestCode, Intent[] intents, String[] resolvedTypes,
7998            int flags, Bundle bOptions, int userId) {
7999        enforceNotIsolatedCaller("getIntentSender");
8000        // Refuse possible leaked file descriptors
8001        if (intents != null) {
8002            if (intents.length < 1) {
8003                throw new IllegalArgumentException("Intents array length must be >= 1");
8004            }
8005            for (int i=0; i<intents.length; i++) {
8006                Intent intent = intents[i];
8007                if (intent != null) {
8008                    if (intent.hasFileDescriptors()) {
8009                        throw new IllegalArgumentException("File descriptors passed in Intent");
8010                    }
8011                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
8012                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
8013                        throw new IllegalArgumentException(
8014                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
8015                    }
8016                    intents[i] = new Intent(intent);
8017                }
8018            }
8019            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
8020                throw new IllegalArgumentException(
8021                        "Intent array length does not match resolvedTypes length");
8022            }
8023        }
8024        if (bOptions != null) {
8025            if (bOptions.hasFileDescriptors()) {
8026                throw new IllegalArgumentException("File descriptors passed in options");
8027            }
8028        }
8029
8030        synchronized(this) {
8031            int callingUid = Binder.getCallingUid();
8032            int origUserId = userId;
8033            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8034                    type == ActivityManager.INTENT_SENDER_BROADCAST,
8035                    ALLOW_NON_FULL, "getIntentSender", null);
8036            if (origUserId == UserHandle.USER_CURRENT) {
8037                // We don't want to evaluate this until the pending intent is
8038                // actually executed.  However, we do want to always do the
8039                // security checking for it above.
8040                userId = UserHandle.USER_CURRENT;
8041            }
8042            try {
8043                if (callingUid != 0 && callingUid != SYSTEM_UID) {
8044                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
8045                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
8046                    if (!UserHandle.isSameApp(callingUid, uid)) {
8047                        String msg = "Permission Denial: getIntentSender() from pid="
8048                            + Binder.getCallingPid()
8049                            + ", uid=" + Binder.getCallingUid()
8050                            + ", (need uid=" + uid + ")"
8051                            + " is not allowed to send as package " + packageName;
8052                        Slog.w(TAG, msg);
8053                        throw new SecurityException(msg);
8054                    }
8055                }
8056
8057                return getIntentSenderLocked(type, packageName, callingUid, userId,
8058                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
8059
8060            } catch (RemoteException e) {
8061                throw new SecurityException(e);
8062            }
8063        }
8064    }
8065
8066    IIntentSender getIntentSenderLocked(int type, String packageName,
8067            int callingUid, int userId, IBinder token, String resultWho,
8068            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
8069            Bundle bOptions) {
8070        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
8071        ActivityRecord activity = null;
8072        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8073            activity = ActivityRecord.isInStackLocked(token);
8074            if (activity == null) {
8075                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
8076                return null;
8077            }
8078            if (activity.finishing) {
8079                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
8080                return null;
8081            }
8082        }
8083
8084        // We're going to be splicing together extras before sending, so we're
8085        // okay poking into any contained extras.
8086        if (intents != null) {
8087            for (int i = 0; i < intents.length; i++) {
8088                intents[i].setDefusable(true);
8089            }
8090        }
8091        Bundle.setDefusable(bOptions, true);
8092
8093        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
8094        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
8095        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
8096        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
8097                |PendingIntent.FLAG_UPDATE_CURRENT);
8098
8099        PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
8100                resultWho, requestCode, intents, resolvedTypes, flags,
8101                SafeActivityOptions.fromBundle(bOptions), userId);
8102        WeakReference<PendingIntentRecord> ref;
8103        ref = mIntentSenderRecords.get(key);
8104        PendingIntentRecord rec = ref != null ? ref.get() : null;
8105        if (rec != null) {
8106            if (!cancelCurrent) {
8107                if (updateCurrent) {
8108                    if (rec.key.requestIntent != null) {
8109                        rec.key.requestIntent.replaceExtras(intents != null ?
8110                                intents[intents.length - 1] : null);
8111                    }
8112                    if (intents != null) {
8113                        intents[intents.length-1] = rec.key.requestIntent;
8114                        rec.key.allIntents = intents;
8115                        rec.key.allResolvedTypes = resolvedTypes;
8116                    } else {
8117                        rec.key.allIntents = null;
8118                        rec.key.allResolvedTypes = null;
8119                    }
8120                }
8121                return rec;
8122            }
8123            makeIntentSenderCanceledLocked(rec);
8124            mIntentSenderRecords.remove(key);
8125        }
8126        if (noCreate) {
8127            return rec;
8128        }
8129        rec = new PendingIntentRecord(this, key, callingUid);
8130        mIntentSenderRecords.put(key, rec.ref);
8131        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8132            if (activity.pendingResults == null) {
8133                activity.pendingResults
8134                        = new HashSet<WeakReference<PendingIntentRecord>>();
8135            }
8136            activity.pendingResults.add(rec.ref);
8137        }
8138        return rec;
8139    }
8140
8141    @Override
8142    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
8143            Intent intent, String resolvedType,
8144            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
8145        if (target instanceof PendingIntentRecord) {
8146            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
8147                    whitelistToken, finishedReceiver, requiredPermission, options);
8148        } else {
8149            if (intent == null) {
8150                // Weird case: someone has given us their own custom IIntentSender, and now
8151                // they have someone else trying to send to it but of course this isn't
8152                // really a PendingIntent, so there is no base Intent, and the caller isn't
8153                // supplying an Intent... but we never want to dispatch a null Intent to
8154                // a receiver, so um...  let's make something up.
8155                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
8156                intent = new Intent(Intent.ACTION_MAIN);
8157            }
8158            try {
8159                target.send(code, intent, resolvedType, whitelistToken, null,
8160                        requiredPermission, options);
8161            } catch (RemoteException e) {
8162            }
8163            // Platform code can rely on getting a result back when the send is done, but if
8164            // this intent sender is from outside of the system we can't rely on it doing that.
8165            // So instead we don't give it the result receiver, and instead just directly
8166            // report the finish immediately.
8167            if (finishedReceiver != null) {
8168                try {
8169                    finishedReceiver.performReceive(intent, 0,
8170                            null, null, false, false, UserHandle.getCallingUserId());
8171                } catch (RemoteException e) {
8172                }
8173            }
8174            return 0;
8175        }
8176    }
8177
8178    @Override
8179    public void cancelIntentSender(IIntentSender sender) {
8180        if (!(sender instanceof PendingIntentRecord)) {
8181            return;
8182        }
8183        synchronized(this) {
8184            PendingIntentRecord rec = (PendingIntentRecord)sender;
8185            try {
8186                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8187                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8188                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8189                    String msg = "Permission Denial: cancelIntentSender() from pid="
8190                        + Binder.getCallingPid()
8191                        + ", uid=" + Binder.getCallingUid()
8192                        + " is not allowed to cancel package "
8193                        + rec.key.packageName;
8194                    Slog.w(TAG, msg);
8195                    throw new SecurityException(msg);
8196                }
8197            } catch (RemoteException e) {
8198                throw new SecurityException(e);
8199            }
8200            cancelIntentSenderLocked(rec, true);
8201        }
8202    }
8203
8204    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8205        makeIntentSenderCanceledLocked(rec);
8206        mIntentSenderRecords.remove(rec.key);
8207        if (cleanActivity && rec.key.activity != null) {
8208            rec.key.activity.pendingResults.remove(rec.ref);
8209        }
8210    }
8211
8212    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8213        rec.canceled = true;
8214        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8215        if (callbacks != null) {
8216            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8217        }
8218    }
8219
8220    @Override
8221    public String getPackageForIntentSender(IIntentSender pendingResult) {
8222        if (!(pendingResult instanceof PendingIntentRecord)) {
8223            return null;
8224        }
8225        try {
8226            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8227            return res.key.packageName;
8228        } catch (ClassCastException e) {
8229        }
8230        return null;
8231    }
8232
8233    @Override
8234    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8235        if (!(sender instanceof PendingIntentRecord)) {
8236            return;
8237        }
8238        synchronized(this) {
8239            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
8240        }
8241    }
8242
8243    @Override
8244    public void unregisterIntentSenderCancelListener(IIntentSender sender,
8245            IResultReceiver receiver) {
8246        if (!(sender instanceof PendingIntentRecord)) {
8247            return;
8248        }
8249        synchronized(this) {
8250            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8251        }
8252    }
8253
8254    @Override
8255    public int getUidForIntentSender(IIntentSender sender) {
8256        if (sender instanceof PendingIntentRecord) {
8257            try {
8258                PendingIntentRecord res = (PendingIntentRecord)sender;
8259                return res.uid;
8260            } catch (ClassCastException e) {
8261            }
8262        }
8263        return -1;
8264    }
8265
8266    @Override
8267    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8268        if (!(pendingResult instanceof PendingIntentRecord)) {
8269            return false;
8270        }
8271        try {
8272            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8273            if (res.key.allIntents == null) {
8274                return false;
8275            }
8276            for (int i=0; i<res.key.allIntents.length; i++) {
8277                Intent intent = res.key.allIntents[i];
8278                if (intent.getPackage() != null && intent.getComponent() != null) {
8279                    return false;
8280                }
8281            }
8282            return true;
8283        } catch (ClassCastException e) {
8284        }
8285        return false;
8286    }
8287
8288    @Override
8289    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8290        if (!(pendingResult instanceof PendingIntentRecord)) {
8291            return false;
8292        }
8293        try {
8294            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8295            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8296                return true;
8297            }
8298            return false;
8299        } catch (ClassCastException e) {
8300        }
8301        return false;
8302    }
8303
8304    @Override
8305    public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8306        if (pendingResult instanceof PendingIntentRecord) {
8307            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8308            return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8309        }
8310        return false;
8311    }
8312
8313    @Override
8314    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8315        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8316                "getIntentForIntentSender()");
8317        if (!(pendingResult instanceof PendingIntentRecord)) {
8318            return null;
8319        }
8320        try {
8321            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8322            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8323        } catch (ClassCastException e) {
8324        }
8325        return null;
8326    }
8327
8328    @Override
8329    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8330        if (!(pendingResult instanceof PendingIntentRecord)) {
8331            return null;
8332        }
8333        try {
8334            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8335            synchronized (this) {
8336                return getTagForIntentSenderLocked(res, prefix);
8337            }
8338        } catch (ClassCastException e) {
8339        }
8340        return null;
8341    }
8342
8343    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8344        final Intent intent = res.key.requestIntent;
8345        if (intent != null) {
8346            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8347                    || res.lastTagPrefix.equals(prefix))) {
8348                return res.lastTag;
8349            }
8350            res.lastTagPrefix = prefix;
8351            final StringBuilder sb = new StringBuilder(128);
8352            if (prefix != null) {
8353                sb.append(prefix);
8354            }
8355            if (intent.getAction() != null) {
8356                sb.append(intent.getAction());
8357            } else if (intent.getComponent() != null) {
8358                intent.getComponent().appendShortString(sb);
8359            } else {
8360                sb.append("?");
8361            }
8362            return res.lastTag = sb.toString();
8363        }
8364        return null;
8365    }
8366
8367    @Override
8368    public void setProcessLimit(int max) {
8369        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8370                "setProcessLimit()");
8371        synchronized (this) {
8372            mConstants.setOverrideMaxCachedProcesses(max);
8373        }
8374        trimApplications();
8375    }
8376
8377    @Override
8378    public int getProcessLimit() {
8379        synchronized (this) {
8380            return mConstants.getOverrideMaxCachedProcesses();
8381        }
8382    }
8383
8384    void importanceTokenDied(ImportanceToken token) {
8385        synchronized (ActivityManagerService.this) {
8386            synchronized (mPidsSelfLocked) {
8387                ImportanceToken cur
8388                    = mImportantProcesses.get(token.pid);
8389                if (cur != token) {
8390                    return;
8391                }
8392                mImportantProcesses.remove(token.pid);
8393                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8394                if (pr == null) {
8395                    return;
8396                }
8397                pr.forcingToImportant = null;
8398                updateProcessForegroundLocked(pr, false, false);
8399            }
8400            updateOomAdjLocked();
8401        }
8402    }
8403
8404    @Override
8405    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8406        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8407                "setProcessImportant()");
8408        synchronized(this) {
8409            boolean changed = false;
8410
8411            synchronized (mPidsSelfLocked) {
8412                ProcessRecord pr = mPidsSelfLocked.get(pid);
8413                if (pr == null && isForeground) {
8414                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8415                    return;
8416                }
8417                ImportanceToken oldToken = mImportantProcesses.get(pid);
8418                if (oldToken != null) {
8419                    oldToken.token.unlinkToDeath(oldToken, 0);
8420                    mImportantProcesses.remove(pid);
8421                    if (pr != null) {
8422                        pr.forcingToImportant = null;
8423                    }
8424                    changed = true;
8425                }
8426                if (isForeground && token != null) {
8427                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8428                        @Override
8429                        public void binderDied() {
8430                            importanceTokenDied(this);
8431                        }
8432                    };
8433                    try {
8434                        token.linkToDeath(newToken, 0);
8435                        mImportantProcesses.put(pid, newToken);
8436                        pr.forcingToImportant = newToken;
8437                        changed = true;
8438                    } catch (RemoteException e) {
8439                        // If the process died while doing this, we will later
8440                        // do the cleanup with the process death link.
8441                    }
8442                }
8443            }
8444
8445            if (changed) {
8446                updateOomAdjLocked();
8447            }
8448        }
8449    }
8450
8451    @Override
8452    public boolean isAppForeground(int uid) throws RemoteException {
8453        synchronized (this) {
8454            UidRecord uidRec = mActiveUids.get(uid);
8455            if (uidRec == null || uidRec.idle) {
8456                return false;
8457            }
8458            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8459        }
8460    }
8461
8462    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8463    // be guarded by permission checking.
8464    int getUidState(int uid) {
8465        synchronized (this) {
8466            return getUidStateLocked(uid);
8467        }
8468    }
8469
8470    int getUidStateLocked(int uid) {
8471        UidRecord uidRec = mActiveUids.get(uid);
8472        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8473    }
8474
8475    @Override
8476    public boolean isInMultiWindowMode(IBinder token) {
8477        final long origId = Binder.clearCallingIdentity();
8478        try {
8479            synchronized(this) {
8480                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8481                if (r == null) {
8482                    return false;
8483                }
8484                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8485                return r.inMultiWindowMode();
8486            }
8487        } finally {
8488            Binder.restoreCallingIdentity(origId);
8489        }
8490    }
8491
8492    @Override
8493    public boolean isInPictureInPictureMode(IBinder token) {
8494        final long origId = Binder.clearCallingIdentity();
8495        try {
8496            synchronized(this) {
8497                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8498            }
8499        } finally {
8500            Binder.restoreCallingIdentity(origId);
8501        }
8502    }
8503
8504    private boolean isInPictureInPictureMode(ActivityRecord r) {
8505        if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8506                || r.getStack().isInStackLocked(r) == null) {
8507            return false;
8508        }
8509
8510        // If we are animating to fullscreen then we have already dispatched the PIP mode
8511        // changed, so we should reflect that check here as well.
8512        final PinnedActivityStack stack = r.getStack();
8513        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8514        return !windowController.isAnimatingBoundsToFullscreen();
8515    }
8516
8517    @Override
8518    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8519        final long origId = Binder.clearCallingIdentity();
8520        try {
8521            synchronized(this) {
8522                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8523                        "enterPictureInPictureMode", token, params);
8524
8525                // If the activity is already in picture in picture mode, then just return early
8526                if (isInPictureInPictureMode(r)) {
8527                    return true;
8528                }
8529
8530                // Activity supports picture-in-picture, now check that we can enter PiP at this
8531                // point, if it is
8532                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8533                        false /* beforeStopping */)) {
8534                    return false;
8535                }
8536
8537                final Runnable enterPipRunnable = () -> {
8538                    // Only update the saved args from the args that are set
8539                    r.pictureInPictureArgs.copyOnlySet(params);
8540                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8541                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8542                    // Adjust the source bounds by the insets for the transition down
8543                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8544                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8545                            "enterPictureInPictureMode");
8546                    final PinnedActivityStack stack = r.getStack();
8547                    stack.setPictureInPictureAspectRatio(aspectRatio);
8548                    stack.setPictureInPictureActions(actions);
8549
8550                    MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.supportsEnterPipOnTaskSwitch);
8551                    logPictureInPictureArgs(params);
8552                };
8553
8554                if (isKeyguardLocked()) {
8555                    // If the keyguard is showing or occluded, then try and dismiss it before
8556                    // entering picture-in-picture (this will prompt the user to authenticate if the
8557                    // device is currently locked).
8558                    try {
8559                        dismissKeyguard(token, new KeyguardDismissCallback() {
8560                            @Override
8561                            public void onDismissSucceeded() throws RemoteException {
8562                                mHandler.post(enterPipRunnable);
8563                            }
8564                        }, null /* message */);
8565                    } catch (RemoteException e) {
8566                        // Local call
8567                    }
8568                } else {
8569                    // Enter picture in picture immediately otherwise
8570                    enterPipRunnable.run();
8571                }
8572                return true;
8573            }
8574        } finally {
8575            Binder.restoreCallingIdentity(origId);
8576        }
8577    }
8578
8579    @Override
8580    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8581        final long origId = Binder.clearCallingIdentity();
8582        try {
8583            synchronized(this) {
8584                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8585                        "setPictureInPictureParams", token, params);
8586
8587                // Only update the saved args from the args that are set
8588                r.pictureInPictureArgs.copyOnlySet(params);
8589                if (r.inPinnedWindowingMode()) {
8590                    // If the activity is already in picture-in-picture, update the pinned stack now
8591                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8592                    // be used the next time the activity enters PiP
8593                    final PinnedActivityStack stack = r.getStack();
8594                    if (!stack.isAnimatingBoundsToFullscreen()) {
8595                        stack.setPictureInPictureAspectRatio(
8596                                r.pictureInPictureArgs.getAspectRatio());
8597                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8598                    }
8599                }
8600                logPictureInPictureArgs(params);
8601            }
8602        } finally {
8603            Binder.restoreCallingIdentity(origId);
8604        }
8605    }
8606
8607    @Override
8608    public int getMaxNumPictureInPictureActions(IBinder token) {
8609        // Currently, this is a static constant, but later, we may change this to be dependent on
8610        // the context of the activity
8611        return 3;
8612    }
8613
8614    private void logPictureInPictureArgs(PictureInPictureParams params) {
8615        if (params.hasSetActions()) {
8616            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8617                    params.getActions().size());
8618        }
8619        if (params.hasSetAspectRatio()) {
8620            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8621            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8622            MetricsLogger.action(lm);
8623        }
8624    }
8625
8626    /**
8627     * Checks the state of the system and the activity associated with the given {@param token} to
8628     * verify that picture-in-picture is supported for that activity.
8629     *
8630     * @return the activity record for the given {@param token} if all the checks pass.
8631     */
8632    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8633            IBinder token, PictureInPictureParams params) {
8634        if (!mSupportsPictureInPicture) {
8635            throw new IllegalStateException(caller
8636                    + ": Device doesn't support picture-in-picture mode.");
8637        }
8638
8639        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8640        if (r == null) {
8641            throw new IllegalStateException(caller
8642                    + ": Can't find activity for token=" + token);
8643        }
8644
8645        if (!r.supportsPictureInPicture()) {
8646            throw new IllegalStateException(caller
8647                    + ": Current activity does not support picture-in-picture.");
8648        }
8649
8650        if (params.hasSetAspectRatio()
8651                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8652                        params.getAspectRatio())) {
8653            final float minAspectRatio = mContext.getResources().getFloat(
8654                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8655            final float maxAspectRatio = mContext.getResources().getFloat(
8656                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8657            throw new IllegalArgumentException(String.format(caller
8658                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8659                            minAspectRatio, maxAspectRatio));
8660        }
8661
8662        // Truncate the number of actions if necessary
8663        params.truncateActions(getMaxNumPictureInPictureActions(token));
8664
8665        return r;
8666    }
8667
8668    // =========================================================
8669    // PROCESS INFO
8670    // =========================================================
8671
8672    static class ProcessInfoService extends IProcessInfoService.Stub {
8673        final ActivityManagerService mActivityManagerService;
8674        ProcessInfoService(ActivityManagerService activityManagerService) {
8675            mActivityManagerService = activityManagerService;
8676        }
8677
8678        @Override
8679        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8680            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8681                    /*in*/ pids, /*out*/ states, null);
8682        }
8683
8684        @Override
8685        public void getProcessStatesAndOomScoresFromPids(
8686                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8687            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8688                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8689        }
8690    }
8691
8692    /**
8693     * For each PID in the given input array, write the current process state
8694     * for that process into the states array, or -1 to indicate that no
8695     * process with the given PID exists. If scores array is provided, write
8696     * the oom score for the process into the scores array, with INVALID_ADJ
8697     * indicating the PID doesn't exist.
8698     */
8699    public void getProcessStatesAndOomScoresForPIDs(
8700            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8701        if (scores != null) {
8702            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8703                    "getProcessStatesAndOomScoresForPIDs()");
8704        }
8705
8706        if (pids == null) {
8707            throw new NullPointerException("pids");
8708        } else if (states == null) {
8709            throw new NullPointerException("states");
8710        } else if (pids.length != states.length) {
8711            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8712        } else if (scores != null && pids.length != scores.length) {
8713            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8714        }
8715
8716        synchronized (mPidsSelfLocked) {
8717            for (int i = 0; i < pids.length; i++) {
8718                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8719                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8720                        pr.curProcState;
8721                if (scores != null) {
8722                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8723                }
8724            }
8725        }
8726    }
8727
8728    // =========================================================
8729    // PERMISSIONS
8730    // =========================================================
8731
8732    static class PermissionController extends IPermissionController.Stub {
8733        ActivityManagerService mActivityManagerService;
8734        PermissionController(ActivityManagerService activityManagerService) {
8735            mActivityManagerService = activityManagerService;
8736        }
8737
8738        @Override
8739        public boolean checkPermission(String permission, int pid, int uid) {
8740            return mActivityManagerService.checkPermission(permission, pid,
8741                    uid) == PackageManager.PERMISSION_GRANTED;
8742        }
8743
8744        @Override
8745        public String[] getPackagesForUid(int uid) {
8746            return mActivityManagerService.mContext.getPackageManager()
8747                    .getPackagesForUid(uid);
8748        }
8749
8750        @Override
8751        public boolean isRuntimePermission(String permission) {
8752            try {
8753                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8754                        .getPermissionInfo(permission, 0);
8755                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8756                        == PermissionInfo.PROTECTION_DANGEROUS;
8757            } catch (NameNotFoundException nnfe) {
8758                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8759            }
8760            return false;
8761        }
8762
8763        @Override
8764        public int getPackageUid(String packageName, int flags) {
8765            try {
8766                return mActivityManagerService.mContext.getPackageManager()
8767                        .getPackageUid(packageName, flags);
8768            } catch (NameNotFoundException nnfe) {
8769                return -1;
8770            }
8771        }
8772    }
8773
8774    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8775        @Override
8776        public int checkComponentPermission(String permission, int pid, int uid,
8777                int owningUid, boolean exported) {
8778            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8779                    owningUid, exported);
8780        }
8781
8782        @Override
8783        public Object getAMSLock() {
8784            return ActivityManagerService.this;
8785        }
8786    }
8787
8788    int checkComponentPermission(String permission, int pid, int uid,
8789            int owningUid, boolean exported) {
8790        if (pid == MY_PID) {
8791            return PackageManager.PERMISSION_GRANTED;
8792        }
8793        return ActivityManager.checkComponentPermission(permission, uid,
8794                owningUid, exported);
8795    }
8796
8797    /**
8798     * As the only public entry point for permissions checking, this method
8799     * can enforce the semantic that requesting a check on a null global
8800     * permission is automatically denied.  (Internally a null permission
8801     * string is used when calling {@link #checkComponentPermission} in cases
8802     * when only uid-based security is needed.)
8803     *
8804     * This can be called with or without the global lock held.
8805     */
8806    @Override
8807    public int checkPermission(String permission, int pid, int uid) {
8808        if (permission == null) {
8809            return PackageManager.PERMISSION_DENIED;
8810        }
8811        return checkComponentPermission(permission, pid, uid, -1, true);
8812    }
8813
8814    @Override
8815    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8816        if (permission == null) {
8817            return PackageManager.PERMISSION_DENIED;
8818        }
8819
8820        // We might be performing an operation on behalf of an indirect binder
8821        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8822        // client identity accordingly before proceeding.
8823        Identity tlsIdentity = sCallerIdentity.get();
8824        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8825            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8826                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8827            uid = tlsIdentity.uid;
8828            pid = tlsIdentity.pid;
8829        }
8830
8831        return checkComponentPermission(permission, pid, uid, -1, true);
8832    }
8833
8834    /**
8835     * Binder IPC calls go through the public entry point.
8836     * This can be called with or without the global lock held.
8837     */
8838    int checkCallingPermission(String permission) {
8839        return checkPermission(permission,
8840                Binder.getCallingPid(),
8841                UserHandle.getAppId(Binder.getCallingUid()));
8842    }
8843
8844    /**
8845     * This can be called with or without the global lock held.
8846     */
8847    void enforceCallingPermission(String permission, String func) {
8848        if (checkCallingPermission(permission)
8849                == PackageManager.PERMISSION_GRANTED) {
8850            return;
8851        }
8852
8853        String msg = "Permission Denial: " + func + " from pid="
8854                + Binder.getCallingPid()
8855                + ", uid=" + Binder.getCallingUid()
8856                + " requires " + permission;
8857        Slog.w(TAG, msg);
8858        throw new SecurityException(msg);
8859    }
8860
8861    /**
8862     * This can be called with or without the global lock held.
8863     */
8864    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
8865        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
8866            enforceCallingPermission(permission, func);
8867        }
8868    }
8869
8870    /**
8871     * Determine if UID is holding permissions required to access {@link Uri} in
8872     * the given {@link ProviderInfo}. Final permission checking is always done
8873     * in {@link ContentProvider}.
8874     */
8875    private final boolean checkHoldingPermissionsLocked(
8876            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8877        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8878                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8879        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8880            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8881                    != PERMISSION_GRANTED) {
8882                return false;
8883            }
8884        }
8885        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8886    }
8887
8888    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8889            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8890        if (pi.applicationInfo.uid == uid) {
8891            return true;
8892        } else if (!pi.exported) {
8893            return false;
8894        }
8895
8896        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8897        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8898        try {
8899            // check if target holds top-level <provider> permissions
8900            if (!readMet && pi.readPermission != null && considerUidPermissions
8901                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8902                readMet = true;
8903            }
8904            if (!writeMet && pi.writePermission != null && considerUidPermissions
8905                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8906                writeMet = true;
8907            }
8908
8909            // track if unprotected read/write is allowed; any denied
8910            // <path-permission> below removes this ability
8911            boolean allowDefaultRead = pi.readPermission == null;
8912            boolean allowDefaultWrite = pi.writePermission == null;
8913
8914            // check if target holds any <path-permission> that match uri
8915            final PathPermission[] pps = pi.pathPermissions;
8916            if (pps != null) {
8917                final String path = grantUri.uri.getPath();
8918                int i = pps.length;
8919                while (i > 0 && (!readMet || !writeMet)) {
8920                    i--;
8921                    PathPermission pp = pps[i];
8922                    if (pp.match(path)) {
8923                        if (!readMet) {
8924                            final String pprperm = pp.getReadPermission();
8925                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8926                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8927                                    + ": match=" + pp.match(path)
8928                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8929                            if (pprperm != null) {
8930                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8931                                        == PERMISSION_GRANTED) {
8932                                    readMet = true;
8933                                } else {
8934                                    allowDefaultRead = false;
8935                                }
8936                            }
8937                        }
8938                        if (!writeMet) {
8939                            final String ppwperm = pp.getWritePermission();
8940                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8941                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8942                                    + ": match=" + pp.match(path)
8943                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8944                            if (ppwperm != null) {
8945                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8946                                        == PERMISSION_GRANTED) {
8947                                    writeMet = true;
8948                                } else {
8949                                    allowDefaultWrite = false;
8950                                }
8951                            }
8952                        }
8953                    }
8954                }
8955            }
8956
8957            // grant unprotected <provider> read/write, if not blocked by
8958            // <path-permission> above
8959            if (allowDefaultRead) readMet = true;
8960            if (allowDefaultWrite) writeMet = true;
8961
8962        } catch (RemoteException e) {
8963            return false;
8964        }
8965
8966        return readMet && writeMet;
8967    }
8968
8969    public boolean isAppStartModeDisabled(int uid, String packageName) {
8970        synchronized (this) {
8971            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8972                    == ActivityManager.APP_START_MODE_DISABLED;
8973        }
8974    }
8975
8976    // Unified app-op and target sdk check
8977    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8978        // Apps that target O+ are always subject to background check
8979        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8980            if (DEBUG_BACKGROUND_CHECK) {
8981                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8982            }
8983            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8984        }
8985        // ...and legacy apps get an AppOp check
8986        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8987                uid, packageName);
8988        if (DEBUG_BACKGROUND_CHECK) {
8989            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8990        }
8991        switch (appop) {
8992            case AppOpsManager.MODE_ALLOWED:
8993                // If force-background-check is enabled, restrict all apps that aren't whitelisted.
8994                if (mForceBackgroundCheck &&
8995                        !UserHandle.isCore(uid) &&
8996                        !isOnDeviceIdleWhitelistLocked(uid)) {
8997                    if (DEBUG_BACKGROUND_CHECK) {
8998                        Slog.i(TAG, "Force background check: " +
8999                                uid + "/" + packageName + " restricted");
9000                    }
9001                    return ActivityManager.APP_START_MODE_DELAYED;
9002                }
9003                return ActivityManager.APP_START_MODE_NORMAL;
9004            case AppOpsManager.MODE_IGNORED:
9005                return ActivityManager.APP_START_MODE_DELAYED;
9006            default:
9007                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9008        }
9009    }
9010
9011    // Service launch is available to apps with run-in-background exemptions but
9012    // some other background operations are not.  If we're doing a check
9013    // of service-launch policy, allow those callers to proceed unrestricted.
9014    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9015        // Persistent app?
9016        if (mPackageManagerInt.isPackagePersistent(packageName)) {
9017            if (DEBUG_BACKGROUND_CHECK) {
9018                Slog.i(TAG, "App " + uid + "/" + packageName
9019                        + " is persistent; not restricted in background");
9020            }
9021            return ActivityManager.APP_START_MODE_NORMAL;
9022        }
9023
9024        // Non-persistent but background whitelisted?
9025        if (uidOnBackgroundWhitelist(uid)) {
9026            if (DEBUG_BACKGROUND_CHECK) {
9027                Slog.i(TAG, "App " + uid + "/" + packageName
9028                        + " on background whitelist; not restricted in background");
9029            }
9030            return ActivityManager.APP_START_MODE_NORMAL;
9031        }
9032
9033        // Is this app on the battery whitelist?
9034        if (isOnDeviceIdleWhitelistLocked(uid)) {
9035            if (DEBUG_BACKGROUND_CHECK) {
9036                Slog.i(TAG, "App " + uid + "/" + packageName
9037                        + " on idle whitelist; not restricted in background");
9038            }
9039            return ActivityManager.APP_START_MODE_NORMAL;
9040        }
9041
9042        // None of the service-policy criteria apply, so we apply the common criteria
9043        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
9044    }
9045
9046    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
9047            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
9048        UidRecord uidRec = mActiveUids.get(uid);
9049        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
9050                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
9051                + (uidRec != null ? uidRec.idle : false));
9052        if (uidRec == null || alwaysRestrict || uidRec.idle) {
9053            boolean ephemeral;
9054            if (uidRec == null) {
9055                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
9056                        UserHandle.getUserId(uid), packageName);
9057            } else {
9058                ephemeral = uidRec.ephemeral;
9059            }
9060
9061            if (ephemeral) {
9062                // We are hard-core about ephemeral apps not running in the background.
9063                return ActivityManager.APP_START_MODE_DISABLED;
9064            } else {
9065                if (disabledOnly) {
9066                    // The caller is only interested in whether app starts are completely
9067                    // disabled for the given package (that is, it is an instant app).  So
9068                    // we don't need to go further, which is all just seeing if we should
9069                    // apply a "delayed" mode for a regular app.
9070                    return ActivityManager.APP_START_MODE_NORMAL;
9071                }
9072                final int startMode = (alwaysRestrict)
9073                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
9074                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
9075                                packageTargetSdk);
9076                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
9077                        + " pkg=" + packageName + " startMode=" + startMode
9078                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
9079                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
9080                    // This is an old app that has been forced into a "compatible as possible"
9081                    // mode of background check.  To increase compatibility, we will allow other
9082                    // foreground apps to cause its services to start.
9083                    if (callingPid >= 0) {
9084                        ProcessRecord proc;
9085                        synchronized (mPidsSelfLocked) {
9086                            proc = mPidsSelfLocked.get(callingPid);
9087                        }
9088                        if (proc != null &&
9089                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
9090                            // Whoever is instigating this is in the foreground, so we will allow it
9091                            // to go through.
9092                            return ActivityManager.APP_START_MODE_NORMAL;
9093                        }
9094                    }
9095                }
9096                return startMode;
9097            }
9098        }
9099        return ActivityManager.APP_START_MODE_NORMAL;
9100    }
9101
9102    /**
9103     * @return whether a UID is in the system, user or temp doze whitelist.
9104     */
9105    boolean isOnDeviceIdleWhitelistLocked(int uid) {
9106        final int appId = UserHandle.getAppId(uid);
9107        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
9108                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9109                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9110    }
9111
9112    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9113        ProviderInfo pi = null;
9114        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9115        if (cpr != null) {
9116            pi = cpr.info;
9117        } else {
9118            try {
9119                pi = AppGlobals.getPackageManager().resolveContentProvider(
9120                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9121                        userHandle);
9122            } catch (RemoteException ex) {
9123            }
9124        }
9125        return pi;
9126    }
9127
9128    void grantEphemeralAccessLocked(int userId, Intent intent,
9129            int targetAppId, int ephemeralAppId) {
9130        getPackageManagerInternalLocked().
9131                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
9132    }
9133
9134    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
9135        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9136        if (targetUris != null) {
9137            return targetUris.get(grantUri);
9138        }
9139        return null;
9140    }
9141
9142    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
9143            String targetPkg, int targetUid, GrantUri grantUri) {
9144        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9145        if (targetUris == null) {
9146            targetUris = Maps.newArrayMap();
9147            mGrantedUriPermissions.put(targetUid, targetUris);
9148        }
9149
9150        UriPermission perm = targetUris.get(grantUri);
9151        if (perm == null) {
9152            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9153            targetUris.put(grantUri, perm);
9154        }
9155
9156        return perm;
9157    }
9158
9159    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
9160            final int modeFlags) {
9161        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
9162        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9163                : UriPermission.STRENGTH_OWNED;
9164
9165        // Root gets to do everything.
9166        if (uid == 0) {
9167            return true;
9168        }
9169
9170        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9171        if (perms == null) return false;
9172
9173        // First look for exact match
9174        final UriPermission exactPerm = perms.get(grantUri);
9175        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9176            return true;
9177        }
9178
9179        // No exact match, look for prefixes
9180        final int N = perms.size();
9181        for (int i = 0; i < N; i++) {
9182            final UriPermission perm = perms.valueAt(i);
9183            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9184                    && perm.getStrength(modeFlags) >= minStrength) {
9185                return true;
9186            }
9187        }
9188
9189        return false;
9190    }
9191
9192    /**
9193     * @param uri This uri must NOT contain an embedded userId.
9194     * @param userId The userId in which the uri is to be resolved.
9195     */
9196    @Override
9197    public int checkUriPermission(Uri uri, int pid, int uid,
9198            final int modeFlags, int userId, IBinder callerToken) {
9199        enforceNotIsolatedCaller("checkUriPermission");
9200
9201        // Another redirected-binder-call permissions check as in
9202        // {@link checkPermissionWithToken}.
9203        Identity tlsIdentity = sCallerIdentity.get();
9204        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9205            uid = tlsIdentity.uid;
9206            pid = tlsIdentity.pid;
9207        }
9208
9209        // Our own process gets to do everything.
9210        if (pid == MY_PID) {
9211            return PackageManager.PERMISSION_GRANTED;
9212        }
9213        synchronized (this) {
9214            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9215                    ? PackageManager.PERMISSION_GRANTED
9216                    : PackageManager.PERMISSION_DENIED;
9217        }
9218    }
9219
9220    /**
9221     * Check if the targetPkg can be granted permission to access uri by
9222     * the callingUid using the given modeFlags.  Throws a security exception
9223     * if callingUid is not allowed to do this.  Returns the uid of the target
9224     * if the URI permission grant should be performed; returns -1 if it is not
9225     * needed (for example targetPkg already has permission to access the URI).
9226     * If you already know the uid of the target, you can supply it in
9227     * lastTargetUid else set that to -1.
9228     */
9229    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9230            final int modeFlags, int lastTargetUid) {
9231        if (!Intent.isAccessUriMode(modeFlags)) {
9232            return -1;
9233        }
9234
9235        if (targetPkg != null) {
9236            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9237                    "Checking grant " + targetPkg + " permission to " + grantUri);
9238        }
9239
9240        final IPackageManager pm = AppGlobals.getPackageManager();
9241
9242        // If this is not a content: uri, we can't do anything with it.
9243        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9244            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9245                    "Can't grant URI permission for non-content URI: " + grantUri);
9246            return -1;
9247        }
9248
9249        // Bail early if system is trying to hand out permissions directly; it
9250        // must always grant permissions on behalf of someone explicit.
9251        final int callingAppId = UserHandle.getAppId(callingUid);
9252        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9253            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9254                // Exempted authority for
9255                // 1. cropping user photos and sharing a generated license html
9256                //    file in Settings app
9257                // 2. sharing a generated license html file in TvSettings app
9258            } else {
9259                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9260                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9261                return -1;
9262            }
9263        }
9264
9265        final String authority = grantUri.uri.getAuthority();
9266        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9267                MATCH_DEBUG_TRIAGED_MISSING);
9268        if (pi == null) {
9269            Slog.w(TAG, "No content provider found for permission check: " +
9270                    grantUri.uri.toSafeString());
9271            return -1;
9272        }
9273
9274        int targetUid = lastTargetUid;
9275        if (targetUid < 0 && targetPkg != null) {
9276            try {
9277                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9278                        UserHandle.getUserId(callingUid));
9279                if (targetUid < 0) {
9280                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9281                            "Can't grant URI permission no uid for: " + targetPkg);
9282                    return -1;
9283                }
9284            } catch (RemoteException ex) {
9285                return -1;
9286            }
9287        }
9288
9289        // If we're extending a persistable grant, then we always need to create
9290        // the grant data structure so that take/release APIs work
9291        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9292            return targetUid;
9293        }
9294
9295        if (targetUid >= 0) {
9296            // First...  does the target actually need this permission?
9297            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9298                // No need to grant the target this permission.
9299                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9300                        "Target " + targetPkg + " already has full permission to " + grantUri);
9301                return -1;
9302            }
9303        } else {
9304            // First...  there is no target package, so can anyone access it?
9305            boolean allowed = pi.exported;
9306            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9307                if (pi.readPermission != null) {
9308                    allowed = false;
9309                }
9310            }
9311            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9312                if (pi.writePermission != null) {
9313                    allowed = false;
9314                }
9315            }
9316            if (allowed) {
9317                return -1;
9318            }
9319        }
9320
9321        /* There is a special cross user grant if:
9322         * - The target is on another user.
9323         * - Apps on the current user can access the uri without any uid permissions.
9324         * In this case, we grant a uri permission, even if the ContentProvider does not normally
9325         * grant uri permissions.
9326         */
9327        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9328                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9329                modeFlags, false /*without considering the uid permissions*/);
9330
9331        // Second...  is the provider allowing granting of URI permissions?
9332        if (!specialCrossUserGrant) {
9333            if (!pi.grantUriPermissions) {
9334                throw new SecurityException("Provider " + pi.packageName
9335                        + "/" + pi.name
9336                        + " does not allow granting of Uri permissions (uri "
9337                        + grantUri + ")");
9338            }
9339            if (pi.uriPermissionPatterns != null) {
9340                final int N = pi.uriPermissionPatterns.length;
9341                boolean allowed = false;
9342                for (int i=0; i<N; i++) {
9343                    if (pi.uriPermissionPatterns[i] != null
9344                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9345                        allowed = true;
9346                        break;
9347                    }
9348                }
9349                if (!allowed) {
9350                    throw new SecurityException("Provider " + pi.packageName
9351                            + "/" + pi.name
9352                            + " does not allow granting of permission to path of Uri "
9353                            + grantUri);
9354                }
9355            }
9356        }
9357
9358        // Third...  does the caller itself have permission to access
9359        // this uri?
9360        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9361            // Require they hold a strong enough Uri permission
9362            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9363                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9364                    throw new SecurityException(
9365                            "UID " + callingUid + " does not have permission to " + grantUri
9366                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9367                                    + "or related APIs");
9368                } else {
9369                    throw new SecurityException(
9370                            "UID " + callingUid + " does not have permission to " + grantUri);
9371                }
9372            }
9373        }
9374        return targetUid;
9375    }
9376
9377    /**
9378     * @param uri This uri must NOT contain an embedded userId.
9379     * @param userId The userId in which the uri is to be resolved.
9380     */
9381    @Override
9382    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9383            final int modeFlags, int userId) {
9384        enforceNotIsolatedCaller("checkGrantUriPermission");
9385        synchronized(this) {
9386            return checkGrantUriPermissionLocked(callingUid, targetPkg,
9387                    new GrantUri(userId, uri, false), modeFlags, -1);
9388        }
9389    }
9390
9391    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9392            final int modeFlags, UriPermissionOwner owner) {
9393        if (!Intent.isAccessUriMode(modeFlags)) {
9394            return;
9395        }
9396
9397        // So here we are: the caller has the assumed permission
9398        // to the uri, and the target doesn't.  Let's now give this to
9399        // the target.
9400
9401        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9402                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9403
9404        final String authority = grantUri.uri.getAuthority();
9405        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9406                MATCH_DEBUG_TRIAGED_MISSING);
9407        if (pi == null) {
9408            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9409            return;
9410        }
9411
9412        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9413            grantUri.prefix = true;
9414        }
9415        final UriPermission perm = findOrCreateUriPermissionLocked(
9416                pi.packageName, targetPkg, targetUid, grantUri);
9417        perm.grantModes(modeFlags, owner);
9418    }
9419
9420    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9421            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9422        if (targetPkg == null) {
9423            throw new NullPointerException("targetPkg");
9424        }
9425        int targetUid;
9426        final IPackageManager pm = AppGlobals.getPackageManager();
9427        try {
9428            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9429        } catch (RemoteException ex) {
9430            return;
9431        }
9432
9433        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9434                targetUid);
9435        if (targetUid < 0) {
9436            return;
9437        }
9438
9439        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9440                owner);
9441    }
9442
9443    static class NeededUriGrants extends ArrayList<GrantUri> {
9444        final String targetPkg;
9445        final int targetUid;
9446        final int flags;
9447
9448        NeededUriGrants(String targetPkg, int targetUid, int flags) {
9449            this.targetPkg = targetPkg;
9450            this.targetUid = targetUid;
9451            this.flags = flags;
9452        }
9453
9454        void writeToProto(ProtoOutputStream proto, long fieldId) {
9455            long token = proto.start(fieldId);
9456            proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9457            proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9458            proto.write(NeededUriGrantsProto.FLAGS, flags);
9459
9460            final int N = this.size();
9461            for (int i=0; i<N; i++) {
9462                this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9463            }
9464            proto.end(token);
9465        }
9466    }
9467
9468    /**
9469     * Like checkGrantUriPermissionLocked, but takes an Intent.
9470     */
9471    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9472            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9473        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9474                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9475                + " clip=" + (intent != null ? intent.getClipData() : null)
9476                + " from " + intent + "; flags=0x"
9477                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9478
9479        if (targetPkg == null) {
9480            throw new NullPointerException("targetPkg");
9481        }
9482
9483        if (intent == null) {
9484            return null;
9485        }
9486        Uri data = intent.getData();
9487        ClipData clip = intent.getClipData();
9488        if (data == null && clip == null) {
9489            return null;
9490        }
9491        // Default userId for uris in the intent (if they don't specify it themselves)
9492        int contentUserHint = intent.getContentUserHint();
9493        if (contentUserHint == UserHandle.USER_CURRENT) {
9494            contentUserHint = UserHandle.getUserId(callingUid);
9495        }
9496        final IPackageManager pm = AppGlobals.getPackageManager();
9497        int targetUid;
9498        if (needed != null) {
9499            targetUid = needed.targetUid;
9500        } else {
9501            try {
9502                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9503                        targetUserId);
9504            } catch (RemoteException ex) {
9505                return null;
9506            }
9507            if (targetUid < 0) {
9508                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9509                        "Can't grant URI permission no uid for: " + targetPkg
9510                        + " on user " + targetUserId);
9511                return null;
9512            }
9513        }
9514        if (data != null) {
9515            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9516            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9517                    targetUid);
9518            if (targetUid > 0) {
9519                if (needed == null) {
9520                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9521                }
9522                needed.add(grantUri);
9523            }
9524        }
9525        if (clip != null) {
9526            for (int i=0; i<clip.getItemCount(); i++) {
9527                Uri uri = clip.getItemAt(i).getUri();
9528                if (uri != null) {
9529                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9530                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9531                            targetUid);
9532                    if (targetUid > 0) {
9533                        if (needed == null) {
9534                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9535                        }
9536                        needed.add(grantUri);
9537                    }
9538                } else {
9539                    Intent clipIntent = clip.getItemAt(i).getIntent();
9540                    if (clipIntent != null) {
9541                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9542                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9543                        if (newNeeded != null) {
9544                            needed = newNeeded;
9545                        }
9546                    }
9547                }
9548            }
9549        }
9550
9551        return needed;
9552    }
9553
9554    /**
9555     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9556     */
9557    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9558            UriPermissionOwner owner) {
9559        if (needed != null) {
9560            for (int i=0; i<needed.size(); i++) {
9561                GrantUri grantUri = needed.get(i);
9562                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9563                        grantUri, needed.flags, owner);
9564            }
9565        }
9566    }
9567
9568    void grantUriPermissionFromIntentLocked(int callingUid,
9569            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9570        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9571                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9572        if (needed == null) {
9573            return;
9574        }
9575
9576        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9577    }
9578
9579    /**
9580     * @param uri This uri must NOT contain an embedded userId.
9581     * @param userId The userId in which the uri is to be resolved.
9582     */
9583    @Override
9584    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9585            final int modeFlags, int userId) {
9586        enforceNotIsolatedCaller("grantUriPermission");
9587        GrantUri grantUri = new GrantUri(userId, uri, false);
9588        synchronized(this) {
9589            final ProcessRecord r = getRecordForAppLocked(caller);
9590            if (r == null) {
9591                throw new SecurityException("Unable to find app for caller "
9592                        + caller
9593                        + " when granting permission to uri " + grantUri);
9594            }
9595            if (targetPkg == null) {
9596                throw new IllegalArgumentException("null target");
9597            }
9598            if (grantUri == null) {
9599                throw new IllegalArgumentException("null uri");
9600            }
9601
9602            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9603                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9604                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9605                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9606
9607            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9608                    UserHandle.getUserId(r.uid));
9609        }
9610    }
9611
9612    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9613        if (perm.modeFlags == 0) {
9614            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9615                    perm.targetUid);
9616            if (perms != null) {
9617                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9618                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9619
9620                perms.remove(perm.uri);
9621                if (perms.isEmpty()) {
9622                    mGrantedUriPermissions.remove(perm.targetUid);
9623                }
9624            }
9625        }
9626    }
9627
9628    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9629            final int modeFlags) {
9630        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9631                "Revoking all granted permissions to " + grantUri);
9632
9633        final IPackageManager pm = AppGlobals.getPackageManager();
9634        final String authority = grantUri.uri.getAuthority();
9635        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9636                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9637        if (pi == null) {
9638            Slog.w(TAG, "No content provider found for permission revoke: "
9639                    + grantUri.toSafeString());
9640            return;
9641        }
9642
9643        // Does the caller have this permission on the URI?
9644        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9645            // If they don't have direct access to the URI, then revoke any
9646            // ownerless URI permissions that have been granted to them.
9647            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9648            if (perms != null) {
9649                boolean persistChanged = false;
9650                for (int i = perms.size()-1; i >= 0; i--) {
9651                    final UriPermission perm = perms.valueAt(i);
9652                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9653                        continue;
9654                    }
9655                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9656                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9657                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9658                                "Revoking non-owned " + perm.targetUid
9659                                + " permission to " + perm.uri);
9660                        persistChanged |= perm.revokeModes(
9661                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9662                        if (perm.modeFlags == 0) {
9663                            perms.removeAt(i);
9664                        }
9665                    }
9666                }
9667                if (perms.isEmpty()) {
9668                    mGrantedUriPermissions.remove(callingUid);
9669                }
9670                if (persistChanged) {
9671                    schedulePersistUriGrants();
9672                }
9673            }
9674            return;
9675        }
9676
9677        boolean persistChanged = false;
9678
9679        // Go through all of the permissions and remove any that match.
9680        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9681            final int targetUid = mGrantedUriPermissions.keyAt(i);
9682            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9683
9684            for (int j = perms.size()-1; j >= 0; j--) {
9685                final UriPermission perm = perms.valueAt(j);
9686                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9687                    continue;
9688                }
9689                if (perm.uri.sourceUserId == grantUri.sourceUserId
9690                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9691                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9692                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9693                    persistChanged |= perm.revokeModes(
9694                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9695                            targetPackage == null);
9696                    if (perm.modeFlags == 0) {
9697                        perms.removeAt(j);
9698                    }
9699                }
9700            }
9701
9702            if (perms.isEmpty()) {
9703                mGrantedUriPermissions.removeAt(i);
9704            }
9705        }
9706
9707        if (persistChanged) {
9708            schedulePersistUriGrants();
9709        }
9710    }
9711
9712    /**
9713     * @param uri This uri must NOT contain an embedded userId.
9714     * @param userId The userId in which the uri is to be resolved.
9715     */
9716    @Override
9717    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9718            final int modeFlags, int userId) {
9719        enforceNotIsolatedCaller("revokeUriPermission");
9720        synchronized(this) {
9721            final ProcessRecord r = getRecordForAppLocked(caller);
9722            if (r == null) {
9723                throw new SecurityException("Unable to find app for caller "
9724                        + caller
9725                        + " when revoking permission to uri " + uri);
9726            }
9727            if (uri == null) {
9728                Slog.w(TAG, "revokeUriPermission: null uri");
9729                return;
9730            }
9731
9732            if (!Intent.isAccessUriMode(modeFlags)) {
9733                return;
9734            }
9735
9736            final String authority = uri.getAuthority();
9737            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9738                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9739            if (pi == null) {
9740                Slog.w(TAG, "No content provider found for permission revoke: "
9741                        + uri.toSafeString());
9742                return;
9743            }
9744
9745            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9746                    modeFlags);
9747        }
9748    }
9749
9750    /**
9751     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9752     * given package.
9753     *
9754     * @param packageName Package name to match, or {@code null} to apply to all
9755     *            packages.
9756     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9757     *            to all users.
9758     * @param persistable If persistable grants should be removed.
9759     * @param targetOnly When {@code true}, only remove permissions where the app is the target,
9760     * not source.
9761     */
9762    private void removeUriPermissionsForPackageLocked(
9763            String packageName, int userHandle, boolean persistable, boolean targetOnly) {
9764        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9765            throw new IllegalArgumentException("Must narrow by either package or user");
9766        }
9767
9768        boolean persistChanged = false;
9769
9770        int N = mGrantedUriPermissions.size();
9771        for (int i = 0; i < N; i++) {
9772            final int targetUid = mGrantedUriPermissions.keyAt(i);
9773            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9774
9775            // Only inspect grants matching user
9776            if (userHandle == UserHandle.USER_ALL
9777                    || userHandle == UserHandle.getUserId(targetUid)) {
9778                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9779                    final UriPermission perm = it.next();
9780
9781                    // Only inspect grants matching package
9782                    if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
9783                            || perm.targetPkg.equals(packageName)) {
9784                        // Hacky solution as part of fixing a security bug; ignore
9785                        // grants associated with DownloadManager so we don't have
9786                        // to immediately launch it to regrant the permissions
9787                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9788                                && !persistable) continue;
9789
9790                        persistChanged |= perm.revokeModes(persistable
9791                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9792
9793                        // Only remove when no modes remain; any persisted grants
9794                        // will keep this alive.
9795                        if (perm.modeFlags == 0) {
9796                            it.remove();
9797                        }
9798                    }
9799                }
9800
9801                if (perms.isEmpty()) {
9802                    mGrantedUriPermissions.remove(targetUid);
9803                    N--;
9804                    i--;
9805                }
9806            }
9807        }
9808
9809        if (persistChanged) {
9810            schedulePersistUriGrants();
9811        }
9812    }
9813
9814    @Override
9815    public IBinder newUriPermissionOwner(String name) {
9816        enforceNotIsolatedCaller("newUriPermissionOwner");
9817        synchronized(this) {
9818            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9819            return owner.getExternalTokenLocked();
9820        }
9821    }
9822
9823    @Override
9824    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9825        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9826        synchronized(this) {
9827            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9828            if (r == null) {
9829                throw new IllegalArgumentException("Activity does not exist; token="
9830                        + activityToken);
9831            }
9832            return r.getUriPermissionsLocked().getExternalTokenLocked();
9833        }
9834    }
9835    /**
9836     * @param uri This uri must NOT contain an embedded userId.
9837     * @param sourceUserId The userId in which the uri is to be resolved.
9838     * @param targetUserId The userId of the app that receives the grant.
9839     */
9840    @Override
9841    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9842            final int modeFlags, int sourceUserId, int targetUserId) {
9843        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9844                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9845                "grantUriPermissionFromOwner", null);
9846        synchronized(this) {
9847            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9848            if (owner == null) {
9849                throw new IllegalArgumentException("Unknown owner: " + token);
9850            }
9851            if (fromUid != Binder.getCallingUid()) {
9852                if (Binder.getCallingUid() != myUid()) {
9853                    // Only system code can grant URI permissions on behalf
9854                    // of other users.
9855                    throw new SecurityException("nice try");
9856                }
9857            }
9858            if (targetPkg == null) {
9859                throw new IllegalArgumentException("null target");
9860            }
9861            if (uri == null) {
9862                throw new IllegalArgumentException("null uri");
9863            }
9864
9865            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9866                    modeFlags, owner, targetUserId);
9867        }
9868    }
9869
9870    /**
9871     * @param uri This uri must NOT contain an embedded userId.
9872     * @param userId The userId in which the uri is to be resolved.
9873     */
9874    @Override
9875    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9876        synchronized(this) {
9877            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9878            if (owner == null) {
9879                throw new IllegalArgumentException("Unknown owner: " + token);
9880            }
9881
9882            if (uri == null) {
9883                owner.removeUriPermissionsLocked(mode);
9884            } else {
9885                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9886                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9887            }
9888        }
9889    }
9890
9891    private void schedulePersistUriGrants() {
9892        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9893            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9894                    10 * DateUtils.SECOND_IN_MILLIS);
9895        }
9896    }
9897
9898    private void writeGrantedUriPermissions() {
9899        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9900
9901        final long startTime = SystemClock.uptimeMillis();
9902
9903        // Snapshot permissions so we can persist without lock
9904        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9905        synchronized (this) {
9906            final int size = mGrantedUriPermissions.size();
9907            for (int i = 0; i < size; i++) {
9908                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9909                for (UriPermission perm : perms.values()) {
9910                    if (perm.persistedModeFlags != 0) {
9911                        persist.add(perm.snapshot());
9912                    }
9913                }
9914            }
9915        }
9916
9917        FileOutputStream fos = null;
9918        try {
9919            fos = mGrantFile.startWrite(startTime);
9920
9921            XmlSerializer out = new FastXmlSerializer();
9922            out.setOutput(fos, StandardCharsets.UTF_8.name());
9923            out.startDocument(null, true);
9924            out.startTag(null, TAG_URI_GRANTS);
9925            for (UriPermission.Snapshot perm : persist) {
9926                out.startTag(null, TAG_URI_GRANT);
9927                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9928                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9929                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9930                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9931                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9932                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9933                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9934                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9935                out.endTag(null, TAG_URI_GRANT);
9936            }
9937            out.endTag(null, TAG_URI_GRANTS);
9938            out.endDocument();
9939
9940            mGrantFile.finishWrite(fos);
9941        } catch (IOException e) {
9942            if (fos != null) {
9943                mGrantFile.failWrite(fos);
9944            }
9945        }
9946    }
9947
9948    private void readGrantedUriPermissionsLocked() {
9949        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9950
9951        final long now = System.currentTimeMillis();
9952
9953        FileInputStream fis = null;
9954        try {
9955            fis = mGrantFile.openRead();
9956            final XmlPullParser in = Xml.newPullParser();
9957            in.setInput(fis, StandardCharsets.UTF_8.name());
9958
9959            int type;
9960            while ((type = in.next()) != END_DOCUMENT) {
9961                final String tag = in.getName();
9962                if (type == START_TAG) {
9963                    if (TAG_URI_GRANT.equals(tag)) {
9964                        final int sourceUserId;
9965                        final int targetUserId;
9966                        final int userHandle = readIntAttribute(in,
9967                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9968                        if (userHandle != UserHandle.USER_NULL) {
9969                            // For backwards compatibility.
9970                            sourceUserId = userHandle;
9971                            targetUserId = userHandle;
9972                        } else {
9973                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9974                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9975                        }
9976                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9977                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9978                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9979                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9980                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9981                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9982
9983                        // Sanity check that provider still belongs to source package
9984                        // Both direct boot aware and unaware packages are fine as we
9985                        // will do filtering at query time to avoid multiple parsing.
9986                        final ProviderInfo pi = getProviderInfoLocked(
9987                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9988                                        | MATCH_DIRECT_BOOT_UNAWARE);
9989                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9990                            int targetUid = -1;
9991                            try {
9992                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9993                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9994                            } catch (RemoteException e) {
9995                            }
9996                            if (targetUid != -1) {
9997                                final UriPermission perm = findOrCreateUriPermissionLocked(
9998                                        sourcePkg, targetPkg, targetUid,
9999                                        new GrantUri(sourceUserId, uri, prefix));
10000                                perm.initPersistedModes(modeFlags, createdTime);
10001                            }
10002                        } else {
10003                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
10004                                    + " but instead found " + pi);
10005                        }
10006                    }
10007                }
10008            }
10009        } catch (FileNotFoundException e) {
10010            // Missing grants is okay
10011        } catch (IOException e) {
10012            Slog.wtf(TAG, "Failed reading Uri grants", e);
10013        } catch (XmlPullParserException e) {
10014            Slog.wtf(TAG, "Failed reading Uri grants", e);
10015        } finally {
10016            IoUtils.closeQuietly(fis);
10017        }
10018    }
10019
10020    /**
10021     * @param uri This uri must NOT contain an embedded userId.
10022     * @param userId The userId in which the uri is to be resolved.
10023     */
10024    @Override
10025    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
10026        enforceNotIsolatedCaller("takePersistableUriPermission");
10027
10028        Preconditions.checkFlagsArgument(modeFlags,
10029                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10030
10031        synchronized (this) {
10032            final int callingUid = Binder.getCallingUid();
10033            boolean persistChanged = false;
10034            GrantUri grantUri = new GrantUri(userId, uri, false);
10035
10036            UriPermission exactPerm = findUriPermissionLocked(callingUid, grantUri);
10037            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
10038                    new GrantUri(userId, uri, true));
10039
10040            final boolean exactValid = (exactPerm != null)
10041                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
10042            final boolean prefixValid = (prefixPerm != null)
10043                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
10044
10045            if (!(exactValid || prefixValid)) {
10046                throw new SecurityException("No persistable permission grants found for UID "
10047                        + callingUid + " and Uri " + grantUri.toSafeString());
10048            }
10049
10050            if (exactValid) {
10051                persistChanged |= exactPerm.takePersistableModes(modeFlags);
10052            }
10053            if (prefixValid) {
10054                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
10055            }
10056
10057            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
10058
10059            if (persistChanged) {
10060                schedulePersistUriGrants();
10061            }
10062        }
10063    }
10064
10065    /**
10066     * @param uri This uri must NOT contain an embedded userId.
10067     * @param userId The userId in which the uri is to be resolved.
10068     */
10069    @Override
10070    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
10071        enforceNotIsolatedCaller("releasePersistableUriPermission");
10072
10073        Preconditions.checkFlagsArgument(modeFlags,
10074                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10075
10076        synchronized (this) {
10077            final int callingUid = Binder.getCallingUid();
10078            boolean persistChanged = false;
10079
10080            UriPermission exactPerm = findUriPermissionLocked(callingUid,
10081                    new GrantUri(userId, uri, false));
10082            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
10083                    new GrantUri(userId, uri, true));
10084            if (exactPerm == null && prefixPerm == null) {
10085                throw new SecurityException("No permission grants found for UID " + callingUid
10086                        + " and Uri " + uri.toSafeString());
10087            }
10088
10089            if (exactPerm != null) {
10090                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10091                removeUriPermissionIfNeededLocked(exactPerm);
10092            }
10093            if (prefixPerm != null) {
10094                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10095                removeUriPermissionIfNeededLocked(prefixPerm);
10096            }
10097
10098            if (persistChanged) {
10099                schedulePersistUriGrants();
10100            }
10101        }
10102    }
10103
10104    /**
10105     * Prune any older {@link UriPermission} for the given UID until outstanding
10106     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10107     *
10108     * @return if any mutations occured that require persisting.
10109     */
10110    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
10111        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
10112        if (perms == null) return false;
10113        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
10114
10115        final ArrayList<UriPermission> persisted = Lists.newArrayList();
10116        for (UriPermission perm : perms.values()) {
10117            if (perm.persistedModeFlags != 0) {
10118                persisted.add(perm);
10119            }
10120        }
10121
10122        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10123        if (trimCount <= 0) return false;
10124
10125        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10126        for (int i = 0; i < trimCount; i++) {
10127            final UriPermission perm = persisted.get(i);
10128
10129            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10130                    "Trimming grant created at " + perm.persistedCreateTime);
10131
10132            perm.releasePersistableModes(~0);
10133            removeUriPermissionIfNeededLocked(perm);
10134        }
10135
10136        return true;
10137    }
10138
10139    @Override
10140    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10141            String packageName, boolean incoming) {
10142        enforceNotIsolatedCaller("getPersistedUriPermissions");
10143        Preconditions.checkNotNull(packageName, "packageName");
10144
10145        final int callingUid = Binder.getCallingUid();
10146        final int callingUserId = UserHandle.getUserId(callingUid);
10147        final IPackageManager pm = AppGlobals.getPackageManager();
10148        try {
10149            final int packageUid = pm.getPackageUid(packageName,
10150                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
10151            if (packageUid != callingUid) {
10152                throw new SecurityException(
10153                        "Package " + packageName + " does not belong to calling UID " + callingUid);
10154            }
10155        } catch (RemoteException e) {
10156            throw new SecurityException("Failed to verify package name ownership");
10157        }
10158
10159        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10160        synchronized (this) {
10161            if (incoming) {
10162                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10163                        callingUid);
10164                if (perms == null) {
10165                    Slog.w(TAG, "No permission grants found for " + packageName);
10166                } else {
10167                    for (int j = 0; j < perms.size(); j++) {
10168                        final UriPermission perm = perms.valueAt(j);
10169                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10170                            result.add(perm.buildPersistedPublicApiObject());
10171                        }
10172                    }
10173                }
10174            } else {
10175                final int size = mGrantedUriPermissions.size();
10176                for (int i = 0; i < size; i++) {
10177                    final ArrayMap<GrantUri, UriPermission> perms =
10178                            mGrantedUriPermissions.valueAt(i);
10179                    for (int j = 0; j < perms.size(); j++) {
10180                        final UriPermission perm = perms.valueAt(j);
10181                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10182                            result.add(perm.buildPersistedPublicApiObject());
10183                        }
10184                    }
10185                }
10186            }
10187        }
10188        return new ParceledListSlice<android.content.UriPermission>(result);
10189    }
10190
10191    @Override
10192    public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
10193            @Nullable String packageName, int userId) {
10194        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10195                "getGrantedUriPermissions");
10196
10197        final List<GrantedUriPermission> result = new ArrayList<>();
10198        synchronized (this) {
10199            final int size = mGrantedUriPermissions.size();
10200            for (int i = 0; i < size; i++) {
10201                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10202                for (int j = 0; j < perms.size(); j++) {
10203                    final UriPermission perm = perms.valueAt(j);
10204                    if ((packageName == null || packageName.equals(perm.targetPkg))
10205                            && perm.targetUserId == userId
10206                            && perm.persistedModeFlags != 0) {
10207                        result.add(perm.buildGrantedUriPermission());
10208                    }
10209                }
10210            }
10211        }
10212        return new ParceledListSlice<>(result);
10213    }
10214
10215    @Override
10216    public void clearGrantedUriPermissions(String packageName, int userId) {
10217        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10218                "clearGrantedUriPermissions");
10219        synchronized(this) {
10220            removeUriPermissionsForPackageLocked(packageName, userId, true, true);
10221        }
10222    }
10223
10224    @Override
10225    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10226        synchronized (this) {
10227            ProcessRecord app =
10228                who != null ? getRecordForAppLocked(who) : null;
10229            if (app == null) return;
10230
10231            Message msg = Message.obtain();
10232            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10233            msg.obj = app;
10234            msg.arg1 = waiting ? 1 : 0;
10235            mUiHandler.sendMessage(msg);
10236        }
10237    }
10238
10239    @Override
10240    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10241        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10242        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10243        outInfo.availMem = getFreeMemory();
10244        outInfo.totalMem = getTotalMemory();
10245        outInfo.threshold = homeAppMem;
10246        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10247        outInfo.hiddenAppThreshold = cachedAppMem;
10248        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10249                ProcessList.SERVICE_ADJ);
10250        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10251                ProcessList.VISIBLE_APP_ADJ);
10252        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10253                ProcessList.FOREGROUND_APP_ADJ);
10254    }
10255
10256    // =========================================================
10257    // TASK MANAGEMENT
10258    // =========================================================
10259
10260    @Override
10261    public List<IBinder> getAppTasks(String callingPackage) {
10262        int callingUid = Binder.getCallingUid();
10263        long ident = Binder.clearCallingIdentity();
10264        try {
10265            synchronized(this) {
10266                return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10267            }
10268        } finally {
10269            Binder.restoreCallingIdentity(ident);
10270        }
10271    }
10272
10273    @Override
10274    public List<RunningTaskInfo> getTasks(int maxNum) {
10275       return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10276    }
10277
10278    @Override
10279    public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10280            @WindowingMode int ignoreWindowingMode) {
10281        final int callingUid = Binder.getCallingUid();
10282        ArrayList<RunningTaskInfo> list = new ArrayList<>();
10283
10284        synchronized(this) {
10285            if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10286
10287            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10288                    callingUid);
10289            mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10290                    ignoreWindowingMode, callingUid, allowed);
10291        }
10292
10293        return list;
10294    }
10295
10296    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10297        if (mRecentTasks.isCallerRecents(callingUid)) {
10298            // Always allow the recents component to get tasks
10299            return true;
10300        }
10301
10302        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10303                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10304        if (!allowed) {
10305            if (checkPermission(android.Manifest.permission.GET_TASKS,
10306                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10307                // Temporary compatibility: some existing apps on the system image may
10308                // still be requesting the old permission and not switched to the new
10309                // one; if so, we'll still allow them full access.  This means we need
10310                // to see if they are holding the old permission and are a system app.
10311                try {
10312                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10313                        allowed = true;
10314                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10315                                + " is using old GET_TASKS but privileged; allowing");
10316                    }
10317                } catch (RemoteException e) {
10318                }
10319            }
10320        }
10321        if (!allowed) {
10322            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10323                    + " does not hold REAL_GET_TASKS; limiting output");
10324        }
10325        return allowed;
10326    }
10327
10328    @Override
10329    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10330            int userId) {
10331        final int callingUid = Binder.getCallingUid();
10332        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10333                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10334        final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10335                callingUid);
10336        final boolean detailed = checkCallingPermission(
10337                android.Manifest.permission.GET_DETAILED_TASKS)
10338                        == PackageManager.PERMISSION_GRANTED;
10339
10340        synchronized (this) {
10341            return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10342                    callingUid);
10343        }
10344    }
10345
10346    @Override
10347    public ActivityManager.TaskDescription getTaskDescription(int id) {
10348        synchronized (this) {
10349            enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10350            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10351                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10352            if (tr != null) {
10353                return tr.lastTaskDescription;
10354            }
10355        }
10356        return null;
10357    }
10358
10359    @Override
10360    public int addAppTask(IBinder activityToken, Intent intent,
10361            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10362        final int callingUid = Binder.getCallingUid();
10363        final long callingIdent = Binder.clearCallingIdentity();
10364
10365        try {
10366            synchronized (this) {
10367                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10368                if (r == null) {
10369                    throw new IllegalArgumentException("Activity does not exist; token="
10370                            + activityToken);
10371                }
10372                ComponentName comp = intent.getComponent();
10373                if (comp == null) {
10374                    throw new IllegalArgumentException("Intent " + intent
10375                            + " must specify explicit component");
10376                }
10377                if (thumbnail.getWidth() != mThumbnailWidth
10378                        || thumbnail.getHeight() != mThumbnailHeight) {
10379                    throw new IllegalArgumentException("Bad thumbnail size: got "
10380                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10381                            + mThumbnailWidth + "x" + mThumbnailHeight);
10382                }
10383                if (intent.getSelector() != null) {
10384                    intent.setSelector(null);
10385                }
10386                if (intent.getSourceBounds() != null) {
10387                    intent.setSourceBounds(null);
10388                }
10389                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10390                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10391                        // The caller has added this as an auto-remove task...  that makes no
10392                        // sense, so turn off auto-remove.
10393                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10394                    }
10395                }
10396                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10397                    mLastAddedTaskActivity = null;
10398                }
10399                ActivityInfo ainfo = mLastAddedTaskActivity;
10400                if (ainfo == null) {
10401                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10402                            comp, 0, UserHandle.getUserId(callingUid));
10403                    if (ainfo.applicationInfo.uid != callingUid) {
10404                        throw new SecurityException(
10405                                "Can't add task for another application: target uid="
10406                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10407                    }
10408                }
10409
10410                TaskRecord task = TaskRecord.create(this,
10411                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10412                        ainfo, intent, description);
10413                if (!mRecentTasks.addToBottom(task)) {
10414                    return INVALID_TASK_ID;
10415                }
10416                r.getStack().addTask(task, !ON_TOP, "addAppTask");
10417
10418                // TODO: Send the thumbnail to WM to store it.
10419
10420                return task.taskId;
10421            }
10422        } finally {
10423            Binder.restoreCallingIdentity(callingIdent);
10424        }
10425    }
10426
10427    @Override
10428    public Point getAppTaskThumbnailSize() {
10429        synchronized (this) {
10430            return new Point(mThumbnailWidth,  mThumbnailHeight);
10431        }
10432    }
10433
10434    @Override
10435    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10436        synchronized (this) {
10437            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10438            if (r != null) {
10439                r.setTaskDescription(td);
10440                final TaskRecord task = r.getTask();
10441                task.updateTaskDescription();
10442                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10443            }
10444        }
10445    }
10446
10447    @Override
10448    public void setTaskResizeable(int taskId, int resizeableMode) {
10449        synchronized (this) {
10450            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10451                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10452            if (task == null) {
10453                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10454                return;
10455            }
10456            task.setResizeMode(resizeableMode);
10457        }
10458    }
10459
10460    @Override
10461    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10462        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10463        long ident = Binder.clearCallingIdentity();
10464        try {
10465            synchronized (this) {
10466                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10467                if (task == null) {
10468                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10469                    return;
10470                }
10471                // Place the task in the right stack if it isn't there already based on
10472                // the requested bounds.
10473                // The stack transition logic is:
10474                // - a null bounds on a freeform task moves that task to fullscreen
10475                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10476                //   that task to freeform
10477                // - otherwise the task is not moved
10478                ActivityStack stack = task.getStack();
10479                if (!task.getWindowConfiguration().canResizeTask()) {
10480                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10481                }
10482                if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10483                    stack = stack.getDisplay().getOrCreateStack(
10484                            WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10485                } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10486                    stack = stack.getDisplay().getOrCreateStack(
10487                            WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10488                }
10489
10490                // Reparent the task to the right stack if necessary
10491                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10492                if (stack != task.getStack()) {
10493                    // Defer resume until the task is resized below
10494                    task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10495                            DEFER_RESUME, "resizeTask");
10496                    preserveWindow = false;
10497                }
10498
10499                // After reparenting (which only resizes the task to the stack bounds), resize the
10500                // task to the actual bounds provided
10501                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10502            }
10503        } finally {
10504            Binder.restoreCallingIdentity(ident);
10505        }
10506    }
10507
10508    @Override
10509    public Rect getTaskBounds(int taskId) {
10510        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10511        long ident = Binder.clearCallingIdentity();
10512        Rect rect = new Rect();
10513        try {
10514            synchronized (this) {
10515                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10516                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10517                if (task == null) {
10518                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10519                    return rect;
10520                }
10521                if (task.getStack() != null) {
10522                    // Return the bounds from window manager since it will be adjusted for various
10523                    // things like the presense of a docked stack for tasks that aren't resizeable.
10524                    task.getWindowContainerBounds(rect);
10525                } else {
10526                    // Task isn't in window manager yet since it isn't associated with a stack.
10527                    // Return the persist value from activity manager
10528                    if (!task.matchParentBounds()) {
10529                        rect.set(task.getBounds());
10530                    } else if (task.mLastNonFullscreenBounds != null) {
10531                        rect.set(task.mLastNonFullscreenBounds);
10532                    }
10533                }
10534            }
10535        } finally {
10536            Binder.restoreCallingIdentity(ident);
10537        }
10538        return rect;
10539    }
10540
10541    @Override
10542    public void cancelTaskWindowTransition(int taskId) {
10543        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10544                "cancelTaskWindowTransition()");
10545        final long ident = Binder.clearCallingIdentity();
10546        try {
10547            synchronized (this) {
10548                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10549                        MATCH_TASK_IN_STACKS_ONLY);
10550                if (task == null) {
10551                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10552                    return;
10553                }
10554                task.cancelWindowTransition();
10555            }
10556        } finally {
10557            Binder.restoreCallingIdentity(ident);
10558        }
10559    }
10560
10561    @Override
10562    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10563        enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10564        final long ident = Binder.clearCallingIdentity();
10565        try {
10566            final TaskRecord task;
10567            synchronized (this) {
10568                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10569                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10570                if (task == null) {
10571                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10572                    return null;
10573                }
10574            }
10575            // Don't call this while holding the lock as this operation might hit the disk.
10576            return task.getSnapshot(reducedResolution);
10577        } finally {
10578            Binder.restoreCallingIdentity(ident);
10579        }
10580    }
10581
10582    @Override
10583    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10584        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10585                userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
10586
10587        final File passedIconFile = new File(filePath);
10588        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10589                passedIconFile.getName());
10590        if (!legitIconFile.getPath().equals(filePath)
10591                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10592            throw new IllegalArgumentException("Bad file path: " + filePath
10593                    + " passed for userId " + userId);
10594        }
10595        return mRecentTasks.getTaskDescriptionIcon(filePath);
10596    }
10597
10598    @Override
10599    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10600            throws RemoteException {
10601        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
10602        final ActivityOptions activityOptions = safeOptions != null
10603                ? safeOptions.getOptions(mStackSupervisor)
10604                : null;
10605        if (activityOptions == null
10606                || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
10607                || activityOptions.getCustomInPlaceResId() == 0) {
10608            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10609                    "with valid animation");
10610        }
10611        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10612        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10613                activityOptions.getCustomInPlaceResId());
10614        mWindowManager.executeAppTransition();
10615    }
10616
10617    @Override
10618    public void removeStack(int stackId) {
10619        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
10620        synchronized (this) {
10621            final long ident = Binder.clearCallingIdentity();
10622            try {
10623                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10624                if (stack == null) {
10625                    Slog.w(TAG, "removeStack: No stack with id=" + stackId);
10626                    return;
10627                }
10628                if (!stack.isActivityTypeStandardOrUndefined()) {
10629                    throw new IllegalArgumentException(
10630                            "Removing non-standard stack is not allowed.");
10631                }
10632                mStackSupervisor.removeStack(stack);
10633            } finally {
10634                Binder.restoreCallingIdentity(ident);
10635            }
10636        }
10637    }
10638
10639    /**
10640     * Removes stacks in the input windowing modes from the system if they are of activity type
10641     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
10642     */
10643    @Override
10644    public void removeStacksInWindowingModes(int[] windowingModes) {
10645        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10646                "removeStacksInWindowingModes()");
10647        synchronized (this) {
10648            final long ident = Binder.clearCallingIdentity();
10649            try {
10650                mStackSupervisor.removeStacksInWindowingModes(windowingModes);
10651            } finally {
10652                Binder.restoreCallingIdentity(ident);
10653            }
10654        }
10655    }
10656
10657    @Override
10658    public void removeStacksWithActivityTypes(int[] activityTypes) {
10659        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10660                "removeStacksWithActivityTypes()");
10661        synchronized (this) {
10662            final long ident = Binder.clearCallingIdentity();
10663            try {
10664                mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
10665            } finally {
10666                Binder.restoreCallingIdentity(ident);
10667            }
10668        }
10669    }
10670
10671    @Override
10672    public void moveStackToDisplay(int stackId, int displayId) {
10673        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10674
10675        synchronized (this) {
10676            final long ident = Binder.clearCallingIdentity();
10677            try {
10678                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10679                        + " to displayId=" + displayId);
10680                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10681            } finally {
10682                Binder.restoreCallingIdentity(ident);
10683            }
10684        }
10685    }
10686
10687    @Override
10688    public boolean removeTask(int taskId) {
10689        enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
10690        synchronized (this) {
10691            final long ident = Binder.clearCallingIdentity();
10692            try {
10693                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
10694                        "remove-task");
10695            } finally {
10696                Binder.restoreCallingIdentity(ident);
10697            }
10698        }
10699    }
10700
10701    /**
10702     * TODO: Add mController hook
10703     */
10704    @Override
10705    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10706        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10707
10708        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10709        synchronized(this) {
10710            moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
10711                    false /* fromRecents */);
10712        }
10713    }
10714
10715    void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
10716            boolean fromRecents) {
10717
10718        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10719                Binder.getCallingUid(), -1, -1, "Task to front")) {
10720            SafeActivityOptions.abort(options);
10721            return;
10722        }
10723        final long origId = Binder.clearCallingIdentity();
10724        try {
10725            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10726            if (task == null) {
10727                Slog.d(TAG, "Could not find task for id: "+ taskId);
10728                return;
10729            }
10730            if (mLockTaskController.isLockTaskModeViolation(task)) {
10731                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10732                return;
10733            }
10734            ActivityOptions realOptions = options != null
10735                    ? options.getOptions(mStackSupervisor)
10736                    : null;
10737            mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
10738                    false /* forceNonResizable */);
10739
10740            final ActivityRecord topActivity = task.getTopActivity();
10741            if (topActivity != null) {
10742
10743                // We are reshowing a task, use a starting window to hide the initial draw delay
10744                // so the transition can start earlier.
10745                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10746                        true /* taskSwitch */, fromRecents);
10747            }
10748        } finally {
10749            Binder.restoreCallingIdentity(origId);
10750        }
10751        SafeActivityOptions.abort(options);
10752    }
10753
10754    /**
10755     * Attempts to move a task backwards in z-order (the order of activities within the task is
10756     * unchanged).
10757     *
10758     * There are several possible results of this call:
10759     * - if the task is locked, then we will show the lock toast
10760     * - if there is a task behind the provided task, then that task is made visible and resumed as
10761     *   this task is moved to the back
10762     * - otherwise, if there are no other tasks in the stack:
10763     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10764     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10765     *       (depending on whether it is visible)
10766     *     - otherwise, we simply return home and hide this task
10767     *
10768     * @param token A reference to the activity we wish to move
10769     * @param nonRoot If false then this only works if the activity is the root
10770     *                of a task; if true it will work for any activity in a task.
10771     * @return Returns true if the move completed, false if not.
10772     */
10773    @Override
10774    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10775        enforceNotIsolatedCaller("moveActivityTaskToBack");
10776        synchronized(this) {
10777            final long origId = Binder.clearCallingIdentity();
10778            try {
10779                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10780                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10781                if (task != null) {
10782                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10783                }
10784            } finally {
10785                Binder.restoreCallingIdentity(origId);
10786            }
10787        }
10788        return false;
10789    }
10790
10791    @Override
10792    public void moveTaskBackwards(int task) {
10793        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10794                "moveTaskBackwards()");
10795
10796        synchronized(this) {
10797            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10798                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10799                return;
10800            }
10801            final long origId = Binder.clearCallingIdentity();
10802            moveTaskBackwardsLocked(task);
10803            Binder.restoreCallingIdentity(origId);
10804        }
10805    }
10806
10807    private final void moveTaskBackwardsLocked(int task) {
10808        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10809    }
10810
10811    @Override
10812    public int createStackOnDisplay(int displayId) throws RemoteException {
10813        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10814        synchronized (this) {
10815            final ActivityDisplay display =
10816                    mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
10817            if (display == null) {
10818                return INVALID_STACK_ID;
10819            }
10820            // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
10821            final ActivityStack stack = display.createStack(
10822                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
10823                    ON_TOP);
10824            return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
10825        }
10826    }
10827
10828    @Override
10829    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10830        synchronized (this) {
10831            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10832            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10833                return stack.mDisplayId;
10834            }
10835            return DEFAULT_DISPLAY;
10836        }
10837    }
10838
10839    @Override
10840    public void exitFreeformMode(IBinder token) throws RemoteException {
10841        synchronized (this) {
10842            long ident = Binder.clearCallingIdentity();
10843            try {
10844                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10845                if (r == null) {
10846                    throw new IllegalArgumentException(
10847                            "exitFreeformMode: No activity record matching token=" + token);
10848                }
10849
10850                final ActivityStack stack = r.getStack();
10851                if (stack == null || !stack.inFreeformWindowingMode()) {
10852                    throw new IllegalStateException(
10853                            "exitFreeformMode: You can only go fullscreen from freeform.");
10854                }
10855
10856                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
10857            } finally {
10858                Binder.restoreCallingIdentity(ident);
10859            }
10860        }
10861    }
10862
10863    @Override
10864    public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
10865        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
10866            setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
10867                    toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
10868            return;
10869        }
10870        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
10871        synchronized (this) {
10872            final long ident = Binder.clearCallingIdentity();
10873            try {
10874                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10875                if (task == null) {
10876                    Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
10877                    return;
10878                }
10879
10880                if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
10881                        + " to windowingMode=" + windowingMode + " toTop=" + toTop);
10882
10883                if (!task.isActivityTypeStandardOrUndefined()) {
10884                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
10885                            + " non-standard task " + taskId + " to windowing mode="
10886                            + windowingMode);
10887                }
10888
10889                final ActivityStack stack = task.getStack();
10890                if (toTop) {
10891                    stack.moveToFront("setTaskWindowingMode", task);
10892                }
10893                stack.setWindowingMode(windowingMode);
10894            } finally {
10895                Binder.restoreCallingIdentity(ident);
10896            }
10897        }
10898    }
10899
10900    /**
10901     * Moves the specified task to the primary-split-screen stack.
10902     *
10903     * @param taskId Id of task to move.
10904     * @param createMode The mode the primary split screen stack should be created in if it doesn't
10905     *                   exist already. See
10906     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
10907     *                   and
10908     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
10909     * @param toTop If the task and stack should be moved to the top.
10910     * @param animate Whether we should play an animation for the moving the task.
10911     * @param initialBounds If the primary stack gets created, it will use these bounds for the
10912     *                      stack. Pass {@code null} to use default bounds.
10913     * @param showRecents If the recents activity should be shown on the other side of the task
10914     *                    going into split-screen mode.
10915     */
10916    @Override
10917    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
10918            boolean animate, Rect initialBounds, boolean showRecents) {
10919        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10920                "setTaskWindowingModeSplitScreenPrimary()");
10921        synchronized (this) {
10922            long ident = Binder.clearCallingIdentity();
10923            try {
10924                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10925                if (task == null) {
10926                    Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
10927                    return false;
10928                }
10929                if (DEBUG_STACK) Slog.d(TAG_STACK,
10930                        "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
10931                        + " to createMode=" + createMode + " toTop=" + toTop);
10932                if (!task.isActivityTypeStandardOrUndefined()) {
10933                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
10934                            + " non-standard task " + taskId + " to split-screen windowing mode");
10935                }
10936
10937                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10938                final int windowingMode = task.getWindowingMode();
10939                final ActivityStack stack = task.getStack();
10940                if (toTop) {
10941                    stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
10942                }
10943                stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
10944                        false /* enteringSplitScreenMode */);
10945                return windowingMode != task.getWindowingMode();
10946            } finally {
10947                Binder.restoreCallingIdentity(ident);
10948            }
10949        }
10950    }
10951
10952    @Override
10953    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10954        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10955        synchronized (this) {
10956            long ident = Binder.clearCallingIdentity();
10957            try {
10958                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10959                if (task == null) {
10960                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10961                    return;
10962                }
10963
10964                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10965                        + " to stackId=" + stackId + " toTop=" + toTop);
10966
10967                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10968                if (stack == null) {
10969                    throw new IllegalStateException(
10970                            "moveTaskToStack: No stack for stackId=" + stackId);
10971                }
10972                if (!stack.isActivityTypeStandardOrUndefined()) {
10973                    throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
10974                            + taskId + " to stack " + stackId);
10975                }
10976                if (stack.inSplitScreenPrimaryWindowingMode()) {
10977                    mWindowManager.setDockedStackCreateState(
10978                            SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
10979                }
10980                task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
10981                        "moveTaskToStack");
10982            } finally {
10983                Binder.restoreCallingIdentity(ident);
10984            }
10985        }
10986    }
10987
10988    /**
10989     * Dismisses split-screen multi-window mode.
10990     * @param toTop If true the current primary split-screen stack will be placed or left on top.
10991     */
10992    @Override
10993    public void dismissSplitScreenMode(boolean toTop) {
10994        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
10995        final long ident = Binder.clearCallingIdentity();
10996        try {
10997            synchronized (this) {
10998                final ActivityStack stack =
10999                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
11000                if (stack == null) {
11001                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
11002                    return;
11003                }
11004
11005                if (toTop) {
11006                    // Caller wants the current split-screen primary stack to be the top stack after
11007                    // it goes fullscreen, so move it to the front.
11008                    stack.moveToFront("dismissSplitScreenMode");
11009                } else if (mStackSupervisor.isFocusedStack(stack)) {
11010                    // In this case the current split-screen primary stack shouldn't be the top
11011                    // stack after it goes fullscreen, but it current has focus, so we move the
11012                    // focus to the top-most split-screen secondary stack next to it.
11013                    final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
11014                            WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
11015                    if (otherStack != null) {
11016                        otherStack.moveToFront("dismissSplitScreenMode_other");
11017                    }
11018                }
11019
11020                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11021            }
11022        } finally {
11023            Binder.restoreCallingIdentity(ident);
11024        }
11025    }
11026
11027    /**
11028     * Dismisses Pip
11029     * @param animate True if the dismissal should be animated.
11030     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
11031     *                          default animation duration should be used.
11032     */
11033    @Override
11034    public void dismissPip(boolean animate, int animationDuration) {
11035        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
11036        final long ident = Binder.clearCallingIdentity();
11037        try {
11038            synchronized (this) {
11039                final PinnedActivityStack stack =
11040                        mStackSupervisor.getDefaultDisplay().getPinnedStack();
11041                if (stack == null) {
11042                    Slog.w(TAG, "dismissPip: pinned stack not found.");
11043                    return;
11044                }
11045                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11046                    throw new IllegalArgumentException("Stack: " + stack
11047                            + " doesn't support animated resize.");
11048                }
11049                if (animate) {
11050                    stack.animateResizePinnedStack(null /* sourceHintBounds */,
11051                            null /* destBounds */, animationDuration, false /* fromFullscreen */);
11052                } else {
11053                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
11054                }
11055            }
11056        } finally {
11057            Binder.restoreCallingIdentity(ident);
11058        }
11059    }
11060
11061    /**
11062     * Moves the top activity in the input stackId to the pinned stack.
11063     *
11064     * @param stackId Id of stack to move the top activity to pinned stack.
11065     * @param bounds Bounds to use for pinned stack.
11066     *
11067     * @return True if the top activity of the input stack was successfully moved to the pinned
11068     *          stack.
11069     */
11070    @Override
11071    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
11072        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11073                "moveTopActivityToPinnedStack()");
11074        synchronized (this) {
11075            if (!mSupportsPictureInPicture) {
11076                throw new IllegalStateException("moveTopActivityToPinnedStack:"
11077                        + "Device doesn't support picture-in-picture mode");
11078            }
11079
11080            long ident = Binder.clearCallingIdentity();
11081            try {
11082                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
11083            } finally {
11084                Binder.restoreCallingIdentity(ident);
11085            }
11086        }
11087    }
11088
11089    @Override
11090    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
11091            boolean preserveWindows, boolean animate, int animationDuration) {
11092        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
11093        long ident = Binder.clearCallingIdentity();
11094        try {
11095            synchronized (this) {
11096                if (animate) {
11097                    final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
11098                    if (stack == null) {
11099                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11100                        return;
11101                    }
11102                    if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11103                        throw new IllegalArgumentException("Stack: " + stackId
11104                                + " doesn't support animated resize.");
11105                    }
11106                    stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11107                            animationDuration, false /* fromFullscreen */);
11108                } else {
11109                    final ActivityStack stack = mStackSupervisor.getStack(stackId);
11110                    if (stack == null) {
11111                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11112                        return;
11113                    }
11114                    mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11115                            null /* tempTaskInsetBounds */, preserveWindows,
11116                            allowResizeInDockedMode, !DEFER_RESUME);
11117                }
11118            }
11119        } finally {
11120            Binder.restoreCallingIdentity(ident);
11121        }
11122    }
11123
11124    @Override
11125    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
11126            Rect tempDockedTaskInsetBounds,
11127            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
11128        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
11129        long ident = Binder.clearCallingIdentity();
11130        try {
11131            synchronized (this) {
11132                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11133                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11134                        PRESERVE_WINDOWS);
11135            }
11136        } finally {
11137            Binder.restoreCallingIdentity(ident);
11138        }
11139    }
11140
11141    @Override
11142    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11143        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11144        final long ident = Binder.clearCallingIdentity();
11145        try {
11146            synchronized (this) {
11147                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11148            }
11149        } finally {
11150            Binder.restoreCallingIdentity(ident);
11151        }
11152    }
11153
11154    /**
11155     * Try to place task to provided position. The final position might be different depending on
11156     * current user and stacks state. The task will be moved to target stack if it's currently in
11157     * different stack.
11158     */
11159    @Override
11160    public void positionTaskInStack(int taskId, int stackId, int position) {
11161        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11162        synchronized (this) {
11163            long ident = Binder.clearCallingIdentity();
11164            try {
11165                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
11166                        + taskId + " in stackId=" + stackId + " at position=" + position);
11167                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11168                if (task == null) {
11169                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
11170                            + taskId);
11171                }
11172
11173                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11174
11175                if (stack == null) {
11176                    throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11177                            + stackId);
11178                }
11179                if (!stack.isActivityTypeStandardOrUndefined()) {
11180                    throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11181                            + " the position of task " + taskId + " in/to non-standard stack");
11182                }
11183
11184                // TODO: Have the callers of this API call a separate reparent method if that is
11185                // what they intended to do vs. having this method also do reparenting.
11186                if (task.getStack() == stack) {
11187                    // Change position in current stack.
11188                    stack.positionChildAt(task, position);
11189                } else {
11190                    // Reparent to new stack.
11191                    task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11192                            !DEFER_RESUME, "positionTaskInStack");
11193                }
11194            } finally {
11195                Binder.restoreCallingIdentity(ident);
11196            }
11197        }
11198    }
11199
11200    @Override
11201    public List<StackInfo> getAllStackInfos() {
11202        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11203        long ident = Binder.clearCallingIdentity();
11204        try {
11205            synchronized (this) {
11206                return mStackSupervisor.getAllStackInfosLocked();
11207            }
11208        } finally {
11209            Binder.restoreCallingIdentity(ident);
11210        }
11211    }
11212
11213    @Override
11214    public StackInfo getStackInfo(int windowingMode, int activityType) {
11215        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11216        long ident = Binder.clearCallingIdentity();
11217        try {
11218            synchronized (this) {
11219                return mStackSupervisor.getStackInfo(windowingMode, activityType);
11220            }
11221        } finally {
11222            Binder.restoreCallingIdentity(ident);
11223        }
11224    }
11225
11226    @Override
11227    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11228        synchronized(this) {
11229            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11230        }
11231    }
11232
11233    @Override
11234    public void updateDeviceOwner(String packageName) {
11235        final int callingUid = Binder.getCallingUid();
11236        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11237            throw new SecurityException("updateDeviceOwner called from non-system process");
11238        }
11239        synchronized (this) {
11240            mDeviceOwnerName = packageName;
11241        }
11242    }
11243
11244    @Override
11245    public void updateLockTaskPackages(int userId, String[] packages) {
11246        final int callingUid = Binder.getCallingUid();
11247        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11248            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11249                    "updateLockTaskPackages()");
11250        }
11251        synchronized (this) {
11252            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11253                    Arrays.toString(packages));
11254            mLockTaskController.updateLockTaskPackages(userId, packages);
11255        }
11256    }
11257
11258    @Override
11259    public void updateLockTaskFeatures(int userId, int flags) {
11260        final int callingUid = Binder.getCallingUid();
11261        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11262            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11263                    "updateLockTaskFeatures()");
11264        }
11265        synchronized (this) {
11266            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11267                    Integer.toHexString(flags));
11268            mLockTaskController.updateLockTaskFeatures(userId, flags);
11269        }
11270    }
11271
11272    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11273        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11274        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11275            return;
11276        }
11277
11278        final ActivityStack stack = mStackSupervisor.getFocusedStack();
11279        if (stack == null || task != stack.topTask()) {
11280            throw new IllegalArgumentException("Invalid task, not in foreground");
11281        }
11282
11283        // When a task is locked, dismiss the pinned stack if it exists
11284        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11285
11286        // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11287        // system or a specific app.
11288        // * System-initiated requests will only start the pinned mode (screen pinning)
11289        // * App-initiated requests
11290        //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
11291        //   - will start the pinned mode, otherwise
11292        final int callingUid = Binder.getCallingUid();
11293        long ident = Binder.clearCallingIdentity();
11294        try {
11295            mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11296        } finally {
11297            Binder.restoreCallingIdentity(ident);
11298        }
11299    }
11300
11301    @Override
11302    public void startLockTaskModeByToken(IBinder token) {
11303        synchronized (this) {
11304            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11305            if (r == null) {
11306                return;
11307            }
11308            startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11309        }
11310    }
11311
11312    @Override
11313    public void startSystemLockTaskMode(int taskId) throws RemoteException {
11314        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11315        // This makes inner call to look as if it was initiated by system.
11316        long ident = Binder.clearCallingIdentity();
11317        try {
11318            synchronized (this) {
11319                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11320
11321                // When starting lock task mode the stack must be in front and focused
11322                task.getStack().moveToFront("startSystemLockTaskMode");
11323                startLockTaskModeLocked(task, true /* isSystemCaller */);
11324            }
11325        } finally {
11326            Binder.restoreCallingIdentity(ident);
11327        }
11328    }
11329
11330    @Override
11331    public void stopLockTaskModeByToken(IBinder token) {
11332        synchronized (this) {
11333            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11334            if (r == null) {
11335                return;
11336            }
11337            stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11338        }
11339    }
11340
11341    /**
11342     * This API should be called by SystemUI only when user perform certain action to dismiss
11343     * lock task mode. We should only dismiss pinned lock task mode in this case.
11344     */
11345    @Override
11346    public void stopSystemLockTaskMode() throws RemoteException {
11347        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11348        stopLockTaskModeInternal(null, true /* isSystemCaller */);
11349    }
11350
11351    private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11352        final int callingUid = Binder.getCallingUid();
11353        long ident = Binder.clearCallingIdentity();
11354        try {
11355            synchronized (this) {
11356                mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11357            }
11358            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11359            // task and jumping straight into a call in the case of emergency call back.
11360            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11361            if (tm != null) {
11362                tm.showInCallScreen(false);
11363            }
11364        } finally {
11365            Binder.restoreCallingIdentity(ident);
11366        }
11367    }
11368
11369    @Override
11370    public boolean isInLockTaskMode() {
11371        return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11372    }
11373
11374    @Override
11375    public int getLockTaskModeState() {
11376        synchronized (this) {
11377            return mLockTaskController.getLockTaskModeState();
11378        }
11379    }
11380
11381    @Override
11382    public void showLockTaskEscapeMessage(IBinder token) {
11383        synchronized (this) {
11384            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11385            if (r == null) {
11386                return;
11387            }
11388            mLockTaskController.showLockTaskToast();
11389        }
11390    }
11391
11392    @Override
11393    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11394            throws RemoteException {
11395        synchronized (this) {
11396            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11397            if (r == null) {
11398                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11399                        + token);
11400                return;
11401            }
11402            final long origId = Binder.clearCallingIdentity();
11403            try {
11404                r.setDisablePreviewScreenshots(disable);
11405            } finally {
11406                Binder.restoreCallingIdentity(origId);
11407            }
11408        }
11409    }
11410
11411    // =========================================================
11412    // CONTENT PROVIDERS
11413    // =========================================================
11414
11415    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11416        List<ProviderInfo> providers = null;
11417        try {
11418            providers = AppGlobals.getPackageManager()
11419                    .queryContentProviders(app.processName, app.uid,
11420                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11421                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11422                    .getList();
11423        } catch (RemoteException ex) {
11424        }
11425        if (DEBUG_MU) Slog.v(TAG_MU,
11426                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11427        int userId = app.userId;
11428        if (providers != null) {
11429            int N = providers.size();
11430            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11431            for (int i=0; i<N; i++) {
11432                // TODO: keep logic in sync with installEncryptionUnawareProviders
11433                ProviderInfo cpi =
11434                    (ProviderInfo)providers.get(i);
11435                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11436                        cpi.name, cpi.flags);
11437                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11438                    // This is a singleton provider, but a user besides the
11439                    // default user is asking to initialize a process it runs
11440                    // in...  well, no, it doesn't actually run in this process,
11441                    // it runs in the process of the default user.  Get rid of it.
11442                    providers.remove(i);
11443                    N--;
11444                    i--;
11445                    continue;
11446                }
11447
11448                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11449                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11450                if (cpr == null) {
11451                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11452                    mProviderMap.putProviderByClass(comp, cpr);
11453                }
11454                if (DEBUG_MU) Slog.v(TAG_MU,
11455                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11456                app.pubProviders.put(cpi.name, cpr);
11457                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11458                    // Don't add this if it is a platform component that is marked
11459                    // to run in multiple processes, because this is actually
11460                    // part of the framework so doesn't make sense to track as a
11461                    // separate apk in the process.
11462                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11463                            mProcessStats);
11464                }
11465                notifyPackageUse(cpi.applicationInfo.packageName,
11466                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11467            }
11468        }
11469        return providers;
11470    }
11471
11472    /**
11473     * Check if the calling UID has a possible chance at accessing the provider
11474     * at the given authority and user.
11475     */
11476    public String checkContentProviderAccess(String authority, int userId) {
11477        if (userId == UserHandle.USER_ALL) {
11478            mContext.enforceCallingOrSelfPermission(
11479                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11480            userId = UserHandle.getCallingUserId();
11481        }
11482
11483        ProviderInfo cpi = null;
11484        try {
11485            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11486                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11487                            | PackageManager.MATCH_DISABLED_COMPONENTS
11488                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11489                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11490                    userId);
11491        } catch (RemoteException ignored) {
11492        }
11493        if (cpi == null) {
11494            return "Failed to find provider " + authority + " for user " + userId
11495                    + "; expected to find a valid ContentProvider for this authority";
11496        }
11497
11498        ProcessRecord r = null;
11499        synchronized (mPidsSelfLocked) {
11500            r = mPidsSelfLocked.get(Binder.getCallingPid());
11501        }
11502        if (r == null) {
11503            return "Failed to find PID " + Binder.getCallingPid();
11504        }
11505
11506        synchronized (this) {
11507            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11508        }
11509    }
11510
11511    /**
11512     * Check if {@link ProcessRecord} has a possible chance at accessing the
11513     * given {@link ProviderInfo}. Final permission checking is always done
11514     * in {@link ContentProvider}.
11515     */
11516    private final String checkContentProviderPermissionLocked(
11517            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11518        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11519        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11520        boolean checkedGrants = false;
11521        if (checkUser) {
11522            // Looking for cross-user grants before enforcing the typical cross-users permissions
11523            int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11524            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11525                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11526                    return null;
11527                }
11528                checkedGrants = true;
11529            }
11530            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11531                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11532            if (userId != tmpTargetUserId) {
11533                // When we actually went to determine the final targer user ID, this ended
11534                // up different than our initial check for the authority.  This is because
11535                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11536                // SELF.  So we need to re-check the grants again.
11537                checkedGrants = false;
11538            }
11539        }
11540        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11541                cpi.applicationInfo.uid, cpi.exported)
11542                == PackageManager.PERMISSION_GRANTED) {
11543            return null;
11544        }
11545        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11546                cpi.applicationInfo.uid, cpi.exported)
11547                == PackageManager.PERMISSION_GRANTED) {
11548            return null;
11549        }
11550
11551        PathPermission[] pps = cpi.pathPermissions;
11552        if (pps != null) {
11553            int i = pps.length;
11554            while (i > 0) {
11555                i--;
11556                PathPermission pp = pps[i];
11557                String pprperm = pp.getReadPermission();
11558                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11559                        cpi.applicationInfo.uid, cpi.exported)
11560                        == PackageManager.PERMISSION_GRANTED) {
11561                    return null;
11562                }
11563                String ppwperm = pp.getWritePermission();
11564                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11565                        cpi.applicationInfo.uid, cpi.exported)
11566                        == PackageManager.PERMISSION_GRANTED) {
11567                    return null;
11568                }
11569            }
11570        }
11571        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11572            return null;
11573        }
11574
11575        final String suffix;
11576        if (!cpi.exported) {
11577            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11578        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11579            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11580        } else {
11581            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11582        }
11583        final String msg = "Permission Denial: opening provider " + cpi.name
11584                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11585                + ", uid=" + callingUid + ")" + suffix;
11586        Slog.w(TAG, msg);
11587        return msg;
11588    }
11589
11590    /**
11591     * Returns if the ContentProvider has granted a uri to callingUid
11592     */
11593    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11594        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11595        if (perms != null) {
11596            for (int i=perms.size()-1; i>=0; i--) {
11597                GrantUri grantUri = perms.keyAt(i);
11598                if (grantUri.sourceUserId == userId || !checkUser) {
11599                    if (matchesProvider(grantUri.uri, cpi)) {
11600                        return true;
11601                    }
11602                }
11603            }
11604        }
11605        return false;
11606    }
11607
11608    /**
11609     * Returns true if the uri authority is one of the authorities specified in the provider.
11610     */
11611    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11612        String uriAuth = uri.getAuthority();
11613        String cpiAuth = cpi.authority;
11614        if (cpiAuth.indexOf(';') == -1) {
11615            return cpiAuth.equals(uriAuth);
11616        }
11617        String[] cpiAuths = cpiAuth.split(";");
11618        int length = cpiAuths.length;
11619        for (int i = 0; i < length; i++) {
11620            if (cpiAuths[i].equals(uriAuth)) return true;
11621        }
11622        return false;
11623    }
11624
11625    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11626            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11627        if (r != null) {
11628            for (int i=0; i<r.conProviders.size(); i++) {
11629                ContentProviderConnection conn = r.conProviders.get(i);
11630                if (conn.provider == cpr) {
11631                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11632                            "Adding provider requested by "
11633                            + r.processName + " from process "
11634                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11635                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11636                    if (stable) {
11637                        conn.stableCount++;
11638                        conn.numStableIncs++;
11639                    } else {
11640                        conn.unstableCount++;
11641                        conn.numUnstableIncs++;
11642                    }
11643                    return conn;
11644                }
11645            }
11646            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11647            if (stable) {
11648                conn.stableCount = 1;
11649                conn.numStableIncs = 1;
11650            } else {
11651                conn.unstableCount = 1;
11652                conn.numUnstableIncs = 1;
11653            }
11654            cpr.connections.add(conn);
11655            r.conProviders.add(conn);
11656            startAssociationLocked(r.uid, r.processName, r.curProcState,
11657                    cpr.uid, cpr.name, cpr.info.processName);
11658            return conn;
11659        }
11660        cpr.addExternalProcessHandleLocked(externalProcessToken);
11661        return null;
11662    }
11663
11664    boolean decProviderCountLocked(ContentProviderConnection conn,
11665            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11666        if (conn != null) {
11667            cpr = conn.provider;
11668            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11669                    "Removing provider requested by "
11670                    + conn.client.processName + " from process "
11671                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11672                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11673            if (stable) {
11674                conn.stableCount--;
11675            } else {
11676                conn.unstableCount--;
11677            }
11678            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11679                cpr.connections.remove(conn);
11680                conn.client.conProviders.remove(conn);
11681                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11682                    // The client is more important than last activity -- note the time this
11683                    // is happening, so we keep the old provider process around a bit as last
11684                    // activity to avoid thrashing it.
11685                    if (cpr.proc != null) {
11686                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11687                    }
11688                }
11689                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11690                return true;
11691            }
11692            return false;
11693        }
11694        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11695        return false;
11696    }
11697
11698    private void checkTime(long startTime, String where) {
11699        long now = SystemClock.uptimeMillis();
11700        if ((now-startTime) > 50) {
11701            // If we are taking more than 50ms, log about it.
11702            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11703        }
11704    }
11705
11706    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11707            PROC_SPACE_TERM,
11708            PROC_SPACE_TERM|PROC_PARENS,
11709            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11710    };
11711
11712    private final long[] mProcessStateStatsLongs = new long[1];
11713
11714    private boolean isProcessAliveLocked(ProcessRecord proc) {
11715        if (proc.pid <= 0) {
11716            if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
11717            return false;
11718        }
11719        if (proc.procStatFile == null) {
11720            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11721        }
11722        mProcessStateStatsLongs[0] = 0;
11723        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11724                mProcessStateStatsLongs, null)) {
11725            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11726            return false;
11727        }
11728        final long state = mProcessStateStatsLongs[0];
11729        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11730                + (char)state);
11731        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11732    }
11733
11734    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11735            String name, IBinder token, boolean stable, int userId) {
11736        ContentProviderRecord cpr;
11737        ContentProviderConnection conn = null;
11738        ProviderInfo cpi = null;
11739
11740        synchronized(this) {
11741            long startTime = SystemClock.uptimeMillis();
11742
11743            ProcessRecord r = null;
11744            if (caller != null) {
11745                r = getRecordForAppLocked(caller);
11746                if (r == null) {
11747                    throw new SecurityException(
11748                            "Unable to find app for caller " + caller
11749                          + " (pid=" + Binder.getCallingPid()
11750                          + ") when getting content provider " + name);
11751                }
11752            }
11753
11754            boolean checkCrossUser = true;
11755
11756            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11757
11758            // First check if this content provider has been published...
11759            cpr = mProviderMap.getProviderByName(name, userId);
11760            // If that didn't work, check if it exists for user 0 and then
11761            // verify that it's a singleton provider before using it.
11762            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11763                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11764                if (cpr != null) {
11765                    cpi = cpr.info;
11766                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11767                            cpi.name, cpi.flags)
11768                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11769                        userId = UserHandle.USER_SYSTEM;
11770                        checkCrossUser = false;
11771                    } else {
11772                        cpr = null;
11773                        cpi = null;
11774                    }
11775                }
11776            }
11777
11778            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11779            if (providerRunning) {
11780                cpi = cpr.info;
11781                String msg;
11782                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11783                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11784                        != null) {
11785                    throw new SecurityException(msg);
11786                }
11787                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11788
11789                if (r != null && cpr.canRunHere(r)) {
11790                    // This provider has been published or is in the process
11791                    // of being published...  but it is also allowed to run
11792                    // in the caller's process, so don't make a connection
11793                    // and just let the caller instantiate its own instance.
11794                    ContentProviderHolder holder = cpr.newHolder(null);
11795                    // don't give caller the provider object, it needs
11796                    // to make its own.
11797                    holder.provider = null;
11798                    return holder;
11799                }
11800                // Don't expose providers between normal apps and instant apps
11801                try {
11802                    if (AppGlobals.getPackageManager()
11803                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11804                        return null;
11805                    }
11806                } catch (RemoteException e) {
11807                }
11808
11809                final long origId = Binder.clearCallingIdentity();
11810
11811                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11812
11813                // In this case the provider instance already exists, so we can
11814                // return it right away.
11815                conn = incProviderCountLocked(r, cpr, token, stable);
11816                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11817                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11818                        // If this is a perceptible app accessing the provider,
11819                        // make sure to count it as being accessed and thus
11820                        // back up on the LRU list.  This is good because
11821                        // content providers are often expensive to start.
11822                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11823                        updateLruProcessLocked(cpr.proc, false, null);
11824                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11825                    }
11826                }
11827
11828                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11829                final int verifiedAdj = cpr.proc.verifiedAdj;
11830                boolean success = updateOomAdjLocked(cpr.proc, true);
11831                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11832                // if the process has been successfully adjusted.  So to reduce races with
11833                // it, we will check whether the process still exists.  Note that this doesn't
11834                // completely get rid of races with LMK killing the process, but should make
11835                // them much smaller.
11836                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11837                    success = false;
11838                }
11839                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11840                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11841                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11842                // NOTE: there is still a race here where a signal could be
11843                // pending on the process even though we managed to update its
11844                // adj level.  Not sure what to do about this, but at least
11845                // the race is now smaller.
11846                if (!success) {
11847                    // Uh oh...  it looks like the provider's process
11848                    // has been killed on us.  We need to wait for a new
11849                    // process to be started, and make sure its death
11850                    // doesn't kill our process.
11851                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11852                            + " is crashing; detaching " + r);
11853                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11854                    checkTime(startTime, "getContentProviderImpl: before appDied");
11855                    appDiedLocked(cpr.proc);
11856                    checkTime(startTime, "getContentProviderImpl: after appDied");
11857                    if (!lastRef) {
11858                        // This wasn't the last ref our process had on
11859                        // the provider...  we have now been killed, bail.
11860                        return null;
11861                    }
11862                    providerRunning = false;
11863                    conn = null;
11864                } else {
11865                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11866                }
11867
11868                Binder.restoreCallingIdentity(origId);
11869            }
11870
11871            if (!providerRunning) {
11872                try {
11873                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11874                    cpi = AppGlobals.getPackageManager().
11875                        resolveContentProvider(name,
11876                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11877                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11878                } catch (RemoteException ex) {
11879                }
11880                if (cpi == null) {
11881                    return null;
11882                }
11883                // If the provider is a singleton AND
11884                // (it's a call within the same user || the provider is a
11885                // privileged app)
11886                // Then allow connecting to the singleton provider
11887                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11888                        cpi.name, cpi.flags)
11889                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11890                if (singleton) {
11891                    userId = UserHandle.USER_SYSTEM;
11892                }
11893                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11894                checkTime(startTime, "getContentProviderImpl: got app info for user");
11895
11896                String msg;
11897                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11898                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11899                        != null) {
11900                    throw new SecurityException(msg);
11901                }
11902                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11903
11904                if (!mProcessesReady
11905                        && !cpi.processName.equals("system")) {
11906                    // If this content provider does not run in the system
11907                    // process, and the system is not yet ready to run other
11908                    // processes, then fail fast instead of hanging.
11909                    throw new IllegalArgumentException(
11910                            "Attempt to launch content provider before system ready");
11911                }
11912
11913                // Make sure that the user who owns this provider is running.  If not,
11914                // we don't want to allow it to run.
11915                if (!mUserController.isUserRunning(userId, 0)) {
11916                    Slog.w(TAG, "Unable to launch app "
11917                            + cpi.applicationInfo.packageName + "/"
11918                            + cpi.applicationInfo.uid + " for provider "
11919                            + name + ": user " + userId + " is stopped");
11920                    return null;
11921                }
11922
11923                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11924                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11925                cpr = mProviderMap.getProviderByClass(comp, userId);
11926                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11927                final boolean firstClass = cpr == null;
11928                if (firstClass) {
11929                    final long ident = Binder.clearCallingIdentity();
11930
11931                    // If permissions need a review before any of the app components can run,
11932                    // we return no provider and launch a review activity if the calling app
11933                    // is in the foreground.
11934                    if (mPermissionReviewRequired) {
11935                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11936                            return null;
11937                        }
11938                    }
11939
11940                    try {
11941                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11942                        ApplicationInfo ai =
11943                            AppGlobals.getPackageManager().
11944                                getApplicationInfo(
11945                                        cpi.applicationInfo.packageName,
11946                                        STOCK_PM_FLAGS, userId);
11947                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11948                        if (ai == null) {
11949                            Slog.w(TAG, "No package info for content provider "
11950                                    + cpi.name);
11951                            return null;
11952                        }
11953                        ai = getAppInfoForUser(ai, userId);
11954                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11955                    } catch (RemoteException ex) {
11956                        // pm is in same process, this will never happen.
11957                    } finally {
11958                        Binder.restoreCallingIdentity(ident);
11959                    }
11960                }
11961
11962                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11963
11964                if (r != null && cpr.canRunHere(r)) {
11965                    // If this is a multiprocess provider, then just return its
11966                    // info and allow the caller to instantiate it.  Only do
11967                    // this if the provider is the same user as the caller's
11968                    // process, or can run as root (so can be in any process).
11969                    return cpr.newHolder(null);
11970                }
11971
11972                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11973                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11974                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11975
11976                // This is single process, and our app is now connecting to it.
11977                // See if we are already in the process of launching this
11978                // provider.
11979                final int N = mLaunchingProviders.size();
11980                int i;
11981                for (i = 0; i < N; i++) {
11982                    if (mLaunchingProviders.get(i) == cpr) {
11983                        break;
11984                    }
11985                }
11986
11987                // If the provider is not already being launched, then get it
11988                // started.
11989                if (i >= N) {
11990                    final long origId = Binder.clearCallingIdentity();
11991
11992                    try {
11993                        // Content provider is now in use, its package can't be stopped.
11994                        try {
11995                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11996                            AppGlobals.getPackageManager().setPackageStoppedState(
11997                                    cpr.appInfo.packageName, false, userId);
11998                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11999                        } catch (RemoteException e) {
12000                        } catch (IllegalArgumentException e) {
12001                            Slog.w(TAG, "Failed trying to unstop package "
12002                                    + cpr.appInfo.packageName + ": " + e);
12003                        }
12004
12005                        // Use existing process if already started
12006                        checkTime(startTime, "getContentProviderImpl: looking for process record");
12007                        ProcessRecord proc = getProcessRecordLocked(
12008                                cpi.processName, cpr.appInfo.uid, false);
12009                        if (proc != null && proc.thread != null && !proc.killed) {
12010                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
12011                                    "Installing in existing process " + proc);
12012                            if (!proc.pubProviders.containsKey(cpi.name)) {
12013                                checkTime(startTime, "getContentProviderImpl: scheduling install");
12014                                proc.pubProviders.put(cpi.name, cpr);
12015                                try {
12016                                    proc.thread.scheduleInstallProvider(cpi);
12017                                } catch (RemoteException e) {
12018                                }
12019                            }
12020                        } else {
12021                            checkTime(startTime, "getContentProviderImpl: before start process");
12022                            proc = startProcessLocked(cpi.processName,
12023                                    cpr.appInfo, false, 0, "content provider",
12024                                    new ComponentName(cpi.applicationInfo.packageName,
12025                                            cpi.name), false, false, false);
12026                            checkTime(startTime, "getContentProviderImpl: after start process");
12027                            if (proc == null) {
12028                                Slog.w(TAG, "Unable to launch app "
12029                                        + cpi.applicationInfo.packageName + "/"
12030                                        + cpi.applicationInfo.uid + " for provider "
12031                                        + name + ": process is bad");
12032                                return null;
12033                            }
12034                        }
12035                        cpr.launchingApp = proc;
12036                        mLaunchingProviders.add(cpr);
12037                    } finally {
12038                        Binder.restoreCallingIdentity(origId);
12039                    }
12040                }
12041
12042                checkTime(startTime, "getContentProviderImpl: updating data structures");
12043
12044                // Make sure the provider is published (the same provider class
12045                // may be published under multiple names).
12046                if (firstClass) {
12047                    mProviderMap.putProviderByClass(comp, cpr);
12048                }
12049
12050                mProviderMap.putProviderByName(name, cpr);
12051                conn = incProviderCountLocked(r, cpr, token, stable);
12052                if (conn != null) {
12053                    conn.waiting = true;
12054                }
12055            }
12056            checkTime(startTime, "getContentProviderImpl: done!");
12057
12058            grantEphemeralAccessLocked(userId, null /*intent*/,
12059                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
12060        }
12061
12062        // Wait for the provider to be published...
12063        synchronized (cpr) {
12064            while (cpr.provider == null) {
12065                if (cpr.launchingApp == null) {
12066                    Slog.w(TAG, "Unable to launch app "
12067                            + cpi.applicationInfo.packageName + "/"
12068                            + cpi.applicationInfo.uid + " for provider "
12069                            + name + ": launching app became null");
12070                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
12071                            UserHandle.getUserId(cpi.applicationInfo.uid),
12072                            cpi.applicationInfo.packageName,
12073                            cpi.applicationInfo.uid, name);
12074                    return null;
12075                }
12076                try {
12077                    if (DEBUG_MU) Slog.v(TAG_MU,
12078                            "Waiting to start provider " + cpr
12079                            + " launchingApp=" + cpr.launchingApp);
12080                    if (conn != null) {
12081                        conn.waiting = true;
12082                    }
12083                    cpr.wait();
12084                } catch (InterruptedException ex) {
12085                } finally {
12086                    if (conn != null) {
12087                        conn.waiting = false;
12088                    }
12089                }
12090            }
12091        }
12092        return cpr != null ? cpr.newHolder(conn) : null;
12093    }
12094
12095    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
12096            ProcessRecord r, final int userId) {
12097        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
12098                cpi.packageName, userId)) {
12099
12100            final boolean callerForeground = r == null || r.setSchedGroup
12101                    != ProcessList.SCHED_GROUP_BACKGROUND;
12102
12103            // Show a permission review UI only for starting from a foreground app
12104            if (!callerForeground) {
12105                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
12106                        + cpi.packageName + " requires a permissions review");
12107                return false;
12108            }
12109
12110            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
12111            intent.addFlags(FLAG_ACTIVITY_NEW_TASK
12112                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
12113            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
12114
12115            if (DEBUG_PERMISSIONS_REVIEW) {
12116                Slog.i(TAG, "u" + userId + " Launching permission review "
12117                        + "for package " + cpi.packageName);
12118            }
12119
12120            final UserHandle userHandle = new UserHandle(userId);
12121            mHandler.post(new Runnable() {
12122                @Override
12123                public void run() {
12124                    mContext.startActivityAsUser(intent, userHandle);
12125                }
12126            });
12127
12128            return false;
12129        }
12130
12131        return true;
12132    }
12133
12134    /**
12135     * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
12136     * PackageManager could be unavailable at construction time and therefore needs to be accessed
12137     * on demand.
12138     */
12139    IPackageManager getPackageManager() {
12140        return AppGlobals.getPackageManager();
12141    }
12142
12143    ActivityStartController getActivityStartController() {
12144        return mActivityStartController;
12145    }
12146
12147    PackageManagerInternal getPackageManagerInternalLocked() {
12148        if (mPackageManagerInt == null) {
12149            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12150        }
12151        return mPackageManagerInt;
12152    }
12153
12154    @Override
12155    public final ContentProviderHolder getContentProvider(
12156            IApplicationThread caller, String name, int userId, boolean stable) {
12157        enforceNotIsolatedCaller("getContentProvider");
12158        if (caller == null) {
12159            String msg = "null IApplicationThread when getting content provider "
12160                    + name;
12161            Slog.w(TAG, msg);
12162            throw new SecurityException(msg);
12163        }
12164        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
12165        // with cross-user grant.
12166        return getContentProviderImpl(caller, name, null, stable, userId);
12167    }
12168
12169    public ContentProviderHolder getContentProviderExternal(
12170            String name, int userId, IBinder token) {
12171        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12172            "Do not have permission in call getContentProviderExternal()");
12173        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12174                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
12175        return getContentProviderExternalUnchecked(name, token, userId);
12176    }
12177
12178    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12179            IBinder token, int userId) {
12180        return getContentProviderImpl(null, name, token, true, userId);
12181    }
12182
12183    /**
12184     * Drop a content provider from a ProcessRecord's bookkeeping
12185     */
12186    public void removeContentProvider(IBinder connection, boolean stable) {
12187        enforceNotIsolatedCaller("removeContentProvider");
12188        long ident = Binder.clearCallingIdentity();
12189        try {
12190            synchronized (this) {
12191                ContentProviderConnection conn;
12192                try {
12193                    conn = (ContentProviderConnection)connection;
12194                } catch (ClassCastException e) {
12195                    String msg ="removeContentProvider: " + connection
12196                            + " not a ContentProviderConnection";
12197                    Slog.w(TAG, msg);
12198                    throw new IllegalArgumentException(msg);
12199                }
12200                if (conn == null) {
12201                    throw new NullPointerException("connection is null");
12202                }
12203                if (decProviderCountLocked(conn, null, null, stable)) {
12204                    updateOomAdjLocked();
12205                }
12206            }
12207        } finally {
12208            Binder.restoreCallingIdentity(ident);
12209        }
12210    }
12211
12212    public void removeContentProviderExternal(String name, IBinder token) {
12213        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12214            "Do not have permission in call removeContentProviderExternal()");
12215        int userId = UserHandle.getCallingUserId();
12216        long ident = Binder.clearCallingIdentity();
12217        try {
12218            removeContentProviderExternalUnchecked(name, token, userId);
12219        } finally {
12220            Binder.restoreCallingIdentity(ident);
12221        }
12222    }
12223
12224    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12225        synchronized (this) {
12226            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12227            if(cpr == null) {
12228                //remove from mProvidersByClass
12229                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12230                return;
12231            }
12232
12233            //update content provider record entry info
12234            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12235            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12236            if (localCpr.hasExternalProcessHandles()) {
12237                if (localCpr.removeExternalProcessHandleLocked(token)) {
12238                    updateOomAdjLocked();
12239                } else {
12240                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12241                            + " with no external reference for token: "
12242                            + token + ".");
12243                }
12244            } else {
12245                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12246                        + " with no external references.");
12247            }
12248        }
12249    }
12250
12251    public final void publishContentProviders(IApplicationThread caller,
12252            List<ContentProviderHolder> providers) {
12253        if (providers == null) {
12254            return;
12255        }
12256
12257        enforceNotIsolatedCaller("publishContentProviders");
12258        synchronized (this) {
12259            final ProcessRecord r = getRecordForAppLocked(caller);
12260            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12261            if (r == null) {
12262                throw new SecurityException(
12263                        "Unable to find app for caller " + caller
12264                      + " (pid=" + Binder.getCallingPid()
12265                      + ") when publishing content providers");
12266            }
12267
12268            final long origId = Binder.clearCallingIdentity();
12269
12270            final int N = providers.size();
12271            for (int i = 0; i < N; i++) {
12272                ContentProviderHolder src = providers.get(i);
12273                if (src == null || src.info == null || src.provider == null) {
12274                    continue;
12275                }
12276                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12277                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12278                if (dst != null) {
12279                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12280                    mProviderMap.putProviderByClass(comp, dst);
12281                    String names[] = dst.info.authority.split(";");
12282                    for (int j = 0; j < names.length; j++) {
12283                        mProviderMap.putProviderByName(names[j], dst);
12284                    }
12285
12286                    int launchingCount = mLaunchingProviders.size();
12287                    int j;
12288                    boolean wasInLaunchingProviders = false;
12289                    for (j = 0; j < launchingCount; j++) {
12290                        if (mLaunchingProviders.get(j) == dst) {
12291                            mLaunchingProviders.remove(j);
12292                            wasInLaunchingProviders = true;
12293                            j--;
12294                            launchingCount--;
12295                        }
12296                    }
12297                    if (wasInLaunchingProviders) {
12298                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12299                    }
12300                    synchronized (dst) {
12301                        dst.provider = src.provider;
12302                        dst.proc = r;
12303                        dst.notifyAll();
12304                    }
12305                    updateOomAdjLocked(r, true);
12306                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12307                            src.info.authority);
12308                }
12309            }
12310
12311            Binder.restoreCallingIdentity(origId);
12312        }
12313    }
12314
12315    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12316        ContentProviderConnection conn;
12317        try {
12318            conn = (ContentProviderConnection)connection;
12319        } catch (ClassCastException e) {
12320            String msg ="refContentProvider: " + connection
12321                    + " not a ContentProviderConnection";
12322            Slog.w(TAG, msg);
12323            throw new IllegalArgumentException(msg);
12324        }
12325        if (conn == null) {
12326            throw new NullPointerException("connection is null");
12327        }
12328
12329        synchronized (this) {
12330            if (stable > 0) {
12331                conn.numStableIncs += stable;
12332            }
12333            stable = conn.stableCount + stable;
12334            if (stable < 0) {
12335                throw new IllegalStateException("stableCount < 0: " + stable);
12336            }
12337
12338            if (unstable > 0) {
12339                conn.numUnstableIncs += unstable;
12340            }
12341            unstable = conn.unstableCount + unstable;
12342            if (unstable < 0) {
12343                throw new IllegalStateException("unstableCount < 0: " + unstable);
12344            }
12345
12346            if ((stable+unstable) <= 0) {
12347                throw new IllegalStateException("ref counts can't go to zero here: stable="
12348                        + stable + " unstable=" + unstable);
12349            }
12350            conn.stableCount = stable;
12351            conn.unstableCount = unstable;
12352            return !conn.dead;
12353        }
12354    }
12355
12356    public void unstableProviderDied(IBinder connection) {
12357        ContentProviderConnection conn;
12358        try {
12359            conn = (ContentProviderConnection)connection;
12360        } catch (ClassCastException e) {
12361            String msg ="refContentProvider: " + connection
12362                    + " not a ContentProviderConnection";
12363            Slog.w(TAG, msg);
12364            throw new IllegalArgumentException(msg);
12365        }
12366        if (conn == null) {
12367            throw new NullPointerException("connection is null");
12368        }
12369
12370        // Safely retrieve the content provider associated with the connection.
12371        IContentProvider provider;
12372        synchronized (this) {
12373            provider = conn.provider.provider;
12374        }
12375
12376        if (provider == null) {
12377            // Um, yeah, we're way ahead of you.
12378            return;
12379        }
12380
12381        // Make sure the caller is being honest with us.
12382        if (provider.asBinder().pingBinder()) {
12383            // Er, no, still looks good to us.
12384            synchronized (this) {
12385                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12386                        + " says " + conn + " died, but we don't agree");
12387                return;
12388            }
12389        }
12390
12391        // Well look at that!  It's dead!
12392        synchronized (this) {
12393            if (conn.provider.provider != provider) {
12394                // But something changed...  good enough.
12395                return;
12396            }
12397
12398            ProcessRecord proc = conn.provider.proc;
12399            if (proc == null || proc.thread == null) {
12400                // Seems like the process is already cleaned up.
12401                return;
12402            }
12403
12404            // As far as we're concerned, this is just like receiving a
12405            // death notification...  just a bit prematurely.
12406            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12407                    + ") early provider death");
12408            final long ident = Binder.clearCallingIdentity();
12409            try {
12410                appDiedLocked(proc);
12411            } finally {
12412                Binder.restoreCallingIdentity(ident);
12413            }
12414        }
12415    }
12416
12417    @Override
12418    public void appNotRespondingViaProvider(IBinder connection) {
12419        enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12420
12421        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12422        if (conn == null) {
12423            Slog.w(TAG, "ContentProviderConnection is null");
12424            return;
12425        }
12426
12427        final ProcessRecord host = conn.provider.proc;
12428        if (host == null) {
12429            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12430            return;
12431        }
12432
12433        mHandler.post(new Runnable() {
12434            @Override
12435            public void run() {
12436                mAppErrors.appNotResponding(host, null, null, false,
12437                        "ContentProvider not responding");
12438            }
12439        });
12440    }
12441
12442    public final void installSystemProviders() {
12443        List<ProviderInfo> providers;
12444        synchronized (this) {
12445            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12446            providers = generateApplicationProvidersLocked(app);
12447            if (providers != null) {
12448                for (int i=providers.size()-1; i>=0; i--) {
12449                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12450                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12451                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12452                                + ": not system .apk");
12453                        providers.remove(i);
12454                    }
12455                }
12456            }
12457        }
12458        if (providers != null) {
12459            mSystemThread.installSystemProviders(providers);
12460        }
12461
12462        mConstants.start(mContext.getContentResolver());
12463        mCoreSettingsObserver = new CoreSettingsObserver(this);
12464        mFontScaleSettingObserver = new FontScaleSettingObserver();
12465        mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
12466        GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12467
12468        // Now that the settings provider is published we can consider sending
12469        // in a rescue party.
12470        RescueParty.onSettingsProviderPublished(mContext);
12471
12472        //mUsageStatsService.monitorPackages();
12473    }
12474
12475    void startPersistentApps(int matchFlags) {
12476        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12477
12478        synchronized (this) {
12479            try {
12480                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12481                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12482                for (ApplicationInfo app : apps) {
12483                    if (!"android".equals(app.packageName)) {
12484                        addAppLocked(app, null, false, null /* ABI override */);
12485                    }
12486                }
12487            } catch (RemoteException ex) {
12488            }
12489        }
12490    }
12491
12492    /**
12493     * When a user is unlocked, we need to install encryption-unaware providers
12494     * belonging to any running apps.
12495     */
12496    void installEncryptionUnawareProviders(int userId) {
12497        // We're only interested in providers that are encryption unaware, and
12498        // we don't care about uninstalled apps, since there's no way they're
12499        // running at this point.
12500        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12501
12502        synchronized (this) {
12503            final int NP = mProcessNames.getMap().size();
12504            for (int ip = 0; ip < NP; ip++) {
12505                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12506                final int NA = apps.size();
12507                for (int ia = 0; ia < NA; ia++) {
12508                    final ProcessRecord app = apps.valueAt(ia);
12509                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12510
12511                    final int NG = app.pkgList.size();
12512                    for (int ig = 0; ig < NG; ig++) {
12513                        try {
12514                            final String pkgName = app.pkgList.keyAt(ig);
12515                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12516                                    .getPackageInfo(pkgName, matchFlags, userId);
12517                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12518                                for (ProviderInfo pi : pkgInfo.providers) {
12519                                    // TODO: keep in sync with generateApplicationProvidersLocked
12520                                    final boolean processMatch = Objects.equals(pi.processName,
12521                                            app.processName) || pi.multiprocess;
12522                                    final boolean userMatch = isSingleton(pi.processName,
12523                                            pi.applicationInfo, pi.name, pi.flags)
12524                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12525                                    if (processMatch && userMatch) {
12526                                        Log.v(TAG, "Installing " + pi);
12527                                        app.thread.scheduleInstallProvider(pi);
12528                                    } else {
12529                                        Log.v(TAG, "Skipping " + pi);
12530                                    }
12531                                }
12532                            }
12533                        } catch (RemoteException ignored) {
12534                        }
12535                    }
12536                }
12537            }
12538        }
12539    }
12540
12541    /**
12542     * Allows apps to retrieve the MIME type of a URI.
12543     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12544     * users, then it does not need permission to access the ContentProvider.
12545     * Either, it needs cross-user uri grants.
12546     *
12547     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12548     *
12549     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12550     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12551     */
12552    public String getProviderMimeType(Uri uri, int userId) {
12553        enforceNotIsolatedCaller("getProviderMimeType");
12554        final String name = uri.getAuthority();
12555        int callingUid = Binder.getCallingUid();
12556        int callingPid = Binder.getCallingPid();
12557        long ident = 0;
12558        boolean clearedIdentity = false;
12559        userId = mUserController.unsafeConvertIncomingUser(userId);
12560        if (canClearIdentity(callingPid, callingUid, userId)) {
12561            clearedIdentity = true;
12562            ident = Binder.clearCallingIdentity();
12563        }
12564        ContentProviderHolder holder = null;
12565        try {
12566            holder = getContentProviderExternalUnchecked(name, null, userId);
12567            if (holder != null) {
12568                return holder.provider.getType(uri);
12569            }
12570        } catch (RemoteException e) {
12571            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12572            return null;
12573        } catch (Exception e) {
12574            Log.w(TAG, "Exception while determining type of " + uri, e);
12575            return null;
12576        } finally {
12577            // We need to clear the identity to call removeContentProviderExternalUnchecked
12578            if (!clearedIdentity) {
12579                ident = Binder.clearCallingIdentity();
12580            }
12581            try {
12582                if (holder != null) {
12583                    removeContentProviderExternalUnchecked(name, null, userId);
12584                }
12585            } finally {
12586                Binder.restoreCallingIdentity(ident);
12587            }
12588        }
12589
12590        return null;
12591    }
12592
12593    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12594        if (UserHandle.getUserId(callingUid) == userId) {
12595            return true;
12596        }
12597        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12598                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12599                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12600                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12601                return true;
12602        }
12603        return false;
12604    }
12605
12606    // =========================================================
12607    // GLOBAL MANAGEMENT
12608    // =========================================================
12609
12610    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12611            boolean isolated, int isolatedUid) {
12612        String proc = customProcess != null ? customProcess : info.processName;
12613        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12614        final int userId = UserHandle.getUserId(info.uid);
12615        int uid = info.uid;
12616        if (isolated) {
12617            if (isolatedUid == 0) {
12618                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12619                while (true) {
12620                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12621                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12622                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12623                    }
12624                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12625                    mNextIsolatedProcessUid++;
12626                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12627                        // No process for this uid, use it.
12628                        break;
12629                    }
12630                    stepsLeft--;
12631                    if (stepsLeft <= 0) {
12632                        return null;
12633                    }
12634                }
12635            } else {
12636                // Special case for startIsolatedProcess (internal only), where
12637                // the uid of the isolated process is specified by the caller.
12638                uid = isolatedUid;
12639            }
12640            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12641
12642            // Register the isolated UID with this application so BatteryStats knows to
12643            // attribute resource usage to the application.
12644            //
12645            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12646            // about the process state of the isolated UID *before* it is registered with the
12647            // owning application.
12648            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12649        }
12650        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12651        if (!mBooted && !mBooting
12652                && userId == UserHandle.USER_SYSTEM
12653                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12654            r.persistent = true;
12655            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12656        }
12657        if (isolated && isolatedUid != 0) {
12658            // Special case for startIsolatedProcess (internal only) - assume the process
12659            // is required by the system server to prevent it being killed.
12660            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
12661        }
12662        addProcessNameLocked(r);
12663        return r;
12664    }
12665
12666    private boolean uidOnBackgroundWhitelist(final int uid) {
12667        final int appId = UserHandle.getAppId(uid);
12668        final int[] whitelist = mBackgroundAppIdWhitelist;
12669        final int N = whitelist.length;
12670        for (int i = 0; i < N; i++) {
12671            if (appId == whitelist[i]) {
12672                return true;
12673            }
12674        }
12675        return false;
12676    }
12677
12678    @Override
12679    public void backgroundWhitelistUid(final int uid) {
12680        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12681            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12682        }
12683
12684        if (DEBUG_BACKGROUND_CHECK) {
12685            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12686        }
12687        synchronized (this) {
12688            final int N = mBackgroundAppIdWhitelist.length;
12689            int[] newList = new int[N+1];
12690            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12691            newList[N] = UserHandle.getAppId(uid);
12692            mBackgroundAppIdWhitelist = newList;
12693        }
12694    }
12695
12696    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12697            String abiOverride) {
12698        ProcessRecord app;
12699        if (!isolated) {
12700            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12701                    info.uid, true);
12702        } else {
12703            app = null;
12704        }
12705
12706        if (app == null) {
12707            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12708            updateLruProcessLocked(app, false, null);
12709            updateOomAdjLocked();
12710        }
12711
12712        // This package really, really can not be stopped.
12713        try {
12714            AppGlobals.getPackageManager().setPackageStoppedState(
12715                    info.packageName, false, UserHandle.getUserId(app.uid));
12716        } catch (RemoteException e) {
12717        } catch (IllegalArgumentException e) {
12718            Slog.w(TAG, "Failed trying to unstop package "
12719                    + info.packageName + ": " + e);
12720        }
12721
12722        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12723            app.persistent = true;
12724            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12725        }
12726        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12727            mPersistentStartingProcesses.add(app);
12728            startProcessLocked(app, "added application",
12729                    customProcess != null ? customProcess : app.processName, abiOverride);
12730        }
12731
12732        return app;
12733    }
12734
12735    public void unhandledBack() {
12736        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12737                "unhandledBack()");
12738
12739        synchronized(this) {
12740            final long origId = Binder.clearCallingIdentity();
12741            try {
12742                getFocusedStack().unhandledBackLocked();
12743            } finally {
12744                Binder.restoreCallingIdentity(origId);
12745            }
12746        }
12747    }
12748
12749    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12750        enforceNotIsolatedCaller("openContentUri");
12751        final int userId = UserHandle.getCallingUserId();
12752        final Uri uri = Uri.parse(uriString);
12753        String name = uri.getAuthority();
12754        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12755        ParcelFileDescriptor pfd = null;
12756        if (cph != null) {
12757            // We record the binder invoker's uid in thread-local storage before
12758            // going to the content provider to open the file.  Later, in the code
12759            // that handles all permissions checks, we look for this uid and use
12760            // that rather than the Activity Manager's own uid.  The effect is that
12761            // we do the check against the caller's permissions even though it looks
12762            // to the content provider like the Activity Manager itself is making
12763            // the request.
12764            Binder token = new Binder();
12765            sCallerIdentity.set(new Identity(
12766                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12767            try {
12768                pfd = cph.provider.openFile(null, uri, "r", null, token);
12769            } catch (FileNotFoundException e) {
12770                // do nothing; pfd will be returned null
12771            } finally {
12772                // Ensure that whatever happens, we clean up the identity state
12773                sCallerIdentity.remove();
12774                // Ensure we're done with the provider.
12775                removeContentProviderExternalUnchecked(name, null, userId);
12776            }
12777        } else {
12778            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12779        }
12780        return pfd;
12781    }
12782
12783    // Actually is sleeping or shutting down or whatever else in the future
12784    // is an inactive state.
12785    boolean isSleepingOrShuttingDownLocked() {
12786        return isSleepingLocked() || mShuttingDown;
12787    }
12788
12789    boolean isShuttingDownLocked() {
12790        return mShuttingDown;
12791    }
12792
12793    boolean isSleepingLocked() {
12794        return mSleeping;
12795    }
12796
12797    void onWakefulnessChanged(int wakefulness) {
12798        synchronized(this) {
12799            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12800            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12801            mWakefulness = wakefulness;
12802
12803            if (wasAwake != isAwake) {
12804                // Also update state in a special way for running foreground services UI.
12805                mServices.updateScreenStateLocked(isAwake);
12806                mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12807                        .sendToTarget();
12808            }
12809        }
12810    }
12811
12812    void finishRunningVoiceLocked() {
12813        if (mRunningVoice != null) {
12814            mRunningVoice = null;
12815            mVoiceWakeLock.release();
12816            updateSleepIfNeededLocked();
12817        }
12818    }
12819
12820    void startTimeTrackingFocusedActivityLocked() {
12821        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12822        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12823            mCurAppTimeTracker.start(resumedActivity.packageName);
12824        }
12825    }
12826
12827    void updateSleepIfNeededLocked() {
12828        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12829        final boolean wasSleeping = mSleeping;
12830
12831        if (!shouldSleep) {
12832            // If wasSleeping is true, we need to wake up activity manager state from when
12833            // we started sleeping. In either case, we need to apply the sleep tokens, which
12834            // will wake up stacks or put them to sleep as appropriate.
12835            if (wasSleeping) {
12836                mSleeping = false;
12837                startTimeTrackingFocusedActivityLocked();
12838                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12839                mStackSupervisor.comeOutOfSleepIfNeededLocked();
12840            }
12841            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12842            if (wasSleeping) {
12843                updateOomAdjLocked();
12844            }
12845        } else if (!mSleeping && shouldSleep) {
12846            mSleeping = true;
12847            if (mCurAppTimeTracker != null) {
12848                mCurAppTimeTracker.stop();
12849            }
12850            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12851            mStackSupervisor.goingToSleepLocked();
12852            updateOomAdjLocked();
12853        }
12854    }
12855
12856    /** Pokes the task persister. */
12857    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12858        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12859    }
12860
12861    /**
12862     * Notifies all listeners when the pinned stack animation starts.
12863     */
12864    @Override
12865    public void notifyPinnedStackAnimationStarted() {
12866        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12867    }
12868
12869    /**
12870     * Notifies all listeners when the pinned stack animation ends.
12871     */
12872    @Override
12873    public void notifyPinnedStackAnimationEnded() {
12874        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12875    }
12876
12877    @Override
12878    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12879        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12880    }
12881
12882    @Override
12883    public boolean shutdown(int timeout) {
12884        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12885                != PackageManager.PERMISSION_GRANTED) {
12886            throw new SecurityException("Requires permission "
12887                    + android.Manifest.permission.SHUTDOWN);
12888        }
12889
12890        // TODO: Where should the corresponding '1' (start) write go?
12891        StatsLog.write(StatsLog.DEVICE_ON_STATUS_CHANGED,
12892                StatsLog.DEVICE_ON_STATUS_CHANGED__STATE__OFF);
12893
12894        boolean timedout = false;
12895
12896        synchronized(this) {
12897            mShuttingDown = true;
12898            mStackSupervisor.prepareForShutdownLocked();
12899            updateEventDispatchingLocked();
12900            timedout = mStackSupervisor.shutdownLocked(timeout);
12901        }
12902
12903        mAppOpsService.shutdown();
12904        if (mUsageStatsService != null) {
12905            mUsageStatsService.prepareShutdown();
12906        }
12907        mBatteryStatsService.shutdown();
12908        synchronized (this) {
12909            mProcessStats.shutdownLocked();
12910            notifyTaskPersisterLocked(null, true);
12911        }
12912
12913        return timedout;
12914    }
12915
12916    public final void activitySlept(IBinder token) {
12917        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12918
12919        final long origId = Binder.clearCallingIdentity();
12920
12921        synchronized (this) {
12922            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12923            if (r != null) {
12924                mStackSupervisor.activitySleptLocked(r);
12925            }
12926        }
12927
12928        Binder.restoreCallingIdentity(origId);
12929    }
12930
12931    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12932        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12933        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12934        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12935            boolean wasRunningVoice = mRunningVoice != null;
12936            mRunningVoice = session;
12937            if (!wasRunningVoice) {
12938                mVoiceWakeLock.acquire();
12939                updateSleepIfNeededLocked();
12940            }
12941        }
12942    }
12943
12944    private void updateEventDispatchingLocked() {
12945        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12946    }
12947
12948    @Override
12949    public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12950        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12951                != PackageManager.PERMISSION_GRANTED) {
12952            throw new SecurityException("Requires permission "
12953                    + android.Manifest.permission.DEVICE_POWER);
12954        }
12955
12956        synchronized(this) {
12957            long ident = Binder.clearCallingIdentity();
12958            try {
12959                mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12960            } finally {
12961                Binder.restoreCallingIdentity(ident);
12962            }
12963        }
12964
12965        mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12966                .sendToTarget();
12967    }
12968
12969    @Override
12970    public void notifyLockedProfile(@UserIdInt int userId) {
12971        try {
12972            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12973                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12974            }
12975        } catch (RemoteException ex) {
12976            throw new SecurityException("Fail to check is caller a privileged app", ex);
12977        }
12978
12979        synchronized (this) {
12980            final long ident = Binder.clearCallingIdentity();
12981            try {
12982                if (mUserController.shouldConfirmCredentials(userId)) {
12983                    if (mKeyguardController.isKeyguardLocked()) {
12984                        // Showing launcher to avoid user entering credential twice.
12985                        final int currentUserId = mUserController.getCurrentUserId();
12986                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12987                    }
12988                    mStackSupervisor.lockAllProfileTasks(userId);
12989                }
12990            } finally {
12991                Binder.restoreCallingIdentity(ident);
12992            }
12993        }
12994    }
12995
12996    @Override
12997    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12998        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12999        synchronized (this) {
13000            final long ident = Binder.clearCallingIdentity();
13001            try {
13002                intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
13003                        FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
13004                        FLAG_ACTIVITY_TASK_ON_HOME);
13005                ActivityOptions activityOptions = options != null
13006                        ? new ActivityOptions(options)
13007                        : ActivityOptions.makeBasic();
13008                activityOptions.setLaunchTaskId(
13009                        mStackSupervisor.getHomeActivity().getTask().taskId);
13010                mContext.startActivityAsUser(intent, activityOptions.toBundle(),
13011                        UserHandle.CURRENT);
13012            } finally {
13013                Binder.restoreCallingIdentity(ident);
13014            }
13015        }
13016    }
13017
13018    @Override
13019    public void stopAppSwitches() {
13020        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
13021                != PackageManager.PERMISSION_GRANTED) {
13022            throw new SecurityException("viewquires permission "
13023                    + android.Manifest.permission.STOP_APP_SWITCHES);
13024        }
13025
13026        synchronized(this) {
13027            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
13028                    + APP_SWITCH_DELAY_TIME;
13029            mDidAppSwitch = false;
13030            mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
13031        }
13032    }
13033
13034    public void resumeAppSwitches() {
13035        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
13036                != PackageManager.PERMISSION_GRANTED) {
13037            throw new SecurityException("Requires permission "
13038                    + android.Manifest.permission.STOP_APP_SWITCHES);
13039        }
13040
13041        synchronized(this) {
13042            // Note that we don't execute any pending app switches... we will
13043            // let those wait until either the timeout, or the next start
13044            // activity request.
13045            mAppSwitchesAllowedTime = 0;
13046        }
13047    }
13048
13049    boolean checkAllowAppSwitchUid(int uid) {
13050        ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
13051        if (types != null) {
13052            for (int i = types.size() - 1; i >= 0; i--) {
13053                if (types.valueAt(i).intValue() == uid) {
13054                    return true;
13055                }
13056            }
13057        }
13058        return false;
13059    }
13060
13061    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
13062            int callingPid, int callingUid, String name) {
13063        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
13064            return true;
13065        }
13066
13067        int perm = checkComponentPermission(
13068                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
13069                sourceUid, -1, true);
13070        if (perm == PackageManager.PERMISSION_GRANTED) {
13071            return true;
13072        }
13073        if (checkAllowAppSwitchUid(sourceUid)) {
13074            return true;
13075        }
13076
13077        // If the actual IPC caller is different from the logical source, then
13078        // also see if they are allowed to control app switches.
13079        if (callingUid != -1 && callingUid != sourceUid) {
13080            perm = checkComponentPermission(
13081                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
13082                    callingUid, -1, true);
13083            if (perm == PackageManager.PERMISSION_GRANTED) {
13084                return true;
13085            }
13086            if (checkAllowAppSwitchUid(callingUid)) {
13087                return true;
13088            }
13089        }
13090
13091        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
13092        return false;
13093    }
13094
13095    public void setDebugApp(String packageName, boolean waitForDebugger,
13096            boolean persistent) {
13097        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
13098                "setDebugApp()");
13099
13100        long ident = Binder.clearCallingIdentity();
13101        try {
13102            // Note that this is not really thread safe if there are multiple
13103            // callers into it at the same time, but that's not a situation we
13104            // care about.
13105            if (persistent) {
13106                final ContentResolver resolver = mContext.getContentResolver();
13107                Settings.Global.putString(
13108                    resolver, Settings.Global.DEBUG_APP,
13109                    packageName);
13110                Settings.Global.putInt(
13111                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13112                    waitForDebugger ? 1 : 0);
13113            }
13114
13115            synchronized (this) {
13116                if (!persistent) {
13117                    mOrigDebugApp = mDebugApp;
13118                    mOrigWaitForDebugger = mWaitForDebugger;
13119                }
13120                mDebugApp = packageName;
13121                mWaitForDebugger = waitForDebugger;
13122                mDebugTransient = !persistent;
13123                if (packageName != null) {
13124                    forceStopPackageLocked(packageName, -1, false, false, true, true,
13125                            false, UserHandle.USER_ALL, "set debug app");
13126                }
13127            }
13128        } finally {
13129            Binder.restoreCallingIdentity(ident);
13130        }
13131    }
13132
13133    /**
13134     * Set or remove an agent to be run whenever an app with the given process name starts.
13135     *
13136     * This method will not check whether the given process name matches a debuggable app. That
13137     * would require scanning all current packages, and a rescan when new packages are installed
13138     * or updated.
13139     *
13140     * Instead, do the check when an application is started and matched to a stored agent.
13141     *
13142     * @param packageName the process name of the app.
13143     * @param agent the agent string to be used, or null to remove any previously set agent.
13144     */
13145    @Override
13146    public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
13147        synchronized (this) {
13148            // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13149            // its own permission.
13150            if (checkCallingPermission(
13151                    android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
13152                        PackageManager.PERMISSION_GRANTED) {
13153                throw new SecurityException(
13154                        "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13155            }
13156
13157            if (agent == null) {
13158                if (mAppAgentMap != null) {
13159                    mAppAgentMap.remove(packageName);
13160                    if (mAppAgentMap.isEmpty()) {
13161                        mAppAgentMap = null;
13162                    }
13163                }
13164            } else {
13165                if (mAppAgentMap == null) {
13166                    mAppAgentMap = new HashMap<>();
13167                }
13168                if (mAppAgentMap.size() >= 100) {
13169                    // Limit the size of the map, to avoid OOMEs.
13170                    Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
13171                            + "/" + agent);
13172                    return;
13173                }
13174                mAppAgentMap.put(packageName, agent);
13175            }
13176        }
13177    }
13178
13179    void setTrackAllocationApp(ApplicationInfo app, String processName) {
13180        synchronized (this) {
13181            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13182            if (!isDebuggable) {
13183                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13184                    throw new SecurityException("Process not debuggable: " + app.packageName);
13185                }
13186            }
13187
13188            mTrackAllocationApp = processName;
13189        }
13190    }
13191
13192    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
13193        synchronized (this) {
13194            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13195            if (!isDebuggable) {
13196                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13197                    throw new SecurityException("Process not debuggable: " + app.packageName);
13198                }
13199            }
13200            mProfileApp = processName;
13201
13202            if (mProfilerInfo != null) {
13203                if (mProfilerInfo.profileFd != null) {
13204                    try {
13205                        mProfilerInfo.profileFd.close();
13206                    } catch (IOException e) {
13207                    }
13208                }
13209            }
13210            mProfilerInfo = new ProfilerInfo(profilerInfo);
13211            mProfileType = 0;
13212        }
13213    }
13214
13215    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
13216        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13217        if (!isDebuggable) {
13218            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13219                throw new SecurityException("Process not debuggable: " + app.packageName);
13220            }
13221        }
13222        mNativeDebuggingApp = processName;
13223    }
13224
13225    @Override
13226    public void setAlwaysFinish(boolean enabled) {
13227        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13228                "setAlwaysFinish()");
13229
13230        long ident = Binder.clearCallingIdentity();
13231        try {
13232            Settings.Global.putInt(
13233                    mContext.getContentResolver(),
13234                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13235
13236            synchronized (this) {
13237                mAlwaysFinishActivities = enabled;
13238            }
13239        } finally {
13240            Binder.restoreCallingIdentity(ident);
13241        }
13242    }
13243
13244    @Override
13245    public void setActivityController(IActivityController controller, boolean imAMonkey) {
13246        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13247                "setActivityController()");
13248        synchronized (this) {
13249            mController = controller;
13250            mControllerIsAMonkey = imAMonkey;
13251            Watchdog.getInstance().setActivityController(controller);
13252        }
13253    }
13254
13255    @Override
13256    public void setUserIsMonkey(boolean userIsMonkey) {
13257        synchronized (this) {
13258            synchronized (mPidsSelfLocked) {
13259                final int callingPid = Binder.getCallingPid();
13260                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13261                if (proc == null) {
13262                    throw new SecurityException("Unknown process: " + callingPid);
13263                }
13264                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13265                    throw new SecurityException("Only an instrumentation process "
13266                            + "with a UiAutomation can call setUserIsMonkey");
13267                }
13268            }
13269            mUserIsMonkey = userIsMonkey;
13270        }
13271    }
13272
13273    @Override
13274    public boolean isUserAMonkey() {
13275        synchronized (this) {
13276            // If there is a controller also implies the user is a monkey.
13277            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13278        }
13279    }
13280
13281    /**
13282     * @deprecated This method is only used by a few internal components and it will soon be
13283     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13284     * No new code should be calling it.
13285     */
13286    @Deprecated
13287    @Override
13288    public void requestBugReport(int bugreportType) {
13289        String extraOptions = null;
13290        switch (bugreportType) {
13291            case ActivityManager.BUGREPORT_OPTION_FULL:
13292                // Default options.
13293                break;
13294            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13295                extraOptions = "bugreportplus";
13296                break;
13297            case ActivityManager.BUGREPORT_OPTION_REMOTE:
13298                extraOptions = "bugreportremote";
13299                break;
13300            case ActivityManager.BUGREPORT_OPTION_WEAR:
13301                extraOptions = "bugreportwear";
13302                break;
13303            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13304                extraOptions = "bugreporttelephony";
13305                break;
13306            case ActivityManager.BUGREPORT_OPTION_WIFI:
13307                extraOptions = "bugreportwifi";
13308                break;
13309            default:
13310                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13311                        + bugreportType);
13312        }
13313        // Always log caller, even if it does not have permission to dump.
13314        String type = extraOptions == null ? "bugreport" : extraOptions;
13315        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13316
13317        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13318        if (extraOptions != null) {
13319            SystemProperties.set("dumpstate.options", extraOptions);
13320        }
13321        SystemProperties.set("ctl.start", "bugreport");
13322    }
13323
13324    /**
13325     * @deprecated This method is only used by a few internal components and it will soon be
13326     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13327     * No new code should be calling it.
13328     */
13329    @Deprecated
13330    private void requestBugReportWithDescription(String shareTitle, String shareDescription,
13331                                                 int bugreportType) {
13332        if (!TextUtils.isEmpty(shareTitle)) {
13333            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13334                String errorStr = "shareTitle should be less than " +
13335                        MAX_BUGREPORT_TITLE_SIZE + " characters";
13336                throw new IllegalArgumentException(errorStr);
13337            } else {
13338                if (!TextUtils.isEmpty(shareDescription)) {
13339                    int length;
13340                    try {
13341                        length = shareDescription.getBytes("UTF-8").length;
13342                    } catch (UnsupportedEncodingException e) {
13343                        String errorStr = "shareDescription: UnsupportedEncodingException";
13344                        throw new IllegalArgumentException(errorStr);
13345                    }
13346                    if (length > SystemProperties.PROP_VALUE_MAX) {
13347                        String errorStr = "shareTitle should be less than " +
13348                                SystemProperties.PROP_VALUE_MAX + " bytes";
13349                        throw new IllegalArgumentException(errorStr);
13350                    } else {
13351                        SystemProperties.set("dumpstate.options.description", shareDescription);
13352                    }
13353                }
13354                SystemProperties.set("dumpstate.options.title", shareTitle);
13355            }
13356        }
13357
13358        Slog.d(TAG, "Bugreport notification title " + shareTitle
13359                + " description " + shareDescription);
13360        requestBugReport(bugreportType);
13361    }
13362
13363    /**
13364     * @deprecated This method is only used by a few internal components and it will soon be
13365     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13366     * No new code should be calling it.
13367     */
13368    @Deprecated
13369    @Override
13370    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13371        requestBugReportWithDescription(shareTitle, shareDescription,
13372                ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13373    }
13374
13375    /**
13376     * @deprecated This method is only used by a few internal components and it will soon be
13377     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13378     * No new code should be calling it.
13379     */
13380    @Deprecated
13381    @Override
13382    public void requestWifiBugReport(String shareTitle, String shareDescription) {
13383        requestBugReportWithDescription(shareTitle, shareDescription,
13384                ActivityManager.BUGREPORT_OPTION_WIFI);
13385    }
13386
13387
13388    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13389        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13390    }
13391
13392    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13393        if (r != null && (r.instr != null || r.usingWrapper)) {
13394            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13395        }
13396        return KEY_DISPATCHING_TIMEOUT;
13397    }
13398
13399    @Override
13400    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13401        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13402                != PackageManager.PERMISSION_GRANTED) {
13403            throw new SecurityException("Requires permission "
13404                    + android.Manifest.permission.FILTER_EVENTS);
13405        }
13406        ProcessRecord proc;
13407        long timeout;
13408        synchronized (this) {
13409            synchronized (mPidsSelfLocked) {
13410                proc = mPidsSelfLocked.get(pid);
13411            }
13412            timeout = getInputDispatchingTimeoutLocked(proc);
13413        }
13414
13415        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13416            return -1;
13417        }
13418
13419        return timeout;
13420    }
13421
13422    /**
13423     * Handle input dispatching timeouts.
13424     * Returns whether input dispatching should be aborted or not.
13425     */
13426    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13427            final ActivityRecord activity, final ActivityRecord parent,
13428            final boolean aboveSystem, String reason) {
13429        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13430                != PackageManager.PERMISSION_GRANTED) {
13431            throw new SecurityException("Requires permission "
13432                    + android.Manifest.permission.FILTER_EVENTS);
13433        }
13434
13435        final String annotation;
13436        if (reason == null) {
13437            annotation = "Input dispatching timed out";
13438        } else {
13439            annotation = "Input dispatching timed out (" + reason + ")";
13440        }
13441
13442        if (proc != null) {
13443            synchronized (this) {
13444                if (proc.debugging) {
13445                    return false;
13446                }
13447
13448                if (proc.instr != null) {
13449                    Bundle info = new Bundle();
13450                    info.putString("shortMsg", "keyDispatchingTimedOut");
13451                    info.putString("longMsg", annotation);
13452                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13453                    return true;
13454                }
13455            }
13456            mHandler.post(new Runnable() {
13457                @Override
13458                public void run() {
13459                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13460                }
13461            });
13462        }
13463
13464        return true;
13465    }
13466
13467    @Override
13468    public Bundle getAssistContextExtras(int requestType) {
13469        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13470                null, null, true /* focused */, true /* newSessionId */,
13471                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13472        if (pae == null) {
13473            return null;
13474        }
13475        synchronized (pae) {
13476            while (!pae.haveResult) {
13477                try {
13478                    pae.wait();
13479                } catch (InterruptedException e) {
13480                }
13481            }
13482        }
13483        synchronized (this) {
13484            buildAssistBundleLocked(pae, pae.result);
13485            mPendingAssistExtras.remove(pae);
13486            mUiHandler.removeCallbacks(pae);
13487        }
13488        return pae.extras;
13489    }
13490
13491    @Override
13492    public boolean isAssistDataAllowedOnCurrentActivity() {
13493        int userId;
13494        synchronized (this) {
13495            final ActivityStack focusedStack = getFocusedStack();
13496            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
13497                return false;
13498            }
13499
13500            final ActivityRecord activity = focusedStack.getTopActivity();
13501            if (activity == null) {
13502                return false;
13503            }
13504            userId = activity.userId;
13505        }
13506        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13507                Context.DEVICE_POLICY_SERVICE);
13508        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13509    }
13510
13511    @Override
13512    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13513        long ident = Binder.clearCallingIdentity();
13514        try {
13515            synchronized (this) {
13516                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13517                ActivityRecord top = getFocusedStack().getTopActivity();
13518                if (top != caller) {
13519                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13520                            + " is not current top " + top);
13521                    return false;
13522                }
13523                if (!top.nowVisible) {
13524                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13525                            + " is not visible");
13526                    return false;
13527                }
13528            }
13529            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13530                    token);
13531        } finally {
13532            Binder.restoreCallingIdentity(ident);
13533        }
13534    }
13535
13536    @Override
13537    public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
13538            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13539        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13540                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13541                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13542    }
13543
13544    @Override
13545    public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
13546            IBinder activityToken, int flags) {
13547        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13548                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13549                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13550    }
13551
13552    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13553            IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13554            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13555            int flags) {
13556        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13557                "enqueueAssistContext()");
13558
13559        synchronized (this) {
13560            ActivityRecord activity = getFocusedStack().getTopActivity();
13561            if (activity == null) {
13562                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13563                return null;
13564            }
13565            if (activity.app == null || activity.app.thread == null) {
13566                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13567                return null;
13568            }
13569            if (focused) {
13570                if (activityToken != null) {
13571                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13572                    if (activity != caller) {
13573                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13574                                + " is not current top " + activity);
13575                        return null;
13576                    }
13577                }
13578            } else {
13579                activity = ActivityRecord.forTokenLocked(activityToken);
13580                if (activity == null) {
13581                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13582                            + " couldn't be found");
13583                    return null;
13584                }
13585                if (activity.app == null || activity.app.thread == null) {
13586                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13587                    return null;
13588                }
13589            }
13590
13591            PendingAssistExtras pae;
13592            Bundle extras = new Bundle();
13593            if (args != null) {
13594                extras.putAll(args);
13595            }
13596            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13597            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13598
13599            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13600                    userHandle);
13601            pae.isHome = activity.isActivityTypeHome();
13602
13603            // Increment the sessionId if necessary
13604            if (newSessionId) {
13605                mViSessionId++;
13606            }
13607            try {
13608                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13609                        mViSessionId, flags);
13610                mPendingAssistExtras.add(pae);
13611                mUiHandler.postDelayed(pae, timeout);
13612            } catch (RemoteException e) {
13613                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13614                return null;
13615            }
13616            return pae;
13617        }
13618    }
13619
13620    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13621        IAssistDataReceiver receiver;
13622        synchronized (this) {
13623            mPendingAssistExtras.remove(pae);
13624            receiver = pae.receiver;
13625        }
13626        if (receiver != null) {
13627            // Caller wants result sent back to them.
13628            Bundle sendBundle = new Bundle();
13629            // At least return the receiver extras
13630            sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13631            try {
13632                pae.receiver.onHandleAssistData(sendBundle);
13633            } catch (RemoteException e) {
13634            }
13635        }
13636    }
13637
13638    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13639        if (result != null) {
13640            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13641        }
13642        if (pae.hint != null) {
13643            pae.extras.putBoolean(pae.hint, true);
13644        }
13645    }
13646
13647    /** Called from an app when assist data is ready. */
13648    @Override
13649    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13650            AssistContent content, Uri referrer) {
13651        PendingAssistExtras pae = (PendingAssistExtras)token;
13652        synchronized (pae) {
13653            pae.result = extras;
13654            pae.structure = structure;
13655            pae.content = content;
13656            if (referrer != null) {
13657                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13658            }
13659            if (structure != null) {
13660                structure.setHomeActivity(pae.isHome);
13661            }
13662            pae.haveResult = true;
13663            pae.notifyAll();
13664            if (pae.intent == null && pae.receiver == null) {
13665                // Caller is just waiting for the result.
13666                return;
13667            }
13668        }
13669        // We are now ready to launch the assist activity.
13670        IAssistDataReceiver sendReceiver = null;
13671        Bundle sendBundle = null;
13672        synchronized (this) {
13673            buildAssistBundleLocked(pae, extras);
13674            boolean exists = mPendingAssistExtras.remove(pae);
13675            mUiHandler.removeCallbacks(pae);
13676            if (!exists) {
13677                // Timed out.
13678                return;
13679            }
13680
13681            if ((sendReceiver=pae.receiver) != null) {
13682                // Caller wants result sent back to them.
13683                sendBundle = new Bundle();
13684                sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
13685                sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
13686                sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
13687                sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13688            }
13689        }
13690        if (sendReceiver != null) {
13691            try {
13692                sendReceiver.onHandleAssistData(sendBundle);
13693            } catch (RemoteException e) {
13694            }
13695            return;
13696        }
13697
13698        final long ident = Binder.clearCallingIdentity();
13699        try {
13700            if (TextUtils.equals(pae.intent.getAction(),
13701                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13702                pae.intent.putExtras(pae.extras);
13703                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13704            } else {
13705                pae.intent.replaceExtras(pae.extras);
13706                pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
13707                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
13708                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13709                closeSystemDialogs("assist");
13710
13711                try {
13712                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13713                } catch (ActivityNotFoundException e) {
13714                    Slog.w(TAG, "No activity to handle assist action.", e);
13715                }
13716            }
13717        } finally {
13718            Binder.restoreCallingIdentity(ident);
13719        }
13720    }
13721
13722    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13723            Bundle args) {
13724        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13725                true /* focused */, true /* newSessionId */, userHandle, args,
13726                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13727    }
13728
13729    public void registerProcessObserver(IProcessObserver observer) {
13730        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13731                "registerProcessObserver()");
13732        synchronized (this) {
13733            mProcessObservers.register(observer);
13734        }
13735    }
13736
13737    @Override
13738    public void unregisterProcessObserver(IProcessObserver observer) {
13739        synchronized (this) {
13740            mProcessObservers.unregister(observer);
13741        }
13742    }
13743
13744    @Override
13745    public int getUidProcessState(int uid, String callingPackage) {
13746        if (!hasUsageStatsPermission(callingPackage)) {
13747            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13748                    "getUidProcessState");
13749        }
13750
13751        synchronized (this) {
13752            UidRecord uidRec = mActiveUids.get(uid);
13753            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13754        }
13755    }
13756
13757    @Override
13758    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13759            String callingPackage) {
13760        if (!hasUsageStatsPermission(callingPackage)) {
13761            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13762                    "registerUidObserver");
13763        }
13764        synchronized (this) {
13765            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13766                    callingPackage, which, cutpoint));
13767        }
13768    }
13769
13770    @Override
13771    public void unregisterUidObserver(IUidObserver observer) {
13772        synchronized (this) {
13773            mUidObservers.unregister(observer);
13774        }
13775    }
13776
13777    @Override
13778    public boolean convertFromTranslucent(IBinder token) {
13779        final long origId = Binder.clearCallingIdentity();
13780        try {
13781            synchronized (this) {
13782                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13783                if (r == null) {
13784                    return false;
13785                }
13786                final boolean translucentChanged = r.changeWindowTranslucency(true);
13787                if (translucentChanged) {
13788                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13789                }
13790                mWindowManager.setAppFullscreen(token, true);
13791                return translucentChanged;
13792            }
13793        } finally {
13794            Binder.restoreCallingIdentity(origId);
13795        }
13796    }
13797
13798    @Override
13799    public boolean convertToTranslucent(IBinder token, Bundle options) {
13800        SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
13801        final long origId = Binder.clearCallingIdentity();
13802        try {
13803            synchronized (this) {
13804                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13805                if (r == null) {
13806                    return false;
13807                }
13808                final TaskRecord task = r.getTask();
13809                int index = task.mActivities.lastIndexOf(r);
13810                if (index > 0) {
13811                    ActivityRecord under = task.mActivities.get(index - 1);
13812                    under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
13813                }
13814                final boolean translucentChanged = r.changeWindowTranslucency(false);
13815                if (translucentChanged) {
13816                    r.getStack().convertActivityToTranslucent(r);
13817                }
13818                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13819                mWindowManager.setAppFullscreen(token, false);
13820                return translucentChanged;
13821            }
13822        } finally {
13823            Binder.restoreCallingIdentity(origId);
13824        }
13825    }
13826
13827    @Override
13828    public Bundle getActivityOptions(IBinder token) {
13829        final long origId = Binder.clearCallingIdentity();
13830        try {
13831            synchronized (this) {
13832                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13833                if (r != null) {
13834                    final ActivityOptions activityOptions = r.takeOptionsLocked();
13835                    return activityOptions == null ? null : activityOptions.toBundle();
13836                }
13837                return null;
13838            }
13839        } finally {
13840            Binder.restoreCallingIdentity(origId);
13841        }
13842    }
13843
13844    @Override
13845    public void setImmersive(IBinder token, boolean immersive) {
13846        synchronized(this) {
13847            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13848            if (r == null) {
13849                throw new IllegalArgumentException();
13850            }
13851            r.immersive = immersive;
13852
13853            // update associated state if we're frontmost
13854            if (r == mStackSupervisor.getResumedActivityLocked()) {
13855                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13856                applyUpdateLockStateLocked(r);
13857            }
13858        }
13859    }
13860
13861    @Override
13862    public boolean isImmersive(IBinder token) {
13863        synchronized (this) {
13864            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13865            if (r == null) {
13866                throw new IllegalArgumentException();
13867            }
13868            return r.immersive;
13869        }
13870    }
13871
13872    @Override
13873    public void setVrThread(int tid) {
13874        enforceSystemHasVrFeature();
13875        synchronized (this) {
13876            synchronized (mPidsSelfLocked) {
13877                final int pid = Binder.getCallingPid();
13878                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13879                mVrController.setVrThreadLocked(tid, pid, proc);
13880            }
13881        }
13882    }
13883
13884    @Override
13885    public void setPersistentVrThread(int tid) {
13886        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13887            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13888                    + Binder.getCallingPid()
13889                    + ", uid=" + Binder.getCallingUid()
13890                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13891            Slog.w(TAG, msg);
13892            throw new SecurityException(msg);
13893        }
13894        enforceSystemHasVrFeature();
13895        synchronized (this) {
13896            synchronized (mPidsSelfLocked) {
13897                final int pid = Binder.getCallingPid();
13898                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13899                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13900            }
13901        }
13902    }
13903
13904    /**
13905     * Schedule the given thread a normal scheduling priority.
13906     *
13907     * @param tid the tid of the thread to adjust the scheduling of.
13908     * @param suppressLogs {@code true} if any error logging should be disabled.
13909     *
13910     * @return {@code true} if this succeeded.
13911     */
13912    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13913        try {
13914            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13915            return true;
13916        } catch (IllegalArgumentException e) {
13917            if (!suppressLogs) {
13918                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13919            }
13920        } catch (SecurityException e) {
13921            if (!suppressLogs) {
13922                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13923            }
13924        }
13925        return false;
13926    }
13927
13928    /**
13929     * Schedule the given thread an FIFO scheduling priority.
13930     *
13931     * @param tid the tid of the thread to adjust the scheduling of.
13932     * @param suppressLogs {@code true} if any error logging should be disabled.
13933     *
13934     * @return {@code true} if this succeeded.
13935     */
13936    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13937        try {
13938            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13939            return true;
13940        } catch (IllegalArgumentException e) {
13941            if (!suppressLogs) {
13942                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13943            }
13944        } catch (SecurityException e) {
13945            if (!suppressLogs) {
13946                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13947            }
13948        }
13949        return false;
13950    }
13951
13952    /**
13953     * Check that we have the features required for VR-related API calls, and throw an exception if
13954     * not.
13955     */
13956    private void enforceSystemHasVrFeature() {
13957        if (!mContext.getPackageManager().hasSystemFeature(
13958                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
13959            throw new UnsupportedOperationException("VR mode not supported on this device!");
13960        }
13961    }
13962
13963    @Override
13964    public void setRenderThread(int tid) {
13965        synchronized (this) {
13966            ProcessRecord proc;
13967            int pid = Binder.getCallingPid();
13968            if (pid == Process.myPid()) {
13969                demoteSystemServerRenderThread(tid);
13970                return;
13971            }
13972            synchronized (mPidsSelfLocked) {
13973                proc = mPidsSelfLocked.get(pid);
13974                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13975                    // ensure the tid belongs to the process
13976                    if (!isThreadInProcess(pid, tid)) {
13977                        throw new IllegalArgumentException(
13978                            "Render thread does not belong to process");
13979                    }
13980                    proc.renderThreadTid = tid;
13981                    if (DEBUG_OOM_ADJ) {
13982                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13983                    }
13984                    // promote to FIFO now
13985                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13986                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13987                        if (mUseFifoUiScheduling) {
13988                            setThreadScheduler(proc.renderThreadTid,
13989                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13990                        } else {
13991                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13992                        }
13993                    }
13994                } else {
13995                    if (DEBUG_OOM_ADJ) {
13996                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13997                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13998                               mUseFifoUiScheduling);
13999                    }
14000                }
14001            }
14002        }
14003    }
14004
14005    /**
14006     * We only use RenderThread in system_server to store task snapshots to the disk, which should
14007     * happen in the background. Thus, demote render thread from system_server to a lower priority.
14008     *
14009     * @param tid the tid of the RenderThread
14010     */
14011    private void demoteSystemServerRenderThread(int tid) {
14012        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
14013    }
14014
14015    @Override
14016    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
14017        enforceSystemHasVrFeature();
14018
14019        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14020
14021        ActivityRecord r;
14022        synchronized (this) {
14023            r = ActivityRecord.isInStackLocked(token);
14024        }
14025
14026        if (r == null) {
14027            throw new IllegalArgumentException();
14028        }
14029
14030        int err;
14031        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
14032                VrManagerInternal.NO_ERROR) {
14033            return err;
14034        }
14035
14036        synchronized(this) {
14037            r.requestedVrComponent = (enabled) ? packageName : null;
14038
14039            // Update associated state if this activity is currently focused
14040            if (r == mStackSupervisor.getResumedActivityLocked()) {
14041                applyUpdateVrModeLocked(r);
14042            }
14043            return 0;
14044        }
14045    }
14046
14047    @Override
14048    public boolean isVrModePackageEnabled(ComponentName packageName) {
14049        enforceSystemHasVrFeature();
14050
14051        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14052
14053        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
14054                VrManagerInternal.NO_ERROR;
14055    }
14056
14057    public boolean isTopActivityImmersive() {
14058        enforceNotIsolatedCaller("startActivity");
14059        synchronized (this) {
14060            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
14061            return (r != null) ? r.immersive : false;
14062        }
14063    }
14064
14065    /**
14066     * @return whether the system should disable UI modes incompatible with VR mode.
14067     */
14068    boolean shouldDisableNonVrUiLocked() {
14069        return mVrController.shouldDisableNonVrUiLocked();
14070    }
14071
14072    @Override
14073    public boolean isTopOfTask(IBinder token) {
14074        synchronized (this) {
14075            ActivityRecord r = ActivityRecord.isInStackLocked(token);
14076            if (r == null) {
14077                throw new IllegalArgumentException();
14078            }
14079            return r.getTask().getTopActivity() == r;
14080        }
14081    }
14082
14083    @Override
14084    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
14085        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
14086            String msg = "Permission Denial: setHasTopUi() from pid="
14087                    + Binder.getCallingPid()
14088                    + ", uid=" + Binder.getCallingUid()
14089                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
14090            Slog.w(TAG, msg);
14091            throw new SecurityException(msg);
14092        }
14093        final int pid = Binder.getCallingPid();
14094        final long origId = Binder.clearCallingIdentity();
14095        try {
14096            synchronized (this) {
14097                boolean changed = false;
14098                ProcessRecord pr;
14099                synchronized (mPidsSelfLocked) {
14100                    pr = mPidsSelfLocked.get(pid);
14101                    if (pr == null) {
14102                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
14103                        return;
14104                    }
14105                    if (pr.hasTopUi != hasTopUi) {
14106                        if (DEBUG_OOM_ADJ) {
14107                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
14108                        }
14109                        pr.hasTopUi = hasTopUi;
14110                        changed = true;
14111                    }
14112                }
14113                if (changed) {
14114                    updateOomAdjLocked(pr, true);
14115                }
14116            }
14117        } finally {
14118            Binder.restoreCallingIdentity(origId);
14119        }
14120    }
14121
14122    public final void enterSafeMode() {
14123        synchronized(this) {
14124            // It only makes sense to do this before the system is ready
14125            // and started launching other packages.
14126            if (!mSystemReady) {
14127                try {
14128                    AppGlobals.getPackageManager().enterSafeMode();
14129                } catch (RemoteException e) {
14130                }
14131            }
14132
14133            mSafeMode = true;
14134        }
14135    }
14136
14137    public final void showSafeModeOverlay() {
14138        View v = LayoutInflater.from(mContext).inflate(
14139                com.android.internal.R.layout.safe_mode, null);
14140        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
14141        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
14142        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
14143        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
14144        lp.gravity = Gravity.BOTTOM | Gravity.START;
14145        lp.format = v.getBackground().getOpacity();
14146        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
14147                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
14148        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
14149        ((WindowManager)mContext.getSystemService(
14150                Context.WINDOW_SERVICE)).addView(v, lp);
14151    }
14152
14153    @Override
14154    public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
14155            String sourcePkg, String tag) {
14156        if (workSource != null && workSource.isEmpty()) {
14157            workSource = null;
14158        }
14159
14160        if (sourceUid <= 0 && workSource == null) {
14161            // Try and derive a UID to attribute things to based on the caller.
14162            if (sender != null) {
14163                if (!(sender instanceof PendingIntentRecord)) {
14164                    return;
14165                }
14166
14167                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14168                final int callerUid = Binder.getCallingUid();
14169                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14170            } else {
14171                // TODO(narayan): Should we throw an exception in this case ? It means that we
14172                // haven't been able to derive a UID to attribute things to.
14173                return;
14174            }
14175        }
14176
14177        if (DEBUG_POWER) {
14178            Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
14179                    + ", workSource=" + workSource + ", tag=" + tag + "]");
14180        }
14181
14182        mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
14183    }
14184
14185    @Override
14186    public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14187            String tag) {
14188        if (workSource != null && workSource.isEmpty()) {
14189            workSource = null;
14190        }
14191
14192        if (sourceUid <= 0 && workSource == null) {
14193            // Try and derive a UID to attribute things to based on the caller.
14194            if (sender != null) {
14195                if (!(sender instanceof PendingIntentRecord)) {
14196                    return;
14197                }
14198
14199                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14200                final int callerUid = Binder.getCallingUid();
14201                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14202            } else {
14203                // TODO(narayan): Should we throw an exception in this case ? It means that we
14204                // haven't been able to derive a UID to attribute things to.
14205                return;
14206            }
14207        }
14208
14209        if (DEBUG_POWER) {
14210            Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14211                    ", tag=" + tag + "]");
14212        }
14213
14214        mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14215    }
14216
14217    @Override
14218    public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14219            String tag) {
14220        if (workSource != null && workSource.isEmpty()) {
14221            workSource = null;
14222        }
14223
14224        if (sourceUid <= 0 && workSource == null) {
14225            // Try and derive a UID to attribute things to based on the caller.
14226            if (sender != null) {
14227                if (!(sender instanceof PendingIntentRecord)) {
14228                    return;
14229                }
14230
14231                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14232                final int callerUid = Binder.getCallingUid();
14233                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14234            } else {
14235                // TODO(narayan): Should we throw an exception in this case ? It means that we
14236                // haven't been able to derive a UID to attribute things to.
14237                return;
14238            }
14239        }
14240
14241        if (DEBUG_POWER) {
14242            Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14243                    ", tag=" + tag + "]");
14244        }
14245
14246        mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
14247    }
14248
14249    public boolean killPids(int[] pids, String pReason, boolean secure) {
14250        if (Binder.getCallingUid() != SYSTEM_UID) {
14251            throw new SecurityException("killPids only available to the system");
14252        }
14253        String reason = (pReason == null) ? "Unknown" : pReason;
14254        // XXX Note: don't acquire main activity lock here, because the window
14255        // manager calls in with its locks held.
14256
14257        boolean killed = false;
14258        synchronized (mPidsSelfLocked) {
14259            int worstType = 0;
14260            for (int i=0; i<pids.length; i++) {
14261                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14262                if (proc != null) {
14263                    int type = proc.setAdj;
14264                    if (type > worstType) {
14265                        worstType = type;
14266                    }
14267                }
14268            }
14269
14270            // If the worst oom_adj is somewhere in the cached proc LRU range,
14271            // then constrain it so we will kill all cached procs.
14272            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14273                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14274                worstType = ProcessList.CACHED_APP_MIN_ADJ;
14275            }
14276
14277            // If this is not a secure call, don't let it kill processes that
14278            // are important.
14279            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14280                worstType = ProcessList.SERVICE_ADJ;
14281            }
14282
14283            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14284            for (int i=0; i<pids.length; i++) {
14285                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14286                if (proc == null) {
14287                    continue;
14288                }
14289                int adj = proc.setAdj;
14290                if (adj >= worstType && !proc.killedByAm) {
14291                    proc.kill(reason, true);
14292                    killed = true;
14293                }
14294            }
14295        }
14296        return killed;
14297    }
14298
14299    @Override
14300    public void killUid(int appId, int userId, String reason) {
14301        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14302        synchronized (this) {
14303            final long identity = Binder.clearCallingIdentity();
14304            try {
14305                killPackageProcessesLocked(null, appId, userId,
14306                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14307                        reason != null ? reason : "kill uid");
14308            } finally {
14309                Binder.restoreCallingIdentity(identity);
14310            }
14311        }
14312    }
14313
14314    @Override
14315    public boolean killProcessesBelowForeground(String reason) {
14316        if (Binder.getCallingUid() != SYSTEM_UID) {
14317            throw new SecurityException("killProcessesBelowForeground() only available to system");
14318        }
14319
14320        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14321    }
14322
14323    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14324        if (Binder.getCallingUid() != SYSTEM_UID) {
14325            throw new SecurityException("killProcessesBelowAdj() only available to system");
14326        }
14327
14328        boolean killed = false;
14329        synchronized (mPidsSelfLocked) {
14330            final int size = mPidsSelfLocked.size();
14331            for (int i = 0; i < size; i++) {
14332                final int pid = mPidsSelfLocked.keyAt(i);
14333                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14334                if (proc == null) continue;
14335
14336                final int adj = proc.setAdj;
14337                if (adj > belowAdj && !proc.killedByAm) {
14338                    proc.kill(reason, true);
14339                    killed = true;
14340                }
14341            }
14342        }
14343        return killed;
14344    }
14345
14346    @Override
14347    public void hang(final IBinder who, boolean allowRestart) {
14348        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14349                != PackageManager.PERMISSION_GRANTED) {
14350            throw new SecurityException("Requires permission "
14351                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14352        }
14353
14354        final IBinder.DeathRecipient death = new DeathRecipient() {
14355            @Override
14356            public void binderDied() {
14357                synchronized (this) {
14358                    notifyAll();
14359                }
14360            }
14361        };
14362
14363        try {
14364            who.linkToDeath(death, 0);
14365        } catch (RemoteException e) {
14366            Slog.w(TAG, "hang: given caller IBinder is already dead.");
14367            return;
14368        }
14369
14370        synchronized (this) {
14371            Watchdog.getInstance().setAllowRestart(allowRestart);
14372            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14373            synchronized (death) {
14374                while (who.isBinderAlive()) {
14375                    try {
14376                        death.wait();
14377                    } catch (InterruptedException e) {
14378                    }
14379                }
14380            }
14381            Watchdog.getInstance().setAllowRestart(true);
14382        }
14383    }
14384
14385    @Override
14386    public void restart() {
14387        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14388                != PackageManager.PERMISSION_GRANTED) {
14389            throw new SecurityException("Requires permission "
14390                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14391        }
14392
14393        Log.i(TAG, "Sending shutdown broadcast...");
14394
14395        BroadcastReceiver br = new BroadcastReceiver() {
14396            @Override public void onReceive(Context context, Intent intent) {
14397                // Now the broadcast is done, finish up the low-level shutdown.
14398                Log.i(TAG, "Shutting down activity manager...");
14399                shutdown(10000);
14400                Log.i(TAG, "Shutdown complete, restarting!");
14401                killProcess(myPid());
14402                System.exit(10);
14403            }
14404        };
14405
14406        // First send the high-level shut down broadcast.
14407        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14408        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14409        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
14410        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
14411        mContext.sendOrderedBroadcastAsUser(intent,
14412                UserHandle.ALL, null, br, mHandler, 0, null, null);
14413        */
14414        br.onReceive(mContext, intent);
14415    }
14416
14417    private long getLowRamTimeSinceIdle(long now) {
14418        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
14419    }
14420
14421    @Override
14422    public void performIdleMaintenance() {
14423        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14424                != PackageManager.PERMISSION_GRANTED) {
14425            throw new SecurityException("Requires permission "
14426                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14427        }
14428
14429        synchronized (this) {
14430            final long now = SystemClock.uptimeMillis();
14431            final long timeSinceLastIdle = now - mLastIdleTime;
14432            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
14433            mLastIdleTime = now;
14434            mLowRamTimeSinceLastIdle = 0;
14435            if (mLowRamStartTime != 0) {
14436                mLowRamStartTime = now;
14437            }
14438
14439            StringBuilder sb = new StringBuilder(128);
14440            sb.append("Idle maintenance over ");
14441            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14442            sb.append(" low RAM for ");
14443            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14444            Slog.i(TAG, sb.toString());
14445
14446            // If at least 1/3 of our time since the last idle period has been spent
14447            // with RAM low, then we want to kill processes.
14448            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14449
14450            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14451                ProcessRecord proc = mLruProcesses.get(i);
14452                if (proc.notCachedSinceIdle) {
14453                    if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
14454                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14455                        if (doKilling && proc.initialIdlePss != 0
14456                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14457                            sb = new StringBuilder(128);
14458                            sb.append("Kill");
14459                            sb.append(proc.processName);
14460                            sb.append(" in idle maint: pss=");
14461                            sb.append(proc.lastPss);
14462                            sb.append(", swapPss=");
14463                            sb.append(proc.lastSwapPss);
14464                            sb.append(", initialPss=");
14465                            sb.append(proc.initialIdlePss);
14466                            sb.append(", period=");
14467                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14468                            sb.append(", lowRamPeriod=");
14469                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14470                            Slog.wtfQuiet(TAG, sb.toString());
14471                            proc.kill("idle maint (pss " + proc.lastPss
14472                                    + " from " + proc.initialIdlePss + ")", true);
14473                        }
14474                    }
14475                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14476                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14477                    proc.notCachedSinceIdle = true;
14478                    proc.initialIdlePss = 0;
14479                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
14480                            mTestPssMode, isSleepingLocked(), now);
14481                }
14482            }
14483
14484            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14485            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14486        }
14487    }
14488
14489    @Override
14490    public void sendIdleJobTrigger() {
14491        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14492                != PackageManager.PERMISSION_GRANTED) {
14493            throw new SecurityException("Requires permission "
14494                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14495        }
14496
14497        final long ident = Binder.clearCallingIdentity();
14498        try {
14499            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14500                    .setPackage("android")
14501                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14502            broadcastIntent(null, intent, null, null, 0, null, null, null,
14503                    OP_NONE, null, true, false, UserHandle.USER_ALL);
14504        } finally {
14505            Binder.restoreCallingIdentity(ident);
14506        }
14507    }
14508
14509    private void retrieveSettings() {
14510        final ContentResolver resolver = mContext.getContentResolver();
14511        final boolean freeformWindowManagement =
14512                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14513                        || Settings.Global.getInt(
14514                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14515
14516        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14517        final boolean supportsPictureInPicture = supportsMultiWindow &&
14518                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14519        final boolean supportsSplitScreenMultiWindow =
14520                ActivityManager.supportsSplitScreenMultiWindow(mContext);
14521        final boolean supportsMultiDisplay = mContext.getPackageManager()
14522                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14523        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14524        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14525        final boolean alwaysFinishActivities =
14526                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14527        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14528        final boolean forceResizable = Settings.Global.getInt(
14529                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14530        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14531                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14532        final boolean supportsLeanbackOnly =
14533                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14534
14535        // Transfer any global setting for forcing RTL layout, into a System Property
14536        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14537
14538        final Configuration configuration = new Configuration();
14539        Settings.System.getConfiguration(resolver, configuration);
14540        if (forceRtl) {
14541            // This will take care of setting the correct layout direction flags
14542            configuration.setLayoutDirection(configuration.locale);
14543        }
14544
14545        synchronized (this) {
14546            mDebugApp = mOrigDebugApp = debugApp;
14547            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14548            mAlwaysFinishActivities = alwaysFinishActivities;
14549            mSupportsLeanbackOnly = supportsLeanbackOnly;
14550            mForceResizableActivities = forceResizable;
14551            final boolean multiWindowFormEnabled = freeformWindowManagement
14552                    || supportsSplitScreenMultiWindow
14553                    || supportsPictureInPicture
14554                    || supportsMultiDisplay;
14555            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14556                mSupportsMultiWindow = true;
14557                mSupportsFreeformWindowManagement = freeformWindowManagement;
14558                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14559                mSupportsPictureInPicture = supportsPictureInPicture;
14560                mSupportsMultiDisplay = supportsMultiDisplay;
14561            } else {
14562                mSupportsMultiWindow = false;
14563                mSupportsFreeformWindowManagement = false;
14564                mSupportsSplitScreenMultiWindow = false;
14565                mSupportsPictureInPicture = false;
14566                mSupportsMultiDisplay = false;
14567            }
14568            mWindowManager.setForceResizableTasks(mForceResizableActivities);
14569            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14570            // This happens before any activities are started, so we can change global configuration
14571            // in-place.
14572            updateConfigurationLocked(configuration, null, true);
14573            final Configuration globalConfig = getGlobalConfiguration();
14574            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14575
14576            // Load resources only after the current configuration has been set.
14577            final Resources res = mContext.getResources();
14578            mThumbnailWidth = res.getDimensionPixelSize(
14579                    com.android.internal.R.dimen.thumbnail_width);
14580            mThumbnailHeight = res.getDimensionPixelSize(
14581                    com.android.internal.R.dimen.thumbnail_height);
14582            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14583                    com.android.internal.R.string.config_appsNotReportingCrashes));
14584            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14585                    com.android.internal.R.bool.config_customUserSwitchUi);
14586            mUserController.mMaxRunningUsers = res.getInteger(
14587                    com.android.internal.R.integer.config_multiuserMaxRunningUsers);
14588
14589            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14590                mFullscreenThumbnailScale = (float) res
14591                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14592                    (float) globalConfig.screenWidthDp;
14593            } else {
14594                mFullscreenThumbnailScale = res.getFraction(
14595                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14596            }
14597            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14598        }
14599    }
14600
14601    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14602        traceLog.traceBegin("PhaseActivityManagerReady");
14603        synchronized(this) {
14604            if (mSystemReady) {
14605                // If we're done calling all the receivers, run the next "boot phase" passed in
14606                // by the SystemServer
14607                if (goingCallback != null) {
14608                    goingCallback.run();
14609                }
14610                return;
14611            }
14612
14613            mLocalDeviceIdleController
14614                    = LocalServices.getService(DeviceIdleController.LocalService.class);
14615            mAssistUtils = new AssistUtils(mContext);
14616            mVrController.onSystemReady();
14617            // Make sure we have the current profile info, since it is needed for security checks.
14618            mUserController.onSystemReady();
14619            mRecentTasks.onSystemReadyLocked();
14620            mAppOpsService.systemReady();
14621            mSystemReady = true;
14622        }
14623
14624        try {
14625            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14626                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14627                    .getSerial();
14628        } catch (RemoteException e) {}
14629
14630        ArrayList<ProcessRecord> procsToKill = null;
14631        synchronized(mPidsSelfLocked) {
14632            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14633                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14634                if (!isAllowedWhileBooting(proc.info)){
14635                    if (procsToKill == null) {
14636                        procsToKill = new ArrayList<ProcessRecord>();
14637                    }
14638                    procsToKill.add(proc);
14639                }
14640            }
14641        }
14642
14643        synchronized(this) {
14644            if (procsToKill != null) {
14645                for (int i=procsToKill.size()-1; i>=0; i--) {
14646                    ProcessRecord proc = procsToKill.get(i);
14647                    Slog.i(TAG, "Removing system update proc: " + proc);
14648                    removeProcessLocked(proc, true, false, "system update done");
14649                }
14650            }
14651
14652            // Now that we have cleaned up any update processes, we
14653            // are ready to start launching real processes and know that
14654            // we won't trample on them any more.
14655            mProcessesReady = true;
14656        }
14657
14658        Slog.i(TAG, "System now ready");
14659        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14660            SystemClock.uptimeMillis());
14661
14662        synchronized(this) {
14663            // Make sure we have no pre-ready processes sitting around.
14664
14665            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14666                ResolveInfo ri = mContext.getPackageManager()
14667                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14668                                STOCK_PM_FLAGS);
14669                CharSequence errorMsg = null;
14670                if (ri != null) {
14671                    ActivityInfo ai = ri.activityInfo;
14672                    ApplicationInfo app = ai.applicationInfo;
14673                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14674                        mTopAction = Intent.ACTION_FACTORY_TEST;
14675                        mTopData = null;
14676                        mTopComponent = new ComponentName(app.packageName,
14677                                ai.name);
14678                    } else {
14679                        errorMsg = mContext.getResources().getText(
14680                                com.android.internal.R.string.factorytest_not_system);
14681                    }
14682                } else {
14683                    errorMsg = mContext.getResources().getText(
14684                            com.android.internal.R.string.factorytest_no_action);
14685                }
14686                if (errorMsg != null) {
14687                    mTopAction = null;
14688                    mTopData = null;
14689                    mTopComponent = null;
14690                    Message msg = Message.obtain();
14691                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14692                    msg.getData().putCharSequence("msg", errorMsg);
14693                    mUiHandler.sendMessage(msg);
14694                }
14695            }
14696        }
14697
14698        retrieveSettings();
14699        final int currentUserId = mUserController.getCurrentUserId();
14700        synchronized (this) {
14701            readGrantedUriPermissionsLocked();
14702        }
14703
14704        final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
14705        if (pmi != null) {
14706            pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
14707                    state -> updateForceBackgroundCheck(state.batterySaverEnabled));
14708            updateForceBackgroundCheck(
14709                    pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
14710        } else {
14711            Slog.wtf(TAG, "PowerManagerInternal not found.");
14712        }
14713
14714        if (goingCallback != null) goingCallback.run();
14715        traceLog.traceBegin("ActivityManagerStartApps");
14716        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14717                Integer.toString(currentUserId), currentUserId);
14718        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14719                Integer.toString(currentUserId), currentUserId);
14720        mSystemServiceManager.startUser(currentUserId);
14721
14722        synchronized (this) {
14723            // Only start up encryption-aware persistent apps; once user is
14724            // unlocked we'll come back around and start unaware apps
14725            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14726
14727            // Start up initial activity.
14728            mBooting = true;
14729            // Enable home activity for system user, so that the system can always boot. We don't
14730            // do this when the system user is not setup since the setup wizard should be the one
14731            // to handle home activity in this case.
14732            if (UserManager.isSplitSystemUser() &&
14733                    Settings.Secure.getInt(mContext.getContentResolver(),
14734                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14735                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14736                try {
14737                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14738                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14739                            UserHandle.USER_SYSTEM);
14740                } catch (RemoteException e) {
14741                    throw e.rethrowAsRuntimeException();
14742                }
14743            }
14744            startHomeActivityLocked(currentUserId, "systemReady");
14745
14746            try {
14747                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14748                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14749                            + " data partition or your device will be unstable.");
14750                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14751                }
14752            } catch (RemoteException e) {
14753            }
14754
14755            if (!Build.isBuildConsistent()) {
14756                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14757                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14758            }
14759
14760            long ident = Binder.clearCallingIdentity();
14761            try {
14762                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14763                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14764                        | Intent.FLAG_RECEIVER_FOREGROUND);
14765                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14766                broadcastIntentLocked(null, null, intent,
14767                        null, null, 0, null, null, null, OP_NONE,
14768                        null, false, false, MY_PID, SYSTEM_UID,
14769                        currentUserId);
14770                intent = new Intent(Intent.ACTION_USER_STARTING);
14771                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14772                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14773                broadcastIntentLocked(null, null, intent,
14774                        null, new IIntentReceiver.Stub() {
14775                            @Override
14776                            public void performReceive(Intent intent, int resultCode, String data,
14777                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14778                                    throws RemoteException {
14779                            }
14780                        }, 0, null, null,
14781                        new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
14782                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14783            } catch (Throwable t) {
14784                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14785            } finally {
14786                Binder.restoreCallingIdentity(ident);
14787            }
14788            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14789            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
14790
14791            BinderInternal.nSetBinderProxyCountEnabled(true);
14792            //STOPSHIP: Temporary BinderProxy Threshold for b/71353150
14793            BinderInternal.nSetBinderProxyCountWatermarks(1500, 1200);
14794            BinderInternal.setBinderProxyCountCallback(
14795                    new BinderInternal.BinderProxyLimitListener() {
14796                        @Override
14797                        public void onLimitReached(int uid) {
14798                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
14799                                    + Process.myUid());
14800                            if (uid == Process.SYSTEM_UID) {
14801                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
14802                            } else {
14803                                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
14804                                        "Too many Binders sent to SYSTEM");
14805                            }
14806                        }
14807                    }, mHandler);
14808
14809            traceLog.traceEnd(); // ActivityManagerStartApps
14810            traceLog.traceEnd(); // PhaseActivityManagerReady
14811        }
14812    }
14813
14814    private void updateForceBackgroundCheck(boolean enabled) {
14815        synchronized (this) {
14816            if (mForceBackgroundCheck != enabled) {
14817                mForceBackgroundCheck = enabled;
14818
14819                if (DEBUG_BACKGROUND_CHECK) {
14820                    Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
14821                }
14822
14823                if (mForceBackgroundCheck) {
14824                    // Stop background services for idle UIDs.
14825                    doStopUidForIdleUidsLocked();
14826                }
14827            }
14828        }
14829    }
14830
14831    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14832        synchronized (this) {
14833            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14834        }
14835    }
14836
14837    void skipCurrentReceiverLocked(ProcessRecord app) {
14838        for (BroadcastQueue queue : mBroadcastQueues) {
14839            queue.skipCurrentReceiverLocked(app);
14840        }
14841    }
14842
14843    /**
14844     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14845     * The application process will exit immediately after this call returns.
14846     * @param app object of the crashing app, null for the system server
14847     * @param crashInfo describing the exception
14848     */
14849    public void handleApplicationCrash(IBinder app,
14850            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14851        ProcessRecord r = findAppProcess(app, "Crash");
14852        final String processName = app == null ? "system_server"
14853                : (r == null ? "unknown" : r.processName);
14854
14855        handleApplicationCrashInner("crash", r, processName, crashInfo);
14856    }
14857
14858    /* Native crash reporting uses this inner version because it needs to be somewhat
14859     * decoupled from the AM-managed cleanup lifecycle
14860     */
14861    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14862            ApplicationErrorReport.CrashInfo crashInfo) {
14863        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14864                UserHandle.getUserId(Binder.getCallingUid()), processName,
14865                r == null ? -1 : r.info.flags,
14866                crashInfo.exceptionClassName,
14867                crashInfo.exceptionMessage,
14868                crashInfo.throwFileName,
14869                crashInfo.throwLineNumber);
14870
14871        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14872
14873        mAppErrors.crashApplication(r, crashInfo);
14874    }
14875
14876    public void handleApplicationStrictModeViolation(
14877            IBinder app,
14878            int violationMask,
14879            StrictMode.ViolationInfo info) {
14880        // We're okay if the ProcessRecord is missing; it probably means that
14881        // we're reporting a violation from the system process itself.
14882        final ProcessRecord r = findAppProcess(app, "StrictMode");
14883
14884        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14885            Integer stackFingerprint = info.hashCode();
14886            boolean logIt = true;
14887            synchronized (mAlreadyLoggedViolatedStacks) {
14888                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14889                    logIt = false;
14890                    // TODO: sub-sample into EventLog for these, with
14891                    // the info.durationMillis?  Then we'd get
14892                    // the relative pain numbers, without logging all
14893                    // the stack traces repeatedly.  We'd want to do
14894                    // likewise in the client code, which also does
14895                    // dup suppression, before the Binder call.
14896                } else {
14897                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14898                        mAlreadyLoggedViolatedStacks.clear();
14899                    }
14900                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14901                }
14902            }
14903            if (logIt) {
14904                logStrictModeViolationToDropBox(r, info);
14905            }
14906        }
14907
14908        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14909            AppErrorResult result = new AppErrorResult();
14910            synchronized (this) {
14911                final long origId = Binder.clearCallingIdentity();
14912
14913                Message msg = Message.obtain();
14914                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14915                HashMap<String, Object> data = new HashMap<String, Object>();
14916                data.put("result", result);
14917                data.put("app", r);
14918                data.put("violationMask", violationMask);
14919                data.put("info", info);
14920                msg.obj = data;
14921                mUiHandler.sendMessage(msg);
14922
14923                Binder.restoreCallingIdentity(origId);
14924            }
14925            int res = result.get();
14926            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14927        }
14928    }
14929
14930    // Depending on the policy in effect, there could be a bunch of
14931    // these in quick succession so we try to batch these together to
14932    // minimize disk writes, number of dropbox entries, and maximize
14933    // compression, by having more fewer, larger records.
14934    private void logStrictModeViolationToDropBox(
14935            ProcessRecord process,
14936            StrictMode.ViolationInfo info) {
14937        if (info == null) {
14938            return;
14939        }
14940        final boolean isSystemApp = process == null ||
14941                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14942                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14943        final String processName = process == null ? "unknown" : process.processName;
14944        final DropBoxManager dbox = (DropBoxManager)
14945                mContext.getSystemService(Context.DROPBOX_SERVICE);
14946
14947        // Exit early if the dropbox isn't configured to accept this report type.
14948        final String dropboxTag = processClass(process) + "_strictmode";
14949        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14950
14951        final StringBuilder sb = new StringBuilder(1024);
14952        synchronized (sb) {
14953            appendDropBoxProcessHeaders(process, processName, sb);
14954            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14955            sb.append("System-App: ").append(isSystemApp).append("\n");
14956            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14957            if (info.violationNumThisLoop != 0) {
14958                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14959            }
14960            if (info.numAnimationsRunning != 0) {
14961                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14962            }
14963            if (info.broadcastIntentAction != null) {
14964                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14965            }
14966            if (info.durationMillis != -1) {
14967                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14968            }
14969            if (info.numInstances != -1) {
14970                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14971            }
14972            if (info.tags != null) {
14973                for (String tag : info.tags) {
14974                    sb.append("Span-Tag: ").append(tag).append("\n");
14975                }
14976            }
14977            sb.append("\n");
14978            sb.append(info.getStackTrace());
14979            sb.append("\n");
14980            if (info.getViolationDetails() != null) {
14981                sb.append(info.getViolationDetails());
14982                sb.append("\n");
14983            }
14984        }
14985
14986        final String res = sb.toString();
14987        IoThread.getHandler().post(() -> {
14988            dbox.addText(dropboxTag, res);
14989        });
14990    }
14991
14992    /**
14993     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14994     * @param app object of the crashing app, null for the system server
14995     * @param tag reported by the caller
14996     * @param system whether this wtf is coming from the system
14997     * @param crashInfo describing the context of the error
14998     * @return true if the process should exit immediately (WTF is fatal)
14999     */
15000    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
15001            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15002        final int callingUid = Binder.getCallingUid();
15003        final int callingPid = Binder.getCallingPid();
15004
15005        if (system) {
15006            // If this is coming from the system, we could very well have low-level
15007            // system locks held, so we want to do this all asynchronously.  And we
15008            // never want this to become fatal, so there is that too.
15009            mHandler.post(new Runnable() {
15010                @Override public void run() {
15011                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
15012                }
15013            });
15014            return false;
15015        }
15016
15017        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
15018                crashInfo);
15019
15020        final boolean isFatal = Build.IS_ENG || Settings.Global
15021                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
15022        final boolean isSystem = (r == null) || r.persistent;
15023
15024        if (isFatal && !isSystem) {
15025            mAppErrors.crashApplication(r, crashInfo);
15026            return true;
15027        } else {
15028            return false;
15029        }
15030    }
15031
15032    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
15033            final ApplicationErrorReport.CrashInfo crashInfo) {
15034        final ProcessRecord r = findAppProcess(app, "WTF");
15035        final String processName = app == null ? "system_server"
15036                : (r == null ? "unknown" : r.processName);
15037
15038        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
15039                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
15040
15041        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
15042
15043        return r;
15044    }
15045
15046    /**
15047     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
15048     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
15049     */
15050    private ProcessRecord findAppProcess(IBinder app, String reason) {
15051        if (app == null) {
15052            return null;
15053        }
15054
15055        synchronized (this) {
15056            final int NP = mProcessNames.getMap().size();
15057            for (int ip=0; ip<NP; ip++) {
15058                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
15059                final int NA = apps.size();
15060                for (int ia=0; ia<NA; ia++) {
15061                    ProcessRecord p = apps.valueAt(ia);
15062                    if (p.thread != null && p.thread.asBinder() == app) {
15063                        return p;
15064                    }
15065                }
15066            }
15067
15068            Slog.w(TAG, "Can't find mystery application for " + reason
15069                    + " from pid=" + Binder.getCallingPid()
15070                    + " uid=" + Binder.getCallingUid() + ": " + app);
15071            return null;
15072        }
15073    }
15074
15075    /**
15076     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
15077     * to append various headers to the dropbox log text.
15078     */
15079    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
15080            StringBuilder sb) {
15081        // Watchdog thread ends up invoking this function (with
15082        // a null ProcessRecord) to add the stack file to dropbox.
15083        // Do not acquire a lock on this (am) in such cases, as it
15084        // could cause a potential deadlock, if and when watchdog
15085        // is invoked due to unavailability of lock on am and it
15086        // would prevent watchdog from killing system_server.
15087        if (process == null) {
15088            sb.append("Process: ").append(processName).append("\n");
15089            return;
15090        }
15091        // Note: ProcessRecord 'process' is guarded by the service
15092        // instance.  (notably process.pkgList, which could otherwise change
15093        // concurrently during execution of this method)
15094        synchronized (this) {
15095            sb.append("Process: ").append(processName).append("\n");
15096            sb.append("PID: ").append(process.pid).append("\n");
15097            int flags = process.info.flags;
15098            IPackageManager pm = AppGlobals.getPackageManager();
15099            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
15100            for (int ip=0; ip<process.pkgList.size(); ip++) {
15101                String pkg = process.pkgList.keyAt(ip);
15102                sb.append("Package: ").append(pkg);
15103                try {
15104                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
15105                    if (pi != null) {
15106                        sb.append(" v").append(pi.getLongVersionCode());
15107                        if (pi.versionName != null) {
15108                            sb.append(" (").append(pi.versionName).append(")");
15109                        }
15110                    }
15111                } catch (RemoteException e) {
15112                    Slog.e(TAG, "Error getting package info: " + pkg, e);
15113                }
15114                sb.append("\n");
15115            }
15116            if (process.info.isInstantApp()) {
15117                sb.append("Instant-App: true\n");
15118            }
15119        }
15120    }
15121
15122    private static String processClass(ProcessRecord process) {
15123        if (process == null || process.pid == MY_PID) {
15124            return "system_server";
15125        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15126            return "system_app";
15127        } else {
15128            return "data_app";
15129        }
15130    }
15131
15132    private volatile long mWtfClusterStart;
15133    private volatile int mWtfClusterCount;
15134
15135    /**
15136     * Write a description of an error (crash, WTF, ANR) to the drop box.
15137     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
15138     * @param process which caused the error, null means the system server
15139     * @param activity which triggered the error, null if unknown
15140     * @param parent activity related to the error, null if unknown
15141     * @param subject line related to the error, null if absent
15142     * @param report in long form describing the error, null if absent
15143     * @param dataFile text file to include in the report, null if none
15144     * @param crashInfo giving an application stack trace, null if absent
15145     */
15146    public void addErrorToDropBox(String eventType,
15147            ProcessRecord process, String processName, ActivityRecord activity,
15148            ActivityRecord parent, String subject,
15149            final String report, final File dataFile,
15150            final ApplicationErrorReport.CrashInfo crashInfo) {
15151        // NOTE -- this must never acquire the ActivityManagerService lock,
15152        // otherwise the watchdog may be prevented from resetting the system.
15153
15154        // Bail early if not published yet
15155        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
15156        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
15157
15158        // Exit early if the dropbox isn't configured to accept this report type.
15159        final String dropboxTag = processClass(process) + "_" + eventType;
15160        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15161
15162        // Log to StatsLog before the rate-limiting.
15163        // The logging below is adapated from appendDropboxProcessHeaders.
15164        StatsLog.write(StatsLog.DROPBOX_ERROR_CHANGED,
15165                process != null ? process.uid : -1,
15166                dropboxTag,
15167                processName,
15168                process != null ? process.pid : -1,
15169                (process != null && process.info != null) ?
15170                        (process.info.isInstantApp() ? 1 : 0) : -1,
15171                activity != null ? activity.shortComponentName : null,
15172                activity != null ? activity.packageName : null,
15173                process != null ? (process.isInterestingToUserLocked() ? 1 : 0) : -1);
15174
15175        // Rate-limit how often we're willing to do the heavy lifting below to
15176        // collect and record logs; currently 5 logs per 10 second period.
15177        final long now = SystemClock.elapsedRealtime();
15178        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
15179            mWtfClusterStart = now;
15180            mWtfClusterCount = 1;
15181        } else {
15182            if (mWtfClusterCount++ >= 5) return;
15183        }
15184
15185        final StringBuilder sb = new StringBuilder(1024);
15186        appendDropBoxProcessHeaders(process, processName, sb);
15187        if (process != null) {
15188            sb.append("Foreground: ")
15189                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
15190                    .append("\n");
15191        }
15192        if (activity != null) {
15193            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15194        }
15195        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15196            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15197        }
15198        if (parent != null && parent != activity) {
15199            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15200        }
15201        if (subject != null) {
15202            sb.append("Subject: ").append(subject).append("\n");
15203        }
15204        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15205        if (Debug.isDebuggerConnected()) {
15206            sb.append("Debugger: Connected\n");
15207        }
15208        sb.append("\n");
15209
15210        // Do the rest in a worker thread to avoid blocking the caller on I/O
15211        // (After this point, we shouldn't access AMS internal data structures.)
15212        Thread worker = new Thread("Error dump: " + dropboxTag) {
15213            @Override
15214            public void run() {
15215                if (report != null) {
15216                    sb.append(report);
15217                }
15218
15219                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
15220                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
15221                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
15222                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
15223
15224                if (dataFile != null && maxDataFileSize > 0) {
15225                    try {
15226                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15227                                    "\n\n[[TRUNCATED]]"));
15228                    } catch (IOException e) {
15229                        Slog.e(TAG, "Error reading " + dataFile, e);
15230                    }
15231                }
15232                if (crashInfo != null && crashInfo.stackTrace != null) {
15233                    sb.append(crashInfo.stackTrace);
15234                }
15235
15236                if (lines > 0) {
15237                    sb.append("\n");
15238
15239                    // Merge several logcat streams, and take the last N lines
15240                    InputStreamReader input = null;
15241                    try {
15242                        java.lang.Process logcat = new ProcessBuilder(
15243                                "/system/bin/timeout", "-k", "15s", "10s",
15244                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
15245                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
15246                                        .redirectErrorStream(true).start();
15247
15248                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
15249                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
15250                        input = new InputStreamReader(logcat.getInputStream());
15251
15252                        int num;
15253                        char[] buf = new char[8192];
15254                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
15255                    } catch (IOException e) {
15256                        Slog.e(TAG, "Error running logcat", e);
15257                    } finally {
15258                        if (input != null) try { input.close(); } catch (IOException e) {}
15259                    }
15260                }
15261
15262                dbox.addText(dropboxTag, sb.toString());
15263            }
15264        };
15265
15266        if (process == null) {
15267            // If process is null, we are being called from some internal code
15268            // and may be about to die -- run this synchronously.
15269            final int oldMask = StrictMode.allowThreadDiskWritesMask();
15270            try {
15271                worker.run();
15272            } finally {
15273                StrictMode.setThreadPolicyMask(oldMask);
15274            }
15275        } else {
15276            worker.start();
15277        }
15278    }
15279
15280    @Override
15281    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15282        enforceNotIsolatedCaller("getProcessesInErrorState");
15283        // assume our apps are happy - lazy create the list
15284        List<ActivityManager.ProcessErrorStateInfo> errList = null;
15285
15286        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15287                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15288        int userId = UserHandle.getUserId(Binder.getCallingUid());
15289
15290        synchronized (this) {
15291
15292            // iterate across all processes
15293            for (int i=mLruProcesses.size()-1; i>=0; i--) {
15294                ProcessRecord app = mLruProcesses.get(i);
15295                if (!allUsers && app.userId != userId) {
15296                    continue;
15297                }
15298                if ((app.thread != null) && (app.crashing || app.notResponding)) {
15299                    // This one's in trouble, so we'll generate a report for it
15300                    // crashes are higher priority (in case there's a crash *and* an anr)
15301                    ActivityManager.ProcessErrorStateInfo report = null;
15302                    if (app.crashing) {
15303                        report = app.crashingReport;
15304                    } else if (app.notResponding) {
15305                        report = app.notRespondingReport;
15306                    }
15307
15308                    if (report != null) {
15309                        if (errList == null) {
15310                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15311                        }
15312                        errList.add(report);
15313                    } else {
15314                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
15315                                " crashing = " + app.crashing +
15316                                " notResponding = " + app.notResponding);
15317                    }
15318                }
15319            }
15320        }
15321
15322        return errList;
15323    }
15324
15325    static int procStateToImportance(int procState, int memAdj,
15326            ActivityManager.RunningAppProcessInfo currApp,
15327            int clientTargetSdk) {
15328        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15329                procState, clientTargetSdk);
15330        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15331            currApp.lru = memAdj;
15332        } else {
15333            currApp.lru = 0;
15334        }
15335        return imp;
15336    }
15337
15338    private void fillInProcMemInfo(ProcessRecord app,
15339            ActivityManager.RunningAppProcessInfo outInfo,
15340            int clientTargetSdk) {
15341        outInfo.pid = app.pid;
15342        outInfo.uid = app.info.uid;
15343        if (mHeavyWeightProcess == app) {
15344            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15345        }
15346        if (app.persistent) {
15347            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15348        }
15349        if (app.activities.size() > 0) {
15350            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15351        }
15352        outInfo.lastTrimLevel = app.trimMemoryLevel;
15353        int adj = app.curAdj;
15354        int procState = app.curProcState;
15355        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15356        outInfo.importanceReasonCode = app.adjTypeCode;
15357        outInfo.processState = app.curProcState;
15358    }
15359
15360    @Override
15361    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15362        enforceNotIsolatedCaller("getRunningAppProcesses");
15363
15364        final int callingUid = Binder.getCallingUid();
15365        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15366
15367        // Lazy instantiation of list
15368        List<ActivityManager.RunningAppProcessInfo> runList = null;
15369        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15370                callingUid) == PackageManager.PERMISSION_GRANTED;
15371        final int userId = UserHandle.getUserId(callingUid);
15372        final boolean allUids = isGetTasksAllowed(
15373                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
15374
15375        synchronized (this) {
15376            // Iterate across all processes
15377            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15378                ProcessRecord app = mLruProcesses.get(i);
15379                if ((!allUsers && app.userId != userId)
15380                        || (!allUids && app.uid != callingUid)) {
15381                    continue;
15382                }
15383                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15384                    // Generate process state info for running application
15385                    ActivityManager.RunningAppProcessInfo currApp =
15386                        new ActivityManager.RunningAppProcessInfo(app.processName,
15387                                app.pid, app.getPackageList());
15388                    fillInProcMemInfo(app, currApp, clientTargetSdk);
15389                    if (app.adjSource instanceof ProcessRecord) {
15390                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15391                        currApp.importanceReasonImportance =
15392                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
15393                                        app.adjSourceProcState);
15394                    } else if (app.adjSource instanceof ActivityRecord) {
15395                        ActivityRecord r = (ActivityRecord)app.adjSource;
15396                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15397                    }
15398                    if (app.adjTarget instanceof ComponentName) {
15399                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15400                    }
15401                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15402                    //        + " lru=" + currApp.lru);
15403                    if (runList == null) {
15404                        runList = new ArrayList<>();
15405                    }
15406                    runList.add(currApp);
15407                }
15408            }
15409        }
15410        return runList;
15411    }
15412
15413    @Override
15414    public List<ApplicationInfo> getRunningExternalApplications() {
15415        enforceNotIsolatedCaller("getRunningExternalApplications");
15416        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
15417        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
15418        if (runningApps != null && runningApps.size() > 0) {
15419            Set<String> extList = new HashSet<String>();
15420            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
15421                if (app.pkgList != null) {
15422                    for (String pkg : app.pkgList) {
15423                        extList.add(pkg);
15424                    }
15425                }
15426            }
15427            IPackageManager pm = AppGlobals.getPackageManager();
15428            for (String pkg : extList) {
15429                try {
15430                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
15431                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
15432                        retList.add(info);
15433                    }
15434                } catch (RemoteException e) {
15435                }
15436            }
15437        }
15438        return retList;
15439    }
15440
15441    @Override
15442    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15443        enforceNotIsolatedCaller("getMyMemoryState");
15444
15445        final int callingUid = Binder.getCallingUid();
15446        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15447
15448        synchronized (this) {
15449            ProcessRecord proc;
15450            synchronized (mPidsSelfLocked) {
15451                proc = mPidsSelfLocked.get(Binder.getCallingPid());
15452            }
15453            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15454        }
15455    }
15456
15457    @Override
15458    public int getMemoryTrimLevel() {
15459        enforceNotIsolatedCaller("getMyMemoryState");
15460        synchronized (this) {
15461            return mLastMemoryLevel;
15462        }
15463    }
15464
15465    @Override
15466    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15467            FileDescriptor err, String[] args, ShellCallback callback,
15468            ResultReceiver resultReceiver) {
15469        (new ActivityManagerShellCommand(this, false)).exec(
15470                this, in, out, err, args, callback, resultReceiver);
15471    }
15472
15473    SleepToken acquireSleepToken(String tag, int displayId) {
15474        synchronized (this) {
15475            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15476            updateSleepIfNeededLocked();
15477            return token;
15478        }
15479    }
15480
15481    @Override
15482    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15483        PriorityDump.dump(mPriorityDumper, fd, pw, args);
15484    }
15485
15486    /**
15487     * Wrapper function to print out debug data filtered by specified arguments.
15488    */
15489    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
15490        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15491
15492        boolean dumpAll = false;
15493        boolean dumpClient = false;
15494        boolean dumpCheckin = false;
15495        boolean dumpCheckinFormat = false;
15496        boolean dumpNormalPriority = false;
15497        boolean dumpVisibleStacksOnly = false;
15498        boolean dumpFocusedStackOnly = false;
15499        String dumpPackage = null;
15500
15501        int opti = 0;
15502        while (opti < args.length) {
15503            String opt = args[opti];
15504            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15505                break;
15506            }
15507            opti++;
15508            if ("-a".equals(opt)) {
15509                dumpAll = true;
15510            } else if ("-c".equals(opt)) {
15511                dumpClient = true;
15512            } else if ("-v".equals(opt)) {
15513                dumpVisibleStacksOnly = true;
15514            } else if ("-f".equals(opt)) {
15515                dumpFocusedStackOnly = true;
15516            } else if ("-p".equals(opt)) {
15517                if (opti < args.length) {
15518                    dumpPackage = args[opti];
15519                    opti++;
15520                } else {
15521                    pw.println("Error: -p option requires package argument");
15522                    return;
15523                }
15524                dumpClient = true;
15525            } else if ("--checkin".equals(opt)) {
15526                dumpCheckin = dumpCheckinFormat = true;
15527            } else if ("-C".equals(opt)) {
15528                dumpCheckinFormat = true;
15529            } else if ("--normal-priority".equals(opt)) {
15530                dumpNormalPriority = true;
15531            } else if ("-h".equals(opt)) {
15532                ActivityManagerShellCommand.dumpHelp(pw, true);
15533                return;
15534            } else {
15535                pw.println("Unknown argument: " + opt + "; use -h for help");
15536            }
15537        }
15538
15539        long origId = Binder.clearCallingIdentity();
15540
15541        if (useProto) {
15542            final ProtoOutputStream proto = new ProtoOutputStream(fd);
15543            String cmd = opti < args.length ? args[opti] : "";
15544            opti++;
15545
15546            if ("activities".equals(cmd) || "a".equals(cmd)) {
15547                // output proto is ActivityStackSupervisorProto
15548                synchronized (this) {
15549                    writeActivitiesToProtoLocked(proto);
15550                }
15551            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15552                // output proto is BroadcastProto
15553                synchronized (this) {
15554                    writeBroadcastsToProtoLocked(proto);
15555                }
15556            } else if ("provider".equals(cmd)) {
15557                String[] newArgs;
15558                String name;
15559                if (opti >= args.length) {
15560                    name = null;
15561                    newArgs = EMPTY_STRING_ARRAY;
15562                } else {
15563                    name = args[opti];
15564                    opti++;
15565                    newArgs = new String[args.length - opti];
15566                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15567                            args.length - opti);
15568                }
15569                if (!dumpProviderProto(fd, pw, name, newArgs)) {
15570                    pw.println("No providers match: " + name);
15571                    pw.println("Use -h for help.");
15572                }
15573            } else if ("service".equals(cmd)) {
15574                mServices.writeToProto(proto);
15575            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15576                if (opti < args.length) {
15577                    dumpPackage = args[opti];
15578                    opti++;
15579                }
15580                // output proto is ProcessProto
15581                synchronized (this) {
15582                    writeProcessesToProtoLocked(proto, dumpPackage);
15583                }
15584            } else {
15585                // default option, dump everything, output is ActivityManagerServiceProto
15586                synchronized (this) {
15587                    long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
15588                    writeActivitiesToProtoLocked(proto);
15589                    proto.end(activityToken);
15590
15591                    long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
15592                    writeBroadcastsToProtoLocked(proto);
15593                    proto.end(broadcastToken);
15594
15595                    long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
15596                    mServices.writeToProto(proto);
15597                    proto.end(serviceToken);
15598
15599                    long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
15600                    writeProcessesToProtoLocked(proto, dumpPackage);
15601                    proto.end(processToken);
15602                }
15603            }
15604            proto.flush();
15605            Binder.restoreCallingIdentity(origId);
15606            return;
15607        }
15608
15609        int dumpAppId = getAppId(dumpPackage);
15610        boolean more = false;
15611        // Is the caller requesting to dump a particular piece of data?
15612        if (opti < args.length) {
15613            String cmd = args[opti];
15614            opti++;
15615            if ("activities".equals(cmd) || "a".equals(cmd)) {
15616                synchronized (this) {
15617                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15618                }
15619            } else if ("lastanr".equals(cmd)) {
15620                synchronized (this) {
15621                    dumpLastANRLocked(pw);
15622                }
15623            } else if ("starter".equals(cmd)) {
15624                synchronized (this) {
15625                    dumpActivityStarterLocked(pw, dumpPackage);
15626                }
15627            } else if ("containers".equals(cmd)) {
15628                synchronized (this) {
15629                    dumpActivityContainersLocked(pw);
15630                }
15631            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15632                synchronized (this) {
15633                    if (mRecentTasks != null) {
15634                        mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
15635                    }
15636                }
15637            } else if ("binder-proxies".equals(cmd)) {
15638                if (opti >= args.length) {
15639                    dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
15640                            "Counts of Binder Proxies held by SYSTEM");
15641                } else {
15642                    String uid = args[opti];
15643                    opti++;
15644                    // Ensure Binder Proxy Count is as up to date as possible
15645                    System.gc();
15646                    System.runFinalization();
15647                    System.gc();
15648                    pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
15649                }
15650            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15651                if (opti < args.length) {
15652                    dumpPackage = args[opti];
15653                    opti++;
15654                }
15655                synchronized (this) {
15656                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15657                }
15658            } else if ("broadcast-stats".equals(cmd)) {
15659                if (opti < args.length) {
15660                    dumpPackage = args[opti];
15661                    opti++;
15662                }
15663                synchronized (this) {
15664                    if (dumpCheckinFormat) {
15665                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15666                                dumpPackage);
15667                    } else {
15668                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15669                    }
15670                }
15671            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15672                if (opti < args.length) {
15673                    dumpPackage = args[opti];
15674                    opti++;
15675                }
15676                synchronized (this) {
15677                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15678                }
15679            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15680                if (opti < args.length) {
15681                    dumpPackage = args[opti];
15682                    opti++;
15683                }
15684                synchronized (this) {
15685                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
15686                }
15687            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15688                synchronized (this) {
15689                    dumpOomLocked(fd, pw, args, opti, true);
15690                }
15691            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15692                synchronized (this) {
15693                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15694                }
15695            } else if ("provider".equals(cmd)) {
15696                String[] newArgs;
15697                String name;
15698                if (opti >= args.length) {
15699                    name = null;
15700                    newArgs = EMPTY_STRING_ARRAY;
15701                } else {
15702                    name = args[opti];
15703                    opti++;
15704                    newArgs = new String[args.length - opti];
15705                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15706                }
15707                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15708                    pw.println("No providers match: " + name);
15709                    pw.println("Use -h for help.");
15710                }
15711            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15712                synchronized (this) {
15713                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15714                }
15715            } else if ("service".equals(cmd)) {
15716                String[] newArgs;
15717                String name;
15718                if (opti >= args.length) {
15719                    name = null;
15720                    newArgs = EMPTY_STRING_ARRAY;
15721                } else {
15722                    name = args[opti];
15723                    opti++;
15724                    newArgs = new String[args.length - opti];
15725                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15726                            args.length - opti);
15727                }
15728                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15729                    pw.println("No services match: " + name);
15730                    pw.println("Use -h for help.");
15731                }
15732            } else if ("package".equals(cmd)) {
15733                String[] newArgs;
15734                if (opti >= args.length) {
15735                    pw.println("package: no package name specified");
15736                    pw.println("Use -h for help.");
15737                } else {
15738                    dumpPackage = args[opti];
15739                    opti++;
15740                    newArgs = new String[args.length - opti];
15741                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15742                            args.length - opti);
15743                    args = newArgs;
15744                    opti = 0;
15745                    more = true;
15746                }
15747            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15748                synchronized (this) {
15749                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15750                }
15751            } else if ("settings".equals(cmd)) {
15752                synchronized (this) {
15753                    mConstants.dump(pw);
15754                }
15755            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15756                if (dumpClient) {
15757                    ActiveServices.ServiceDumper dumper;
15758                    synchronized (this) {
15759                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15760                                dumpPackage);
15761                    }
15762                    dumper.dumpWithClient();
15763                } else {
15764                    synchronized (this) {
15765                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15766                                dumpPackage).dumpLocked();
15767                    }
15768                }
15769            } else if ("locks".equals(cmd)) {
15770                LockGuard.dump(fd, pw, args);
15771            } else {
15772                // Dumping a single activity?
15773                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15774                        dumpFocusedStackOnly)) {
15775                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15776                    int res = shell.exec(this, null, fd, null, args, null,
15777                            new ResultReceiver(null));
15778                    if (res < 0) {
15779                        pw.println("Bad activity command, or no activities match: " + cmd);
15780                        pw.println("Use -h for help.");
15781                    }
15782                }
15783            }
15784            if (!more) {
15785                Binder.restoreCallingIdentity(origId);
15786                return;
15787            }
15788        }
15789
15790        // No piece of data specified, dump everything.
15791        if (dumpCheckinFormat) {
15792            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15793        } else if (dumpClient) {
15794            ActiveServices.ServiceDumper sdumper;
15795            synchronized (this) {
15796                mConstants.dump(pw);
15797                pw.println();
15798                if (dumpAll) {
15799                    pw.println("-------------------------------------------------------------------------------");
15800                }
15801                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15802                pw.println();
15803                if (dumpAll) {
15804                    pw.println("-------------------------------------------------------------------------------");
15805                }
15806                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15807                pw.println();
15808                if (dumpAll) {
15809                    pw.println("-------------------------------------------------------------------------------");
15810                }
15811                if (dumpAll || dumpPackage != null) {
15812                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15813                    pw.println();
15814                    if (dumpAll) {
15815                        pw.println("-------------------------------------------------------------------------------");
15816                    }
15817                }
15818                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15819                pw.println();
15820                if (dumpAll) {
15821                    pw.println("-------------------------------------------------------------------------------");
15822                }
15823                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15824                pw.println();
15825                if (dumpAll) {
15826                    pw.println("-------------------------------------------------------------------------------");
15827                }
15828                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15829                        dumpPackage);
15830            }
15831            sdumper.dumpWithClient();
15832            pw.println();
15833            synchronized (this) {
15834                if (dumpAll) {
15835                    pw.println("-------------------------------------------------------------------------------");
15836                }
15837                if (mRecentTasks != null) {
15838                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
15839                }
15840                pw.println();
15841                if (dumpAll) {
15842                    pw.println("-------------------------------------------------------------------------------");
15843                }
15844                dumpLastANRLocked(pw);
15845                pw.println();
15846                if (dumpAll) {
15847                    pw.println("-------------------------------------------------------------------------------");
15848                }
15849                dumpActivityStarterLocked(pw, dumpPackage);
15850                pw.println();
15851                if (dumpAll) {
15852                    pw.println("-------------------------------------------------------------------------------");
15853                }
15854                dumpActivityContainersLocked(pw);
15855                pw.println();
15856                if (dumpAll) {
15857                    pw.println("-------------------------------------------------------------------------------");
15858                }
15859                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15860                if (mAssociations.size() > 0) {
15861                    pw.println();
15862                    if (dumpAll) {
15863                        pw.println("-------------------------------------------------------------------------------");
15864                    }
15865                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15866                }
15867                pw.println();
15868                if (dumpAll) {
15869                    pw.println("-------------------------------------------------------------------------------");
15870                }
15871                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
15872            }
15873
15874        } else {
15875            synchronized (this) {
15876                mConstants.dump(pw);
15877                pw.println();
15878                if (dumpAll) {
15879                    pw.println("-------------------------------------------------------------------------------");
15880                }
15881                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15882                pw.println();
15883                if (dumpAll) {
15884                    pw.println("-------------------------------------------------------------------------------");
15885                }
15886                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15887                pw.println();
15888                if (dumpAll) {
15889                    pw.println("-------------------------------------------------------------------------------");
15890                }
15891                if (dumpAll || dumpPackage != null) {
15892                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15893                    pw.println();
15894                    if (dumpAll) {
15895                        pw.println("-------------------------------------------------------------------------------");
15896                    }
15897                }
15898                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15899                pw.println();
15900                if (dumpAll) {
15901                    pw.println("-------------------------------------------------------------------------------");
15902                }
15903                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15904                pw.println();
15905                if (dumpAll) {
15906                    pw.println("-------------------------------------------------------------------------------");
15907                }
15908                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15909                        .dumpLocked();
15910                pw.println();
15911                if (dumpAll) {
15912                    pw.println("-------------------------------------------------------------------------------");
15913                }
15914                if (mRecentTasks != null) {
15915                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
15916                }
15917                pw.println();
15918                if (dumpAll) {
15919                    pw.println("-------------------------------------------------------------------------------");
15920                }
15921                dumpLastANRLocked(pw);
15922                pw.println();
15923                if (dumpAll) {
15924                    pw.println("-------------------------------------------------------------------------------");
15925                }
15926                dumpActivityStarterLocked(pw, dumpPackage);
15927                pw.println();
15928                if (dumpAll) {
15929                    pw.println("-------------------------------------------------------------------------------");
15930                }
15931                dumpActivityContainersLocked(pw);
15932                // Activities section is dumped as part of the Critical priority dump. Exclude the
15933                // section if priority is Normal.
15934                if (!dumpNormalPriority){
15935                    pw.println();
15936                    if (dumpAll) {
15937                        pw.println("-------------------------------------------------------------------------------");
15938                    }
15939                    dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15940                }
15941                if (mAssociations.size() > 0) {
15942                    pw.println();
15943                    if (dumpAll) {
15944                        pw.println("-------------------------------------------------------------------------------");
15945                    }
15946                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15947                }
15948                pw.println();
15949                if (dumpAll) {
15950                    pw.println("-------------------------------------------------------------------------------");
15951                }
15952                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
15953            }
15954        }
15955        Binder.restoreCallingIdentity(origId);
15956    }
15957
15958    private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
15959        // The output proto of "activity --proto activities" is ActivityStackSupervisorProto
15960        mStackSupervisor.writeToProto(proto);
15961    }
15962
15963    private void dumpLastANRLocked(PrintWriter pw) {
15964        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15965        if (mLastANRState == null) {
15966            pw.println("  <no ANR has occurred since boot>");
15967        } else {
15968            pw.println(mLastANRState);
15969        }
15970    }
15971
15972    private void dumpActivityContainersLocked(PrintWriter pw) {
15973        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
15974        mStackSupervisor.dumpChildrenNames(pw, " ");
15975        pw.println(" ");
15976    }
15977
15978    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15979        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15980        mActivityStartController.dump(pw, "", dumpPackage);
15981    }
15982
15983    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15984            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15985        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15986                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15987    }
15988
15989    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15990            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15991        pw.println(header);
15992
15993        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15994                dumpPackage);
15995        boolean needSep = printedAnything;
15996
15997        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15998                mStackSupervisor.getResumedActivityLocked(),
15999                dumpPackage, needSep, "  ResumedActivity: ");
16000        if (printed) {
16001            printedAnything = true;
16002            needSep = false;
16003        }
16004
16005        if (dumpPackage == null) {
16006            if (needSep) {
16007                pw.println();
16008            }
16009            printedAnything = true;
16010            mStackSupervisor.dump(pw, "  ");
16011        }
16012
16013        if (!printedAnything) {
16014            pw.println("  (nothing)");
16015        }
16016    }
16017
16018    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16019            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16020        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
16021
16022        int dumpUid = 0;
16023        if (dumpPackage != null) {
16024            IPackageManager pm = AppGlobals.getPackageManager();
16025            try {
16026                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
16027            } catch (RemoteException e) {
16028            }
16029        }
16030
16031        boolean printedAnything = false;
16032
16033        final long now = SystemClock.uptimeMillis();
16034
16035        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
16036            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
16037                    = mAssociations.valueAt(i1);
16038            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
16039                SparseArray<ArrayMap<String, Association>> sourceUids
16040                        = targetComponents.valueAt(i2);
16041                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
16042                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
16043                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
16044                        Association ass = sourceProcesses.valueAt(i4);
16045                        if (dumpPackage != null) {
16046                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
16047                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
16048                                continue;
16049                            }
16050                        }
16051                        printedAnything = true;
16052                        pw.print("  ");
16053                        pw.print(ass.mTargetProcess);
16054                        pw.print("/");
16055                        UserHandle.formatUid(pw, ass.mTargetUid);
16056                        pw.print(" <- ");
16057                        pw.print(ass.mSourceProcess);
16058                        pw.print("/");
16059                        UserHandle.formatUid(pw, ass.mSourceUid);
16060                        pw.println();
16061                        pw.print("    via ");
16062                        pw.print(ass.mTargetComponent.flattenToShortString());
16063                        pw.println();
16064                        pw.print("    ");
16065                        long dur = ass.mTime;
16066                        if (ass.mNesting > 0) {
16067                            dur += now - ass.mStartTime;
16068                        }
16069                        TimeUtils.formatDuration(dur, pw);
16070                        pw.print(" (");
16071                        pw.print(ass.mCount);
16072                        pw.print(" times)");
16073                        pw.print("  ");
16074                        for (int i=0; i<ass.mStateTimes.length; i++) {
16075                            long amt = ass.mStateTimes[i];
16076                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16077                                amt += now - ass.mLastStateUptime;
16078                            }
16079                            if (amt != 0) {
16080                                pw.print(" ");
16081                                pw.print(ProcessList.makeProcStateString(
16082                                            i + ActivityManager.MIN_PROCESS_STATE));
16083                                pw.print("=");
16084                                TimeUtils.formatDuration(amt, pw);
16085                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16086                                    pw.print("*");
16087                                }
16088                            }
16089                        }
16090                        pw.println();
16091                        if (ass.mNesting > 0) {
16092                            pw.print("    Currently active: ");
16093                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
16094                            pw.println();
16095                        }
16096                    }
16097                }
16098            }
16099
16100        }
16101
16102        if (!printedAnything) {
16103            pw.println("  (nothing)");
16104        }
16105    }
16106
16107    private int getAppId(String dumpPackage) {
16108        if (dumpPackage != null) {
16109            try {
16110                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
16111                        dumpPackage, 0);
16112                return UserHandle.getAppId(info.uid);
16113            } catch (NameNotFoundException e) {
16114                e.printStackTrace();
16115            }
16116        }
16117        return -1;
16118    }
16119
16120    boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
16121                String header, boolean needSep) {
16122        boolean printed = false;
16123        for (int i=0; i<uids.size(); i++) {
16124            UidRecord uidRec = uids.valueAt(i);
16125            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
16126                continue;
16127            }
16128            if (!printed) {
16129                printed = true;
16130                if (needSep) {
16131                    pw.println();
16132                }
16133                pw.print("  ");
16134                pw.println(header);
16135                needSep = true;
16136            }
16137            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
16138            pw.print(": "); pw.println(uidRec);
16139        }
16140        return printed;
16141    }
16142
16143    boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
16144        if(counts != null) {
16145            pw.println(header);
16146            for (int i = 0; i < counts.size(); i++) {
16147                final int uid = counts.keyAt(i);
16148                final int binderCount = counts.valueAt(i);
16149                pw.print("    UID ");
16150                pw.print(uid);
16151                pw.print(", binder count = ");
16152                pw.print(binderCount);
16153                pw.print(", package(s)= ");
16154                final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
16155                if (pkgNames != null) {
16156                    for (int j = 0; j < pkgNames.length; j++) {
16157                        pw.print(pkgNames[j]);
16158                        pw.print("; ");
16159                    }
16160                } else {
16161                    pw.print("NO PACKAGE NAME FOUND");
16162                }
16163                pw.println();
16164            }
16165            pw.println();
16166            return true;
16167        }
16168        return false;
16169    }
16170
16171    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16172            int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
16173        boolean needSep = false;
16174        int numPers = 0;
16175
16176        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
16177
16178        if (dumpAll) {
16179            final int NP = mProcessNames.getMap().size();
16180            for (int ip=0; ip<NP; ip++) {
16181                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16182                final int NA = procs.size();
16183                for (int ia=0; ia<NA; ia++) {
16184                    ProcessRecord r = procs.valueAt(ia);
16185                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16186                        continue;
16187                    }
16188                    if (!needSep) {
16189                        pw.println("  All known processes:");
16190                        needSep = true;
16191                    }
16192                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
16193                        pw.print(" UID "); pw.print(procs.keyAt(ia));
16194                        pw.print(" "); pw.println(r);
16195                    r.dump(pw, "    ");
16196                    if (r.persistent) {
16197                        numPers++;
16198                    }
16199                }
16200            }
16201        }
16202
16203        if (mIsolatedProcesses.size() > 0) {
16204            boolean printed = false;
16205            for (int i=0; i<mIsolatedProcesses.size(); i++) {
16206                ProcessRecord r = mIsolatedProcesses.valueAt(i);
16207                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16208                    continue;
16209                }
16210                if (!printed) {
16211                    if (needSep) {
16212                        pw.println();
16213                    }
16214                    pw.println("  Isolated process list (sorted by uid):");
16215                    printed = true;
16216                    needSep = true;
16217                }
16218                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
16219                pw.println(r);
16220            }
16221        }
16222
16223        if (mActiveInstrumentation.size() > 0) {
16224            boolean printed = false;
16225            for (int i=0; i<mActiveInstrumentation.size(); i++) {
16226                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16227                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16228                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16229                    continue;
16230                }
16231                if (!printed) {
16232                    if (needSep) {
16233                        pw.println();
16234                    }
16235                    pw.println("  Active instrumentation:");
16236                    printed = true;
16237                    needSep = true;
16238                }
16239                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
16240                pw.println(ai);
16241                ai.dump(pw, "      ");
16242            }
16243        }
16244
16245        if (mActiveUids.size() > 0) {
16246            if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16247                needSep = true;
16248            }
16249        }
16250        if (dumpAll) {
16251            if (mValidateUids.size() > 0) {
16252                if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16253                        needSep)) {
16254                    needSep = true;
16255                }
16256            }
16257        }
16258
16259        if (mLruProcesses.size() > 0) {
16260            if (needSep) {
16261                pw.println();
16262            }
16263            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16264                    pw.print(" total, non-act at ");
16265                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16266                    pw.print(", non-svc at ");
16267                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16268                    pw.println("):");
16269            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
16270            needSep = true;
16271        }
16272
16273        if (dumpAll || dumpPackage != null) {
16274            synchronized (mPidsSelfLocked) {
16275                boolean printed = false;
16276                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16277                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16278                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16279                        continue;
16280                    }
16281                    if (!printed) {
16282                        if (needSep) pw.println();
16283                        needSep = true;
16284                        pw.println("  PID mappings:");
16285                        printed = true;
16286                    }
16287                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16288                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16289                }
16290            }
16291        }
16292
16293        if (mImportantProcesses.size() > 0) {
16294            synchronized (mPidsSelfLocked) {
16295                boolean printed = false;
16296                for (int i = 0; i< mImportantProcesses.size(); i++) {
16297                    ProcessRecord r = mPidsSelfLocked.get(
16298                            mImportantProcesses.valueAt(i).pid);
16299                    if (dumpPackage != null && (r == null
16300                            || !r.pkgList.containsKey(dumpPackage))) {
16301                        continue;
16302                    }
16303                    if (!printed) {
16304                        if (needSep) pw.println();
16305                        needSep = true;
16306                        pw.println("  Foreground Processes:");
16307                        printed = true;
16308                    }
16309                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
16310                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16311                }
16312            }
16313        }
16314
16315        if (mPersistentStartingProcesses.size() > 0) {
16316            if (needSep) pw.println();
16317            needSep = true;
16318            pw.println("  Persisent processes that are starting:");
16319            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
16320                    "Starting Norm", "Restarting PERS", dumpPackage);
16321        }
16322
16323        if (mRemovedProcesses.size() > 0) {
16324            if (needSep) pw.println();
16325            needSep = true;
16326            pw.println("  Processes that are being removed:");
16327            dumpProcessList(pw, this, mRemovedProcesses, "    ",
16328                    "Removed Norm", "Removed PERS", dumpPackage);
16329        }
16330
16331        if (mProcessesOnHold.size() > 0) {
16332            if (needSep) pw.println();
16333            needSep = true;
16334            pw.println("  Processes that are on old until the system is ready:");
16335            dumpProcessList(pw, this, mProcessesOnHold, "    ",
16336                    "OnHold Norm", "OnHold PERS", dumpPackage);
16337        }
16338
16339        needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16340
16341        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16342
16343        if (dumpPackage == null) {
16344            pw.println();
16345            needSep = false;
16346            mUserController.dump(pw, dumpAll);
16347        }
16348        if (mHomeProcess != null && (dumpPackage == null
16349                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16350            if (needSep) {
16351                pw.println();
16352                needSep = false;
16353            }
16354            pw.println("  mHomeProcess: " + mHomeProcess);
16355        }
16356        if (mPreviousProcess != null && (dumpPackage == null
16357                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16358            if (needSep) {
16359                pw.println();
16360                needSep = false;
16361            }
16362            pw.println("  mPreviousProcess: " + mPreviousProcess);
16363        }
16364        if (dumpAll && (mPreviousProcess == null || dumpPackage == null
16365                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16366            StringBuilder sb = new StringBuilder(128);
16367            sb.append("  mPreviousProcessVisibleTime: ");
16368            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
16369            pw.println(sb);
16370        }
16371        if (mHeavyWeightProcess != null && (dumpPackage == null
16372                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16373            if (needSep) {
16374                pw.println();
16375                needSep = false;
16376            }
16377            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16378        }
16379        if (dumpAll && mPendingStarts.size() > 0) {
16380            if (needSep) pw.println();
16381            needSep = true;
16382            pw.println("  mPendingStarts: ");
16383            for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
16384                pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
16385            }
16386        }
16387        if (dumpPackage == null) {
16388            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
16389            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
16390        }
16391        if (dumpAll) {
16392            if (dumpPackage == null) {
16393                pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
16394            }
16395            if (mCompatModePackages.getPackages().size() > 0) {
16396                boolean printed = false;
16397                for (Map.Entry<String, Integer> entry
16398                        : mCompatModePackages.getPackages().entrySet()) {
16399                    String pkg = entry.getKey();
16400                    int mode = entry.getValue();
16401                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
16402                        continue;
16403                    }
16404                    if (!printed) {
16405                        pw.println("  mScreenCompatPackages:");
16406                        printed = true;
16407                    }
16408                    pw.print("    "); pw.print(pkg); pw.print(": ");
16409                            pw.print(mode); pw.println();
16410                }
16411            }
16412            final int NI = mUidObservers.getRegisteredCallbackCount();
16413            boolean printed = false;
16414            for (int i=0; i<NI; i++) {
16415                final UidObserverRegistration reg = (UidObserverRegistration)
16416                        mUidObservers.getRegisteredCallbackCookie(i);
16417                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16418                    if (!printed) {
16419                        pw.println("  mUidObservers:");
16420                        printed = true;
16421                    }
16422                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
16423                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
16424                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
16425                        pw.print(" IDLE");
16426                    }
16427                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
16428                        pw.print(" ACT" );
16429                    }
16430                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
16431                        pw.print(" GONE");
16432                    }
16433                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
16434                        pw.print(" STATE");
16435                        pw.print(" (cut="); pw.print(reg.cutpoint);
16436                        pw.print(")");
16437                    }
16438                    pw.println();
16439                    if (reg.lastProcStates != null) {
16440                        final int NJ = reg.lastProcStates.size();
16441                        for (int j=0; j<NJ; j++) {
16442                            pw.print("      Last ");
16443                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
16444                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
16445                        }
16446                    }
16447                }
16448            }
16449            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
16450            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
16451            if (mPendingTempWhitelist.size() > 0) {
16452                pw.println("  mPendingTempWhitelist:");
16453                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
16454                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
16455                    pw.print("    ");
16456                    UserHandle.formatUid(pw, ptw.targetUid);
16457                    pw.print(": ");
16458                    TimeUtils.formatDuration(ptw.duration, pw);
16459                    pw.print(" ");
16460                    pw.println(ptw.tag);
16461                }
16462            }
16463        }
16464        if (dumpPackage == null) {
16465            pw.println("  mWakefulness="
16466                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
16467            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
16468            pw.println("  mSleeping=" + mSleeping);
16469            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
16470            if (mRunningVoice != null) {
16471                pw.println("  mRunningVoice=" + mRunningVoice);
16472                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
16473            }
16474            pw.println("  mVrController=" + mVrController);
16475        }
16476        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16477                || mOrigWaitForDebugger) {
16478            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16479                    || dumpPackage.equals(mOrigDebugApp)) {
16480                if (needSep) {
16481                    pw.println();
16482                    needSep = false;
16483                }
16484                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
16485                        + " mDebugTransient=" + mDebugTransient
16486                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
16487            }
16488        }
16489        if (mCurAppTimeTracker != null) {
16490            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
16491        }
16492        if (mMemWatchProcesses.getMap().size() > 0) {
16493            pw.println("  Mem watch processes:");
16494            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
16495                    = mMemWatchProcesses.getMap();
16496            for (int i=0; i<procs.size(); i++) {
16497                final String proc = procs.keyAt(i);
16498                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16499                for (int j=0; j<uids.size(); j++) {
16500                    if (needSep) {
16501                        pw.println();
16502                        needSep = false;
16503                    }
16504                    StringBuilder sb = new StringBuilder();
16505                    sb.append("    ").append(proc).append('/');
16506                    UserHandle.formatUid(sb, uids.keyAt(j));
16507                    Pair<Long, String> val = uids.valueAt(j);
16508                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
16509                    if (val.second != null) {
16510                        sb.append(", report to ").append(val.second);
16511                    }
16512                    pw.println(sb.toString());
16513                }
16514            }
16515            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
16516            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
16517            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
16518                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
16519        }
16520        if (mTrackAllocationApp != null) {
16521            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16522                if (needSep) {
16523                    pw.println();
16524                    needSep = false;
16525                }
16526                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
16527            }
16528        }
16529        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16530                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16531            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16532                if (needSep) {
16533                    pw.println();
16534                    needSep = false;
16535                }
16536                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16537                if (mProfilerInfo != null) {
16538                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16539                            mProfilerInfo.profileFd);
16540                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16541                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16542                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16543                    pw.println("  mProfileType=" + mProfileType);
16544                }
16545            }
16546        }
16547        if (mNativeDebuggingApp != null) {
16548            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16549                if (needSep) {
16550                    pw.println();
16551                    needSep = false;
16552                }
16553                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16554            }
16555        }
16556        if (mAllowAppSwitchUids.size() > 0) {
16557            boolean printed = false;
16558            for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
16559                ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
16560                for (int j = 0; j < types.size(); j++) {
16561                    if (dumpPackage == null ||
16562                            UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
16563                        if (needSep) {
16564                            pw.println();
16565                            needSep = false;
16566                        }
16567                        if (!printed) {
16568                            pw.println("  mAllowAppSwitchUids:");
16569                            printed = true;
16570                        }
16571                        pw.print("    User ");
16572                        pw.print(mAllowAppSwitchUids.keyAt(i));
16573                        pw.print(": Type ");
16574                        pw.print(types.keyAt(j));
16575                        pw.print(" = ");
16576                        UserHandle.formatUid(pw, types.valueAt(j).intValue());
16577                        pw.println();
16578                    }
16579                }
16580            }
16581        }
16582        if (dumpPackage == null) {
16583            if (mAlwaysFinishActivities) {
16584                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16585            }
16586            if (mController != null) {
16587                pw.println("  mController=" + mController
16588                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16589            }
16590            if (dumpAll) {
16591                pw.println("  Total persistent processes: " + numPers);
16592                pw.println("  mProcessesReady=" + mProcessesReady
16593                        + " mSystemReady=" + mSystemReady
16594                        + " mBooted=" + mBooted
16595                        + " mFactoryTest=" + mFactoryTest);
16596                pw.println("  mBooting=" + mBooting
16597                        + " mCallFinishBooting=" + mCallFinishBooting
16598                        + " mBootAnimationComplete=" + mBootAnimationComplete);
16599                pw.print("  mLastPowerCheckUptime=");
16600                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16601                        pw.println("");
16602                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16603                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16604                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16605                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16606                        + " (" + mLruProcesses.size() + " total)"
16607                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16608                        + " mNumServiceProcs=" + mNumServiceProcs
16609                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16610                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16611                        + " mLastMemoryLevel=" + mLastMemoryLevel
16612                        + " mLastNumProcesses=" + mLastNumProcesses);
16613                long now = SystemClock.uptimeMillis();
16614                pw.print("  mLastIdleTime=");
16615                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
16616                        pw.print(" mLowRamSinceLastIdle=");
16617                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16618                        pw.println();
16619            }
16620        }
16621        pw.println("  mForceBackgroundCheck=" + mForceBackgroundCheck);
16622    }
16623
16624    void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
16625        int numPers = 0;
16626
16627        final int NP = mProcessNames.getMap().size();
16628        for (int ip=0; ip<NP; ip++) {
16629            SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16630            final int NA = procs.size();
16631            for (int ia = 0; ia<NA; ia++) {
16632                ProcessRecord r = procs.valueAt(ia);
16633                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16634                    continue;
16635                }
16636                r.writeToProto(proto, ProcessesProto.PROCS);
16637                if (r.persistent) {
16638                    numPers++;
16639                }
16640            }
16641        }
16642
16643        for (int i=0; i<mIsolatedProcesses.size(); i++) {
16644            ProcessRecord r = mIsolatedProcesses.valueAt(i);
16645            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16646                continue;
16647            }
16648            r.writeToProto(proto, ProcessesProto.ISOLATED_PROCS);
16649        }
16650
16651        for (int i=0; i<mActiveInstrumentation.size(); i++) {
16652            ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16653            if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16654                    && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16655                continue;
16656            }
16657            ai.writeToProto(proto, ProcessesProto.ACTIVE_INSTRUMENTATIONS);
16658        }
16659
16660        int whichAppId = getAppId(dumpPackage);
16661        for (int i=0; i<mActiveUids.size(); i++) {
16662            UidRecord uidRec = mActiveUids.valueAt(i);
16663            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16664                continue;
16665            }
16666            uidRec.writeToProto(proto, ProcessesProto.ACTIVE_UIDS);
16667        }
16668
16669        for (int i=0; i<mValidateUids.size(); i++) {
16670            UidRecord uidRec = mValidateUids.valueAt(i);
16671            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16672                continue;
16673            }
16674            uidRec.writeToProto(proto, ProcessesProto.VALIDATE_UIDS);
16675        }
16676
16677        if (mLruProcesses.size() > 0) {
16678            long lruToken = proto.start(ProcessesProto.LRU_PROCS);
16679            int total = mLruProcesses.size();
16680            proto.write(ProcessesProto.LruProcesses.SIZE, total);
16681            proto.write(ProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
16682            proto.write(ProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
16683            writeProcessOomListToProto(proto, ProcessesProto.LruProcesses.LIST, this,
16684                    mLruProcesses,false, dumpPackage);
16685            proto.end(lruToken);
16686        }
16687
16688        if (dumpPackage != null) {
16689            synchronized (mPidsSelfLocked) {
16690                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16691                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16692                    if (!r.pkgList.containsKey(dumpPackage)) {
16693                        continue;
16694                    }
16695                    r.writeToProto(proto, ProcessesProto.PIDS_SELF_LOCKED);
16696                }
16697            }
16698        }
16699
16700        if (mImportantProcesses.size() > 0) {
16701            synchronized (mPidsSelfLocked) {
16702                for (int i=0; i<mImportantProcesses.size(); i++) {
16703                    ImportanceToken it = mImportantProcesses.valueAt(i);
16704                    ProcessRecord r = mPidsSelfLocked.get(it.pid);
16705                    if (dumpPackage != null && (r == null
16706                            || !r.pkgList.containsKey(dumpPackage))) {
16707                        continue;
16708                    }
16709                    it.writeToProto(proto, ProcessesProto.IMPORTANT_PROCS);
16710                }
16711            }
16712        }
16713
16714        for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
16715            ProcessRecord r = mPersistentStartingProcesses.get(i);
16716            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16717                continue;
16718            }
16719            r.writeToProto(proto, ProcessesProto.PERSISTENT_STARTING_PROCS);
16720        }
16721
16722        for (int i=0; i<mRemovedProcesses.size(); i++) {
16723            ProcessRecord r = mRemovedProcesses.get(i);
16724            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16725                continue;
16726            }
16727            r.writeToProto(proto, ProcessesProto.REMOVED_PROCS);
16728        }
16729
16730        for (int i=0; i<mProcessesOnHold.size(); i++) {
16731            ProcessRecord r = mProcessesOnHold.get(i);
16732            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16733                continue;
16734            }
16735            r.writeToProto(proto, ProcessesProto.ON_HOLD_PROCS);
16736        }
16737
16738        writeProcessesToGcToProto(proto, ProcessesProto.GC_PROCS, dumpPackage);
16739        mAppErrors.writeToProto(proto, ProcessesProto.APP_ERRORS, dumpPackage);
16740
16741        if (dumpPackage == null) {
16742            mUserController.writeToProto(proto, ProcessesProto.USER_CONTROLLER);
16743            getGlobalConfiguration().writeToProto(proto, ProcessesProto.GLOBAL_CONFIGURATION);
16744            proto.write(ProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
16745        }
16746
16747        if (mHomeProcess != null && (dumpPackage == null
16748                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16749            mHomeProcess.writeToProto(proto, ProcessesProto.HOME_PROC);
16750        }
16751
16752        if (mPreviousProcess != null && (dumpPackage == null
16753                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16754            mPreviousProcess.writeToProto(proto, ProcessesProto.PREVIOUS_PROC);
16755            proto.write(ProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
16756        }
16757
16758        if (mHeavyWeightProcess != null && (dumpPackage == null
16759                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16760            mHeavyWeightProcess.writeToProto(proto, ProcessesProto.HEAVY_WEIGHT_PROC);
16761        }
16762
16763        for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
16764            String pkg = entry.getKey();
16765            int mode = entry.getValue();
16766            if (dumpPackage == null || dumpPackage.equals(pkg)) {
16767                long compatToken = proto.start(ProcessesProto.SCREEN_COMPAT_PACKAGES);
16768                proto.write(ProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
16769                proto.write(ProcessesProto.ScreenCompatPackage.MODE, mode);
16770                proto.end(compatToken);
16771            }
16772        }
16773
16774        final int NI = mUidObservers.getRegisteredCallbackCount();
16775        for (int i=0; i<NI; i++) {
16776            final UidObserverRegistration reg = (UidObserverRegistration)
16777                    mUidObservers.getRegisteredCallbackCookie(i);
16778            if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16779                reg.writeToProto(proto, ProcessesProto.UID_OBSERVERS);
16780            }
16781        }
16782
16783        for (int v : mDeviceIdleWhitelist) {
16784            proto.write(ProcessesProto.DEVICE_IDLE_WHITELIST, v);
16785        }
16786
16787        for (int v : mDeviceIdleTempWhitelist) {
16788            proto.write(ProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
16789        }
16790
16791        if (mPendingTempWhitelist.size() > 0) {
16792            for (int i=0; i < mPendingTempWhitelist.size(); i++) {
16793                mPendingTempWhitelist.valueAt(i).writeToProto(proto,
16794                        ProcessesProto.PENDING_TEMP_WHITELIST);
16795            }
16796        }
16797
16798        if (dumpPackage == null) {
16799            final long sleepToken = proto.start(ProcessesProto.SLEEP_STATUS);
16800            proto.write(ProcessesProto.SleepStatus.WAKEFULNESS,
16801                    PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
16802            for (SleepToken st : mStackSupervisor.mSleepTokens) {
16803                proto.write(ProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
16804            }
16805            proto.write(ProcessesProto.SleepStatus.SLEEPING, mSleeping);
16806            proto.write(ProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
16807            proto.write(ProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
16808            proto.end(sleepToken);
16809
16810            if (mRunningVoice != null) {
16811                final long vrToken = proto.start(ProcessesProto.RUNNING_VOICE);
16812                proto.write(ProcessesProto.VoiceProto.SESSION, mRunningVoice.toString());
16813                mVoiceWakeLock.writeToProto(proto, ProcessesProto.VoiceProto.WAKELOCK);
16814                proto.end(vrToken);
16815            }
16816
16817            mVrController.writeToProto(proto, ProcessesProto.VR_CONTROLLER);
16818        }
16819
16820        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16821                || mOrigWaitForDebugger) {
16822            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16823                    || dumpPackage.equals(mOrigDebugApp)) {
16824                final long debugAppToken = proto.start(ProcessesProto.DEBUG);
16825                proto.write(ProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
16826                proto.write(ProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
16827                proto.write(ProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
16828                proto.write(ProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
16829                proto.end(debugAppToken);
16830            }
16831        }
16832
16833        if (mCurAppTimeTracker != null) {
16834            mCurAppTimeTracker.writeToProto(proto, ProcessesProto.CURRENT_TRACKER, true);
16835        }
16836
16837        if (mMemWatchProcesses.getMap().size() > 0) {
16838            final long token = proto.start(ProcessesProto.MEM_WATCH_PROCESSES);
16839            ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
16840            for (int i=0; i<procs.size(); i++) {
16841                final String proc = procs.keyAt(i);
16842                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16843                final long ptoken = proto.start(ProcessesProto.MemWatchProcess.PROCS);
16844                proto.write(ProcessesProto.MemWatchProcess.Process.NAME, proc);
16845                for (int j=0; j<uids.size(); j++) {
16846                    final long utoken = proto.start(ProcessesProto.MemWatchProcess.Process.MEM_STATS);
16847                    Pair<Long, String> val = uids.valueAt(j);
16848                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
16849                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
16850                            DebugUtils.sizeValueToString(val.first, new StringBuilder()));
16851                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
16852                    proto.end(utoken);
16853                }
16854                proto.end(ptoken);
16855            }
16856
16857            final long dtoken = proto.start(ProcessesProto.MemWatchProcess.DUMP);
16858            proto.write(ProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
16859            proto.write(ProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
16860            proto.write(ProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
16861            proto.write(ProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
16862            proto.end(dtoken);
16863
16864            proto.end(token);
16865        }
16866
16867        if (mTrackAllocationApp != null) {
16868            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16869                proto.write(ProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
16870            }
16871        }
16872
16873        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16874                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16875            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16876                final long token = proto.start(ProcessesProto.PROFILE);
16877                proto.write(ProcessesProto.Profile.APP_NAME, mProfileApp);
16878                mProfileProc.writeToProto(proto,ProcessesProto.Profile.PROC);
16879                if (mProfilerInfo != null) {
16880                    mProfilerInfo.writeToProto(proto, ProcessesProto.Profile.INFO);
16881                    proto.write(ProcessesProto.Profile.TYPE, mProfileType);
16882                }
16883                proto.end(token);
16884            }
16885        }
16886
16887        if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16888            proto.write(ProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
16889        }
16890
16891        if (dumpPackage == null) {
16892            proto.write(ProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
16893            if (mController != null) {
16894                final long token = proto.start(ProcessesProto.CONTROLLER);
16895                proto.write(ProcessesProto.Controller.CONTROLLER, mController.toString());
16896                proto.write(ProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
16897                proto.end(token);
16898            }
16899            proto.write(ProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
16900            proto.write(ProcessesProto.PROCESSES_READY, mProcessesReady);
16901            proto.write(ProcessesProto.SYSTEM_READY, mSystemReady);
16902            proto.write(ProcessesProto.BOOTED, mBooted);
16903            proto.write(ProcessesProto.FACTORY_TEST, mFactoryTest);
16904            proto.write(ProcessesProto.BOOTING, mBooting);
16905            proto.write(ProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
16906            proto.write(ProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
16907            proto.write(ProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
16908            mStackSupervisor.mGoingToSleep.writeToProto(proto, ProcessesProto.GOING_TO_SLEEP);
16909            mStackSupervisor.mLaunchingActivity.writeToProto(proto, ProcessesProto.LAUNCHING_ACTIVITY);
16910            proto.write(ProcessesProto.ADJ_SEQ, mAdjSeq);
16911            proto.write(ProcessesProto.LRU_SEQ, mLruSeq);
16912            proto.write(ProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
16913            proto.write(ProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
16914            proto.write(ProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
16915            proto.write(ProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
16916            proto.write(ProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
16917            proto.write(ProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
16918            long now = SystemClock.uptimeMillis();
16919            ProtoUtils.toDuration(proto, ProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
16920            proto.write(ProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
16921        }
16922
16923    }
16924
16925    void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
16926        if (mProcessesToGc.size() > 0) {
16927            long now = SystemClock.uptimeMillis();
16928            for (int i=0; i<mProcessesToGc.size(); i++) {
16929                ProcessRecord r = mProcessesToGc.get(i);
16930                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16931                    continue;
16932                }
16933                final long token = proto.start(fieldId);
16934                r.writeToProto(proto, ProcessToGcProto.PROC);
16935                proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
16936                proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
16937                proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
16938                proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
16939                proto.end(token);
16940            }
16941        }
16942    }
16943
16944    boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
16945        if (mProcessesToGc.size() > 0) {
16946            boolean printed = false;
16947            long now = SystemClock.uptimeMillis();
16948            for (int i=0; i<mProcessesToGc.size(); i++) {
16949                ProcessRecord proc = mProcessesToGc.get(i);
16950                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16951                    continue;
16952                }
16953                if (!printed) {
16954                    if (needSep) pw.println();
16955                    needSep = true;
16956                    pw.println("  Processes that are waiting to GC:");
16957                    printed = true;
16958                }
16959                pw.print("    Process "); pw.println(proc);
16960                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16961                        pw.print(", last gced=");
16962                        pw.print(now-proc.lastRequestedGc);
16963                        pw.print(" ms ago, last lowMem=");
16964                        pw.print(now-proc.lastLowMemory);
16965                        pw.println(" ms ago");
16966
16967            }
16968        }
16969        return needSep;
16970    }
16971
16972    void printOomLevel(PrintWriter pw, String name, int adj) {
16973        pw.print("    ");
16974        if (adj >= 0) {
16975            pw.print(' ');
16976            if (adj < 10) pw.print(' ');
16977        } else {
16978            if (adj > -10) pw.print(' ');
16979        }
16980        pw.print(adj);
16981        pw.print(": ");
16982        pw.print(name);
16983        pw.print(" (");
16984        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16985        pw.println(")");
16986    }
16987
16988    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16989            int opti, boolean dumpAll) {
16990        boolean needSep = false;
16991
16992        if (mLruProcesses.size() > 0) {
16993            if (needSep) pw.println();
16994            needSep = true;
16995            pw.println("  OOM levels:");
16996            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16997            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16998            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16999            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
17000            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
17001            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
17002            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
17003            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
17004            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
17005            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
17006            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
17007            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
17008            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
17009            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
17010
17011            if (needSep) pw.println();
17012            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
17013                    pw.print(" total, non-act at ");
17014                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
17015                    pw.print(", non-svc at ");
17016                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
17017                    pw.println("):");
17018            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
17019            needSep = true;
17020        }
17021
17022        dumpProcessesToGc(pw, needSep, null);
17023
17024        pw.println();
17025        pw.println("  mHomeProcess: " + mHomeProcess);
17026        pw.println("  mPreviousProcess: " + mPreviousProcess);
17027        if (mHeavyWeightProcess != null) {
17028            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
17029        }
17030
17031        return true;
17032    }
17033
17034    /**
17035     * There are three ways to call this:
17036     *  - no provider specified: dump all the providers
17037     *  - a flattened component name that matched an existing provider was specified as the
17038     *    first arg: dump that one provider
17039     *  - the first arg isn't the flattened component name of an existing provider:
17040     *    dump all providers whose component contains the first arg as a substring
17041     */
17042    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17043            int opti, boolean dumpAll) {
17044        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
17045    }
17046
17047    /**
17048     * Similar to the dumpProvider, but only dumps the first matching provider.
17049     * The provider is responsible for dumping as proto.
17050     */
17051    protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
17052            String[] args) {
17053        return mProviderMap.dumpProviderProto(fd, pw, name, args);
17054    }
17055
17056    static class ItemMatcher {
17057        ArrayList<ComponentName> components;
17058        ArrayList<String> strings;
17059        ArrayList<Integer> objects;
17060        boolean all;
17061
17062        ItemMatcher() {
17063            all = true;
17064        }
17065
17066        void build(String name) {
17067            ComponentName componentName = ComponentName.unflattenFromString(name);
17068            if (componentName != null) {
17069                if (components == null) {
17070                    components = new ArrayList<ComponentName>();
17071                }
17072                components.add(componentName);
17073                all = false;
17074            } else {
17075                int objectId = 0;
17076                // Not a '/' separated full component name; maybe an object ID?
17077                try {
17078                    objectId = Integer.parseInt(name, 16);
17079                    if (objects == null) {
17080                        objects = new ArrayList<Integer>();
17081                    }
17082                    objects.add(objectId);
17083                    all = false;
17084                } catch (RuntimeException e) {
17085                    // Not an integer; just do string match.
17086                    if (strings == null) {
17087                        strings = new ArrayList<String>();
17088                    }
17089                    strings.add(name);
17090                    all = false;
17091                }
17092            }
17093        }
17094
17095        int build(String[] args, int opti) {
17096            for (; opti<args.length; opti++) {
17097                String name = args[opti];
17098                if ("--".equals(name)) {
17099                    return opti+1;
17100                }
17101                build(name);
17102            }
17103            return opti;
17104        }
17105
17106        boolean match(Object object, ComponentName comp) {
17107            if (all) {
17108                return true;
17109            }
17110            if (components != null) {
17111                for (int i=0; i<components.size(); i++) {
17112                    if (components.get(i).equals(comp)) {
17113                        return true;
17114                    }
17115                }
17116            }
17117            if (objects != null) {
17118                for (int i=0; i<objects.size(); i++) {
17119                    if (System.identityHashCode(object) == objects.get(i)) {
17120                        return true;
17121                    }
17122                }
17123            }
17124            if (strings != null) {
17125                String flat = comp.flattenToString();
17126                for (int i=0; i<strings.size(); i++) {
17127                    if (flat.contains(strings.get(i))) {
17128                        return true;
17129                    }
17130                }
17131            }
17132            return false;
17133        }
17134    }
17135
17136    /**
17137     * There are three things that cmd can be:
17138     *  - a flattened component name that matches an existing activity
17139     *  - the cmd arg isn't the flattened component name of an existing activity:
17140     *    dump all activity whose component contains the cmd as a substring
17141     *  - A hex number of the ActivityRecord object instance.
17142     *
17143     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
17144     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
17145     */
17146    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17147            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
17148        ArrayList<ActivityRecord> activities;
17149
17150        synchronized (this) {
17151            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
17152                    dumpFocusedStackOnly);
17153        }
17154
17155        if (activities.size() <= 0) {
17156            return false;
17157        }
17158
17159        String[] newArgs = new String[args.length - opti];
17160        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
17161
17162        TaskRecord lastTask = null;
17163        boolean needSep = false;
17164        for (int i=activities.size()-1; i>=0; i--) {
17165            ActivityRecord r = activities.get(i);
17166            if (needSep) {
17167                pw.println();
17168            }
17169            needSep = true;
17170            synchronized (this) {
17171                final TaskRecord task = r.getTask();
17172                if (lastTask != task) {
17173                    lastTask = task;
17174                    pw.print("TASK "); pw.print(lastTask.affinity);
17175                            pw.print(" id="); pw.print(lastTask.taskId);
17176                            pw.print(" userId="); pw.println(lastTask.userId);
17177                    if (dumpAll) {
17178                        lastTask.dump(pw, "  ");
17179                    }
17180                }
17181            }
17182            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
17183        }
17184        return true;
17185    }
17186
17187    /**
17188     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
17189     * there is a thread associated with the activity.
17190     */
17191    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
17192            final ActivityRecord r, String[] args, boolean dumpAll) {
17193        String innerPrefix = prefix + "  ";
17194        synchronized (this) {
17195            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
17196                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
17197                    pw.print(" pid=");
17198                    if (r.app != null) pw.println(r.app.pid);
17199                    else pw.println("(not running)");
17200            if (dumpAll) {
17201                r.dump(pw, innerPrefix);
17202            }
17203        }
17204        if (r.app != null && r.app.thread != null) {
17205            // flush anything that is already in the PrintWriter since the thread is going
17206            // to write to the file descriptor directly
17207            pw.flush();
17208            try {
17209                TransferPipe tp = new TransferPipe();
17210                try {
17211                    r.app.thread.dumpActivity(tp.getWriteFd(),
17212                            r.appToken, innerPrefix, args);
17213                    tp.go(fd);
17214                } finally {
17215                    tp.kill();
17216                }
17217            } catch (IOException e) {
17218                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
17219            } catch (RemoteException e) {
17220                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
17221            }
17222        }
17223    }
17224
17225    void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
17226        if (mRegisteredReceivers.size() > 0) {
17227            Iterator it = mRegisteredReceivers.values().iterator();
17228            while (it.hasNext()) {
17229                ReceiverList r = (ReceiverList)it.next();
17230                r.writeToProto(proto, BroadcastProto.RECEIVER_LIST);
17231            }
17232        }
17233        mReceiverResolver.writeToProto(proto, BroadcastProto.RECEIVER_RESOLVER);
17234        for (BroadcastQueue q : mBroadcastQueues) {
17235            q.writeToProto(proto, BroadcastProto.BROADCAST_QUEUE);
17236        }
17237        for (int user=0; user<mStickyBroadcasts.size(); user++) {
17238            long token = proto.start(BroadcastProto.STICKY_BROADCASTS);
17239            proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
17240            for (Map.Entry<String, ArrayList<Intent>> ent
17241                    : mStickyBroadcasts.valueAt(user).entrySet()) {
17242                long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
17243                proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
17244                for (Intent intent : ent.getValue()) {
17245                    intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
17246                            false, true, true, false);
17247                }
17248                proto.end(actionToken);
17249            }
17250            proto.end(token);
17251        }
17252
17253        long handlerToken = proto.start(BroadcastProto.HANDLER);
17254        proto.write(BroadcastProto.MainHandler.HANDLER, mHandler.toString());
17255        mHandler.getLooper().writeToProto(proto, BroadcastProto.MainHandler.LOOPER);
17256        proto.end(handlerToken);
17257    }
17258
17259    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17260            int opti, boolean dumpAll, String dumpPackage) {
17261        boolean needSep = false;
17262        boolean onlyHistory = false;
17263        boolean printedAnything = false;
17264
17265        if ("history".equals(dumpPackage)) {
17266            if (opti < args.length && "-s".equals(args[opti])) {
17267                dumpAll = false;
17268            }
17269            onlyHistory = true;
17270            dumpPackage = null;
17271        }
17272
17273        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
17274        if (!onlyHistory && dumpAll) {
17275            if (mRegisteredReceivers.size() > 0) {
17276                boolean printed = false;
17277                Iterator it = mRegisteredReceivers.values().iterator();
17278                while (it.hasNext()) {
17279                    ReceiverList r = (ReceiverList)it.next();
17280                    if (dumpPackage != null && (r.app == null ||
17281                            !dumpPackage.equals(r.app.info.packageName))) {
17282                        continue;
17283                    }
17284                    if (!printed) {
17285                        pw.println("  Registered Receivers:");
17286                        needSep = true;
17287                        printed = true;
17288                        printedAnything = true;
17289                    }
17290                    pw.print("  * "); pw.println(r);
17291                    r.dump(pw, "    ");
17292                }
17293            }
17294
17295            if (mReceiverResolver.dump(pw, needSep ?
17296                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
17297                    "    ", dumpPackage, false, false)) {
17298                needSep = true;
17299                printedAnything = true;
17300            }
17301        }
17302
17303        for (BroadcastQueue q : mBroadcastQueues) {
17304            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17305            printedAnything |= needSep;
17306        }
17307
17308        needSep = true;
17309
17310        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17311            for (int user=0; user<mStickyBroadcasts.size(); user++) {
17312                if (needSep) {
17313                    pw.println();
17314                }
17315                needSep = true;
17316                printedAnything = true;
17317                pw.print("  Sticky broadcasts for user ");
17318                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
17319                StringBuilder sb = new StringBuilder(128);
17320                for (Map.Entry<String, ArrayList<Intent>> ent
17321                        : mStickyBroadcasts.valueAt(user).entrySet()) {
17322                    pw.print("  * Sticky action "); pw.print(ent.getKey());
17323                    if (dumpAll) {
17324                        pw.println(":");
17325                        ArrayList<Intent> intents = ent.getValue();
17326                        final int N = intents.size();
17327                        for (int i=0; i<N; i++) {
17328                            sb.setLength(0);
17329                            sb.append("    Intent: ");
17330                            intents.get(i).toShortString(sb, false, true, false, false);
17331                            pw.println(sb.toString());
17332                            Bundle bundle = intents.get(i).getExtras();
17333                            if (bundle != null) {
17334                                pw.print("      ");
17335                                pw.println(bundle.toString());
17336                            }
17337                        }
17338                    } else {
17339                        pw.println("");
17340                    }
17341                }
17342            }
17343        }
17344
17345        if (!onlyHistory && dumpAll) {
17346            pw.println();
17347            for (BroadcastQueue queue : mBroadcastQueues) {
17348                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
17349                        + queue.mBroadcastsScheduled);
17350            }
17351            pw.println("  mHandler:");
17352            mHandler.dump(new PrintWriterPrinter(pw), "    ");
17353            needSep = true;
17354            printedAnything = true;
17355        }
17356
17357        if (!printedAnything) {
17358            pw.println("  (nothing)");
17359        }
17360    }
17361
17362    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17363            int opti, boolean dumpAll, String dumpPackage) {
17364        if (mCurBroadcastStats == null) {
17365            return;
17366        }
17367
17368        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
17369        final long now = SystemClock.elapsedRealtime();
17370        if (mLastBroadcastStats != null) {
17371            pw.print("  Last stats (from ");
17372            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
17373            pw.print(" to ");
17374            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
17375            pw.print(", ");
17376            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
17377                    - mLastBroadcastStats.mStartUptime, pw);
17378            pw.println(" uptime):");
17379            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17380                pw.println("    (nothing)");
17381            }
17382            pw.println();
17383        }
17384        pw.print("  Current stats (from ");
17385        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
17386        pw.print(" to now, ");
17387        TimeUtils.formatDuration(SystemClock.uptimeMillis()
17388                - mCurBroadcastStats.mStartUptime, pw);
17389        pw.println(" uptime):");
17390        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17391            pw.println("    (nothing)");
17392        }
17393    }
17394
17395    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17396            int opti, boolean fullCheckin, String dumpPackage) {
17397        if (mCurBroadcastStats == null) {
17398            return;
17399        }
17400
17401        if (mLastBroadcastStats != null) {
17402            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17403            if (fullCheckin) {
17404                mLastBroadcastStats = null;
17405                return;
17406            }
17407        }
17408        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17409        if (fullCheckin) {
17410            mCurBroadcastStats = null;
17411        }
17412    }
17413
17414    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17415            int opti, boolean dumpAll, String dumpPackage) {
17416        boolean needSep;
17417        boolean printedAnything = false;
17418
17419        ItemMatcher matcher = new ItemMatcher();
17420        matcher.build(args, opti);
17421
17422        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
17423
17424        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
17425        printedAnything |= needSep;
17426
17427        if (mLaunchingProviders.size() > 0) {
17428            boolean printed = false;
17429            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
17430                ContentProviderRecord r = mLaunchingProviders.get(i);
17431                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
17432                    continue;
17433                }
17434                if (!printed) {
17435                    if (needSep) pw.println();
17436                    needSep = true;
17437                    pw.println("  Launching content providers:");
17438                    printed = true;
17439                    printedAnything = true;
17440                }
17441                pw.print("  Launching #"); pw.print(i); pw.print(": ");
17442                        pw.println(r);
17443            }
17444        }
17445
17446        if (!printedAnything) {
17447            pw.println("  (nothing)");
17448        }
17449    }
17450
17451    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17452            int opti, boolean dumpAll, String dumpPackage) {
17453        boolean needSep = false;
17454        boolean printedAnything = false;
17455
17456        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
17457
17458        if (mGrantedUriPermissions.size() > 0) {
17459            boolean printed = false;
17460            int dumpUid = -2;
17461            if (dumpPackage != null) {
17462                try {
17463                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
17464                            MATCH_ANY_USER, 0);
17465                } catch (NameNotFoundException e) {
17466                    dumpUid = -1;
17467                }
17468            }
17469            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
17470                int uid = mGrantedUriPermissions.keyAt(i);
17471                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
17472                    continue;
17473                }
17474                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
17475                if (!printed) {
17476                    if (needSep) pw.println();
17477                    needSep = true;
17478                    pw.println("  Granted Uri Permissions:");
17479                    printed = true;
17480                    printedAnything = true;
17481                }
17482                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
17483                for (UriPermission perm : perms.values()) {
17484                    pw.print("    "); pw.println(perm);
17485                    if (dumpAll) {
17486                        perm.dump(pw, "      ");
17487                    }
17488                }
17489            }
17490        }
17491
17492        if (!printedAnything) {
17493            pw.println("  (nothing)");
17494        }
17495    }
17496
17497    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17498            int opti, boolean dumpAll, String dumpPackage) {
17499        boolean printed = false;
17500
17501        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
17502
17503        if (mIntentSenderRecords.size() > 0) {
17504            // Organize these by package name, so they are easier to read.
17505            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
17506            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
17507            final Iterator<WeakReference<PendingIntentRecord>> it
17508                    = mIntentSenderRecords.values().iterator();
17509            while (it.hasNext()) {
17510                WeakReference<PendingIntentRecord> ref = it.next();
17511                PendingIntentRecord rec = ref != null ? ref.get() : null;
17512                if (rec == null) {
17513                    weakRefs.add(ref);
17514                    continue;
17515                }
17516                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
17517                    continue;
17518                }
17519                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
17520                if (list == null) {
17521                    list = new ArrayList<>();
17522                    byPackage.put(rec.key.packageName, list);
17523                }
17524                list.add(rec);
17525            }
17526            for (int i = 0; i < byPackage.size(); i++) {
17527                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
17528                printed = true;
17529                pw.print("  * "); pw.print(byPackage.keyAt(i));
17530                pw.print(": "); pw.print(intents.size()); pw.println(" items");
17531                for (int j = 0; j < intents.size(); j++) {
17532                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
17533                    if (dumpAll) {
17534                        intents.get(j).dump(pw, "      ");
17535                    }
17536                }
17537            }
17538            if (weakRefs.size() > 0) {
17539                printed = true;
17540                pw.println("  * WEAK REFS:");
17541                for (int i = 0; i < weakRefs.size(); i++) {
17542                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
17543                }
17544            }
17545        }
17546
17547        if (!printed) {
17548            pw.println("  (nothing)");
17549        }
17550    }
17551
17552    private static final int dumpProcessList(PrintWriter pw,
17553            ActivityManagerService service, List list,
17554            String prefix, String normalLabel, String persistentLabel,
17555            String dumpPackage) {
17556        int numPers = 0;
17557        final int N = list.size()-1;
17558        for (int i=N; i>=0; i--) {
17559            ProcessRecord r = (ProcessRecord)list.get(i);
17560            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17561                continue;
17562            }
17563            pw.println(String.format("%s%s #%2d: %s",
17564                    prefix, (r.persistent ? persistentLabel : normalLabel),
17565                    i, r.toString()));
17566            if (r.persistent) {
17567                numPers++;
17568            }
17569        }
17570        return numPers;
17571    }
17572
17573    private static final ArrayList<Pair<ProcessRecord, Integer>>
17574        sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
17575        ArrayList<Pair<ProcessRecord, Integer>> list
17576                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
17577        for (int i=0; i<origList.size(); i++) {
17578            ProcessRecord r = origList.get(i);
17579            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17580                continue;
17581            }
17582            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
17583        }
17584
17585        Comparator<Pair<ProcessRecord, Integer>> comparator
17586                = new Comparator<Pair<ProcessRecord, Integer>>() {
17587            @Override
17588            public int compare(Pair<ProcessRecord, Integer> object1,
17589                    Pair<ProcessRecord, Integer> object2) {
17590                if (object1.first.setAdj != object2.first.setAdj) {
17591                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
17592                }
17593                if (object1.first.setProcState != object2.first.setProcState) {
17594                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
17595                }
17596                if (object1.second.intValue() != object2.second.intValue()) {
17597                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
17598                }
17599                return 0;
17600            }
17601        };
17602
17603        Collections.sort(list, comparator);
17604        return list;
17605    }
17606
17607    private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
17608            ActivityManagerService service, List<ProcessRecord> origList,
17609            boolean inclDetails, String dumpPackage) {
17610        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17611        if (list.isEmpty()) return false;
17612
17613        final long curUptime = SystemClock.uptimeMillis();
17614
17615        for (int i = list.size() - 1; i >= 0; i--) {
17616            ProcessRecord r = list.get(i).first;
17617            long token = proto.start(fieldId);
17618            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17619            proto.write(ProcessOomProto.PERSISTENT, r.persistent);
17620            proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
17621            proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
17622            int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
17623            switch (r.setSchedGroup) {
17624                case ProcessList.SCHED_GROUP_BACKGROUND:
17625                    schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
17626                    break;
17627                case ProcessList.SCHED_GROUP_DEFAULT:
17628                    schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
17629                    break;
17630                case ProcessList.SCHED_GROUP_TOP_APP:
17631                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
17632                    break;
17633                case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
17634                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
17635                    break;
17636            }
17637            if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
17638                proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
17639            }
17640            if (r.foregroundActivities) {
17641                proto.write(ProcessOomProto.ACTIVITIES, true);
17642            } else if (r.foregroundServices) {
17643                proto.write(ProcessOomProto.SERVICES, true);
17644            }
17645            proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
17646            proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
17647            r.writeToProto(proto, ProcessOomProto.PROC);
17648            proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
17649            if (r.adjSource != null || r.adjTarget != null) {
17650                if (r.adjTarget instanceof  ComponentName) {
17651                    ComponentName cn = (ComponentName) r.adjTarget;
17652                    cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
17653                } else if (r.adjTarget != null) {
17654                    proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
17655                }
17656                if (r.adjSource instanceof ProcessRecord) {
17657                    ProcessRecord p = (ProcessRecord) r.adjSource;
17658                    p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
17659                } else if (r.adjSource != null) {
17660                    proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
17661                }
17662            }
17663            if (inclDetails) {
17664                long detailToken = proto.start(ProcessOomProto.DETAIL);
17665                proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
17666                proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
17667                proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
17668                proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
17669                proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
17670                proto.write(ProcessOomProto.Detail.CURRENT_STATE,
17671                        ProcessList.makeProcStateProtoEnum(r.curProcState));
17672                proto.write(ProcessOomProto.Detail.SET_STATE,
17673                        ProcessList.makeProcStateProtoEnum(r.setProcState));
17674                proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
17675                        r.lastPss*1024, new StringBuilder()));
17676                proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
17677                        r.lastSwapPss*1024, new StringBuilder()));
17678                proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
17679                        r.lastCachedPss*1024, new StringBuilder()));
17680                proto.write(ProcessOomProto.Detail.CACHED, r.cached);
17681                proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
17682                proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
17683
17684                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
17685                    if (r.lastCpuTime != 0) {
17686                        long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17687                        long timeUsed = r.curCpuTime - r.lastCpuTime;
17688                        long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
17689                        proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
17690                        proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
17691                        proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
17692                                (100.0*timeUsed)/uptimeSince);
17693                        proto.end(cpuTimeToken);
17694                    }
17695                }
17696                proto.end(detailToken);
17697            }
17698            proto.end(token);
17699        }
17700
17701        return true;
17702    }
17703
17704    private static final boolean dumpProcessOomList(PrintWriter pw,
17705            ActivityManagerService service, List<ProcessRecord> origList,
17706            String prefix, String normalLabel, String persistentLabel,
17707            boolean inclDetails, String dumpPackage) {
17708
17709        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17710        if (list.isEmpty()) return false;
17711
17712        final long curUptime = SystemClock.uptimeMillis();
17713        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17714
17715        for (int i=list.size()-1; i>=0; i--) {
17716            ProcessRecord r = list.get(i).first;
17717            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17718            char schedGroup;
17719            switch (r.setSchedGroup) {
17720                case ProcessList.SCHED_GROUP_BACKGROUND:
17721                    schedGroup = 'B';
17722                    break;
17723                case ProcessList.SCHED_GROUP_DEFAULT:
17724                    schedGroup = 'F';
17725                    break;
17726                case ProcessList.SCHED_GROUP_TOP_APP:
17727                    schedGroup = 'T';
17728                    break;
17729                default:
17730                    schedGroup = '?';
17731                    break;
17732            }
17733            char foreground;
17734            if (r.foregroundActivities) {
17735                foreground = 'A';
17736            } else if (r.foregroundServices) {
17737                foreground = 'S';
17738            } else {
17739                foreground = ' ';
17740            }
17741            String procState = ProcessList.makeProcStateString(r.curProcState);
17742            pw.print(prefix);
17743            pw.print(r.persistent ? persistentLabel : normalLabel);
17744            pw.print(" #");
17745            int num = (origList.size()-1)-list.get(i).second;
17746            if (num < 10) pw.print(' ');
17747            pw.print(num);
17748            pw.print(": ");
17749            pw.print(oomAdj);
17750            pw.print(' ');
17751            pw.print(schedGroup);
17752            pw.print('/');
17753            pw.print(foreground);
17754            pw.print('/');
17755            pw.print(procState);
17756            pw.print(" trm:");
17757            if (r.trimMemoryLevel < 10) pw.print(' ');
17758            pw.print(r.trimMemoryLevel);
17759            pw.print(' ');
17760            pw.print(r.toShortString());
17761            pw.print(" (");
17762            pw.print(r.adjType);
17763            pw.println(')');
17764            if (r.adjSource != null || r.adjTarget != null) {
17765                pw.print(prefix);
17766                pw.print("    ");
17767                if (r.adjTarget instanceof ComponentName) {
17768                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
17769                } else if (r.adjTarget != null) {
17770                    pw.print(r.adjTarget.toString());
17771                } else {
17772                    pw.print("{null}");
17773                }
17774                pw.print("<=");
17775                if (r.adjSource instanceof ProcessRecord) {
17776                    pw.print("Proc{");
17777                    pw.print(((ProcessRecord)r.adjSource).toShortString());
17778                    pw.println("}");
17779                } else if (r.adjSource != null) {
17780                    pw.println(r.adjSource.toString());
17781                } else {
17782                    pw.println("{null}");
17783                }
17784            }
17785            if (inclDetails) {
17786                pw.print(prefix);
17787                pw.print("    ");
17788                pw.print("oom: max="); pw.print(r.maxAdj);
17789                pw.print(" curRaw="); pw.print(r.curRawAdj);
17790                pw.print(" setRaw="); pw.print(r.setRawAdj);
17791                pw.print(" cur="); pw.print(r.curAdj);
17792                pw.print(" set="); pw.println(r.setAdj);
17793                pw.print(prefix);
17794                pw.print("    ");
17795                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
17796                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
17797                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
17798                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
17799                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
17800                pw.println();
17801                pw.print(prefix);
17802                pw.print("    ");
17803                pw.print("cached="); pw.print(r.cached);
17804                pw.print(" empty="); pw.print(r.empty);
17805                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
17806
17807                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
17808                    if (r.lastCpuTime != 0) {
17809                        long timeUsed = r.curCpuTime - r.lastCpuTime;
17810                        pw.print(prefix);
17811                        pw.print("    ");
17812                        pw.print("run cpu over ");
17813                        TimeUtils.formatDuration(uptimeSince, pw);
17814                        pw.print(" used ");
17815                        TimeUtils.formatDuration(timeUsed, pw);
17816                        pw.print(" (");
17817                        pw.print((timeUsed*100)/uptimeSince);
17818                        pw.println("%)");
17819                    }
17820                }
17821            }
17822        }
17823        return true;
17824    }
17825
17826    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
17827            String[] args) {
17828        ArrayList<ProcessRecord> procs;
17829        synchronized (this) {
17830            if (args != null && args.length > start
17831                    && args[start].charAt(0) != '-') {
17832                procs = new ArrayList<ProcessRecord>();
17833                int pid = -1;
17834                try {
17835                    pid = Integer.parseInt(args[start]);
17836                } catch (NumberFormatException e) {
17837                }
17838                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17839                    ProcessRecord proc = mLruProcesses.get(i);
17840                    if (proc.pid > 0 && proc.pid == pid) {
17841                        procs.add(proc);
17842                    } else if (allPkgs && proc.pkgList != null
17843                            && proc.pkgList.containsKey(args[start])) {
17844                        procs.add(proc);
17845                    } else if (proc.processName.equals(args[start])) {
17846                        procs.add(proc);
17847                    }
17848                }
17849                if (procs.size() <= 0) {
17850                    return null;
17851                }
17852            } else {
17853                procs = new ArrayList<ProcessRecord>(mLruProcesses);
17854            }
17855        }
17856        return procs;
17857    }
17858
17859    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
17860            PrintWriter pw, String[] args) {
17861        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
17862        if (procs == null) {
17863            pw.println("No process found for: " + args[0]);
17864            return;
17865        }
17866
17867        long uptime = SystemClock.uptimeMillis();
17868        long realtime = SystemClock.elapsedRealtime();
17869        pw.println("Applications Graphics Acceleration Info:");
17870        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17871
17872        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17873            ProcessRecord r = procs.get(i);
17874            if (r.thread != null) {
17875                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
17876                pw.flush();
17877                try {
17878                    TransferPipe tp = new TransferPipe();
17879                    try {
17880                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
17881                        tp.go(fd);
17882                    } finally {
17883                        tp.kill();
17884                    }
17885                } catch (IOException e) {
17886                    pw.println("Failure while dumping the app: " + r);
17887                    pw.flush();
17888                } catch (RemoteException e) {
17889                    pw.println("Got a RemoteException while dumping the app " + r);
17890                    pw.flush();
17891                }
17892            }
17893        }
17894    }
17895
17896    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
17897        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
17898        if (procs == null) {
17899            pw.println("No process found for: " + args[0]);
17900            return;
17901        }
17902
17903        pw.println("Applications Database Info:");
17904
17905        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17906            ProcessRecord r = procs.get(i);
17907            if (r.thread != null) {
17908                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
17909                pw.flush();
17910                try {
17911                    TransferPipe tp = new TransferPipe();
17912                    try {
17913                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
17914                        tp.go(fd);
17915                    } finally {
17916                        tp.kill();
17917                    }
17918                } catch (IOException e) {
17919                    pw.println("Failure while dumping the app: " + r);
17920                    pw.flush();
17921                } catch (RemoteException e) {
17922                    pw.println("Got a RemoteException while dumping the app " + r);
17923                    pw.flush();
17924                }
17925            }
17926        }
17927    }
17928
17929    final static class MemItem {
17930        final boolean isProc;
17931        final String label;
17932        final String shortLabel;
17933        final long pss;
17934        final long swapPss;
17935        final int id;
17936        final boolean hasActivities;
17937        ArrayList<MemItem> subitems;
17938
17939        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
17940                boolean _hasActivities) {
17941            isProc = true;
17942            label = _label;
17943            shortLabel = _shortLabel;
17944            pss = _pss;
17945            swapPss = _swapPss;
17946            id = _id;
17947            hasActivities = _hasActivities;
17948        }
17949
17950        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
17951            isProc = false;
17952            label = _label;
17953            shortLabel = _shortLabel;
17954            pss = _pss;
17955            swapPss = _swapPss;
17956            id = _id;
17957            hasActivities = false;
17958        }
17959    }
17960
17961    private static void sortMemItems(List<MemItem> items) {
17962        Collections.sort(items, new Comparator<MemItem>() {
17963            @Override
17964            public int compare(MemItem lhs, MemItem rhs) {
17965                if (lhs.pss < rhs.pss) {
17966                    return 1;
17967                } else if (lhs.pss > rhs.pss) {
17968                    return -1;
17969                }
17970                return 0;
17971            }
17972        });
17973    }
17974
17975    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
17976            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
17977        if (sort && !isCompact) {
17978            sortMemItems(items);
17979        }
17980
17981        for (int i=0; i<items.size(); i++) {
17982            MemItem mi = items.get(i);
17983            if (!isCompact) {
17984                if (dumpSwapPss) {
17985                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
17986                            mi.label, stringifyKBSize(mi.swapPss));
17987                } else {
17988                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
17989                }
17990            } else if (mi.isProc) {
17991                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
17992                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
17993                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
17994                pw.println(mi.hasActivities ? ",a" : ",e");
17995            } else {
17996                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
17997                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
17998            }
17999            if (mi.subitems != null) {
18000                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
18001                        true, isCompact, dumpSwapPss);
18002            }
18003        }
18004    }
18005
18006    static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
18007            ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
18008        if (sort) {
18009            sortMemItems(items);
18010        }
18011
18012        for (int i=0; i<items.size(); i++) {
18013            MemItem mi = items.get(i);
18014            final long token = proto.start(fieldId);
18015
18016            proto.write(MemInfoProto.MemItem.TAG, tag);
18017            proto.write(MemInfoProto.MemItem.LABEL, mi.shortLabel);
18018            proto.write(MemInfoProto.MemItem.IS_PROC, mi.isProc);
18019            proto.write(MemInfoProto.MemItem.ID, mi.id);
18020            proto.write(MemInfoProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
18021            proto.write(MemInfoProto.MemItem.PSS_KB, mi.pss);
18022            if (dumpSwapPss) {
18023                proto.write(MemInfoProto.MemItem.SWAP_PSS_KB, mi.swapPss);
18024            }
18025            if (mi.subitems != null) {
18026                dumpMemItems(proto, MemInfoProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
18027                        true, dumpSwapPss);
18028            }
18029            proto.end(token);
18030        }
18031    }
18032
18033    // These are in KB.
18034    static final long[] DUMP_MEM_BUCKETS = new long[] {
18035        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
18036        120*1024, 160*1024, 200*1024,
18037        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
18038        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
18039    };
18040
18041    static final void appendMemBucket(StringBuilder out, long memKB, String label,
18042            boolean stackLike) {
18043        int start = label.lastIndexOf('.');
18044        if (start >= 0) start++;
18045        else start = 0;
18046        int end = label.length();
18047        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
18048            if (DUMP_MEM_BUCKETS[i] >= memKB) {
18049                long bucket = DUMP_MEM_BUCKETS[i]/1024;
18050                out.append(bucket);
18051                out.append(stackLike ? "MB." : "MB ");
18052                out.append(label, start, end);
18053                return;
18054            }
18055        }
18056        out.append(memKB/1024);
18057        out.append(stackLike ? "MB." : "MB ");
18058        out.append(label, start, end);
18059    }
18060
18061    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
18062            ProcessList.NATIVE_ADJ,
18063            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
18064            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
18065            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
18066            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
18067            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
18068            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
18069    };
18070    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
18071            "Native",
18072            "System", "Persistent", "Persistent Service", "Foreground",
18073            "Visible", "Perceptible",
18074            "Heavy Weight", "Backup",
18075            "A Services", "Home",
18076            "Previous", "B Services", "Cached"
18077    };
18078    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
18079            "native",
18080            "sys", "pers", "persvc", "fore",
18081            "vis", "percept",
18082            "heavy", "backup",
18083            "servicea", "home",
18084            "prev", "serviceb", "cached"
18085    };
18086
18087    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
18088            long realtime, boolean isCheckinRequest, boolean isCompact) {
18089        if (isCompact) {
18090            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
18091        }
18092        if (isCheckinRequest || isCompact) {
18093            // short checkin version
18094            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
18095        } else {
18096            pw.println("Applications Memory Usage (in Kilobytes):");
18097            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18098        }
18099    }
18100
18101    private static final int KSM_SHARED = 0;
18102    private static final int KSM_SHARING = 1;
18103    private static final int KSM_UNSHARED = 2;
18104    private static final int KSM_VOLATILE = 3;
18105
18106    private final long[] getKsmInfo() {
18107        long[] longOut = new long[4];
18108        final int[] SINGLE_LONG_FORMAT = new int[] {
18109            PROC_SPACE_TERM| PROC_OUT_LONG
18110        };
18111        long[] longTmp = new long[1];
18112        readProcFile("/sys/kernel/mm/ksm/pages_shared",
18113                SINGLE_LONG_FORMAT, null, longTmp, null);
18114        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18115        longTmp[0] = 0;
18116        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
18117                SINGLE_LONG_FORMAT, null, longTmp, null);
18118        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18119        longTmp[0] = 0;
18120        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
18121                SINGLE_LONG_FORMAT, null, longTmp, null);
18122        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18123        longTmp[0] = 0;
18124        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
18125                SINGLE_LONG_FORMAT, null, longTmp, null);
18126        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18127        return longOut;
18128    }
18129
18130    private static String stringifySize(long size, int order) {
18131        Locale locale = Locale.US;
18132        switch (order) {
18133            case 1:
18134                return String.format(locale, "%,13d", size);
18135            case 1024:
18136                return String.format(locale, "%,9dK", size / 1024);
18137            case 1024 * 1024:
18138                return String.format(locale, "%,5dM", size / 1024 / 1024);
18139            case 1024 * 1024 * 1024:
18140                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
18141            default:
18142                throw new IllegalArgumentException("Invalid size order");
18143        }
18144    }
18145
18146    private static String stringifyKBSize(long size) {
18147        return stringifySize(size * 1024, 1024);
18148    }
18149
18150    // Update this version number if you change the 'compact' format.
18151    private static final int MEMINFO_COMPACT_VERSION = 1;
18152
18153    private static class MemoryUsageDumpOptions {
18154        boolean dumpDetails;
18155        boolean dumpFullDetails;
18156        boolean dumpDalvik;
18157        boolean dumpSummaryOnly;
18158        boolean dumpUnreachable;
18159        boolean oomOnly;
18160        boolean isCompact;
18161        boolean localOnly;
18162        boolean packages;
18163        boolean isCheckinRequest;
18164        boolean dumpSwapPss;
18165        boolean dumpProto;
18166    }
18167
18168    final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18169            String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
18170        MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
18171        opts.dumpDetails = false;
18172        opts.dumpFullDetails = false;
18173        opts.dumpDalvik = false;
18174        opts.dumpSummaryOnly = false;
18175        opts.dumpUnreachable = false;
18176        opts.oomOnly = false;
18177        opts.isCompact = false;
18178        opts.localOnly = false;
18179        opts.packages = false;
18180        opts.isCheckinRequest = false;
18181        opts.dumpSwapPss = false;
18182        opts.dumpProto = asProto;
18183
18184        int opti = 0;
18185        while (opti < args.length) {
18186            String opt = args[opti];
18187            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18188                break;
18189            }
18190            opti++;
18191            if ("-a".equals(opt)) {
18192                opts.dumpDetails = true;
18193                opts.dumpFullDetails = true;
18194                opts.dumpDalvik = true;
18195                opts.dumpSwapPss = true;
18196            } else if ("-d".equals(opt)) {
18197                opts.dumpDalvik = true;
18198            } else if ("-c".equals(opt)) {
18199                opts.isCompact = true;
18200            } else if ("-s".equals(opt)) {
18201                opts.dumpDetails = true;
18202                opts.dumpSummaryOnly = true;
18203            } else if ("-S".equals(opt)) {
18204                opts.dumpSwapPss = true;
18205            } else if ("--unreachable".equals(opt)) {
18206                opts.dumpUnreachable = true;
18207            } else if ("--oom".equals(opt)) {
18208                opts.oomOnly = true;
18209            } else if ("--local".equals(opt)) {
18210                opts.localOnly = true;
18211            } else if ("--package".equals(opt)) {
18212                opts.packages = true;
18213            } else if ("--checkin".equals(opt)) {
18214                opts.isCheckinRequest = true;
18215            } else if ("--proto".equals(opt)) {
18216                opts.dumpProto = true;
18217
18218            } else if ("-h".equals(opt)) {
18219                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
18220                pw.println("  -a: include all available information for each process.");
18221                pw.println("  -d: include dalvik details.");
18222                pw.println("  -c: dump in a compact machine-parseable representation.");
18223                pw.println("  -s: dump only summary of application memory usage.");
18224                pw.println("  -S: dump also SwapPss.");
18225                pw.println("  --oom: only show processes organized by oom adj.");
18226                pw.println("  --local: only collect details locally, don't call process.");
18227                pw.println("  --package: interpret process arg as package, dumping all");
18228                pw.println("             processes that have loaded that package.");
18229                pw.println("  --checkin: dump data for a checkin");
18230                pw.println("  --proto: dump data to proto");
18231                pw.println("If [process] is specified it can be the name or ");
18232                pw.println("pid of a specific process to dump.");
18233                return;
18234            } else {
18235                pw.println("Unknown argument: " + opt + "; use -h for help");
18236            }
18237        }
18238
18239        String[] innerArgs = new String[args.length-opti];
18240        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18241
18242        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18243        if (opts.dumpProto) {
18244            dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18245        } else {
18246            dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
18247        }
18248    }
18249
18250    private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18251            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18252            ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
18253        long uptime = SystemClock.uptimeMillis();
18254        long realtime = SystemClock.elapsedRealtime();
18255        final long[] tmpLong = new long[1];
18256
18257        if (procs == null) {
18258            // No Java processes.  Maybe they want to print a native process.
18259            String proc = "N/A";
18260            if (innerArgs.length > 0) {
18261                proc = innerArgs[0];
18262                if (proc.charAt(0) != '-') {
18263                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18264                            = new ArrayList<ProcessCpuTracker.Stats>();
18265                    updateCpuStatsNow();
18266                    int findPid = -1;
18267                    try {
18268                        findPid = Integer.parseInt(innerArgs[0]);
18269                    } catch (NumberFormatException e) {
18270                    }
18271                    synchronized (mProcessCpuTracker) {
18272                        final int N = mProcessCpuTracker.countStats();
18273                        for (int i=0; i<N; i++) {
18274                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18275                            if (st.pid == findPid || (st.baseName != null
18276                                    && st.baseName.equals(innerArgs[0]))) {
18277                                nativeProcs.add(st);
18278                            }
18279                        }
18280                    }
18281                    if (nativeProcs.size() > 0) {
18282                        dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
18283                                opts.isCheckinRequest, opts.isCompact);
18284                        Debug.MemoryInfo mi = null;
18285                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18286                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18287                            final int pid = r.pid;
18288                            if (!opts.isCheckinRequest && opts.dumpDetails) {
18289                                pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
18290                            }
18291                            if (mi == null) {
18292                                mi = new Debug.MemoryInfo();
18293                            }
18294                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18295                                Debug.getMemoryInfo(pid, mi);
18296                            } else {
18297                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18298                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18299                            }
18300                            ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
18301                                    opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18302                                    pid, r.baseName, 0, 0, 0, 0, 0, 0);
18303                            if (opts.isCheckinRequest) {
18304                                pw.println();
18305                            }
18306                        }
18307                        return;
18308                    }
18309                }
18310            }
18311            pw.println("No process found for: " + proc);
18312            return;
18313        }
18314
18315        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18316            opts.dumpDetails = true;
18317        }
18318
18319        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
18320
18321        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18322        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18323        long nativePss = 0;
18324        long nativeSwapPss = 0;
18325        long dalvikPss = 0;
18326        long dalvikSwapPss = 0;
18327        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18328                EmptyArray.LONG;
18329        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18330                EmptyArray.LONG;
18331        long otherPss = 0;
18332        long otherSwapPss = 0;
18333        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18334        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18335
18336        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18337        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18338        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18339                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18340
18341        long totalPss = 0;
18342        long totalSwapPss = 0;
18343        long cachedPss = 0;
18344        long cachedSwapPss = 0;
18345        boolean hasSwapPss = false;
18346
18347        Debug.MemoryInfo mi = null;
18348        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18349            final ProcessRecord r = procs.get(i);
18350            final IApplicationThread thread;
18351            final int pid;
18352            final int oomAdj;
18353            final boolean hasActivities;
18354            synchronized (this) {
18355                thread = r.thread;
18356                pid = r.pid;
18357                oomAdj = r.getSetAdjWithServices();
18358                hasActivities = r.activities.size() > 0;
18359            }
18360            if (thread != null) {
18361                if (!opts.isCheckinRequest && opts.dumpDetails) {
18362                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
18363                }
18364                if (mi == null) {
18365                    mi = new Debug.MemoryInfo();
18366                }
18367                final int reportType;
18368                final long startTime;
18369                final long endTime;
18370                if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18371                    reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18372                    startTime = SystemClock.currentThreadTimeMillis();
18373                    Debug.getMemoryInfo(pid, mi);
18374                    endTime = SystemClock.currentThreadTimeMillis();
18375                    hasSwapPss = mi.hasSwappedOutPss;
18376                } else {
18377                    reportType = ProcessStats.ADD_PSS_EXTERNAL;
18378                    startTime = SystemClock.currentThreadTimeMillis();
18379                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18380                    endTime = SystemClock.currentThreadTimeMillis();
18381                    mi.dalvikPrivateDirty = (int)tmpLong[0];
18382                }
18383                if (opts.dumpDetails) {
18384                    if (opts.localOnly) {
18385                        ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
18386                                opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
18387                        if (opts.isCheckinRequest) {
18388                            pw.println();
18389                        }
18390                    } else {
18391                        pw.flush();
18392                        try {
18393                            TransferPipe tp = new TransferPipe();
18394                            try {
18395                                thread.dumpMemInfo(tp.getWriteFd(),
18396                                        mi, opts.isCheckinRequest, opts.dumpFullDetails,
18397                                        opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
18398                                tp.go(fd);
18399                            } finally {
18400                                tp.kill();
18401                            }
18402                        } catch (IOException e) {
18403                            if (!opts.isCheckinRequest) {
18404                                pw.println("Got IoException! " + e);
18405                                pw.flush();
18406                            }
18407                        } catch (RemoteException e) {
18408                            if (!opts.isCheckinRequest) {
18409                                pw.println("Got RemoteException! " + e);
18410                                pw.flush();
18411                            }
18412                        }
18413                    }
18414                }
18415
18416                final long myTotalPss = mi.getTotalPss();
18417                final long myTotalUss = mi.getTotalUss();
18418                final long myTotalRss = mi.getTotalRss();
18419                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18420
18421                synchronized (this) {
18422                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18423                        // Record this for posterity if the process has been stable.
18424                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
18425                                reportType, endTime-startTime, r.pkgList);
18426                    }
18427                }
18428
18429                if (!opts.isCheckinRequest && mi != null) {
18430                    totalPss += myTotalPss;
18431                    totalSwapPss += myTotalSwapPss;
18432                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
18433                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
18434                            myTotalSwapPss, pid, hasActivities);
18435                    procMems.add(pssItem);
18436                    procMemsMap.put(pid, pssItem);
18437
18438                    nativePss += mi.nativePss;
18439                    nativeSwapPss += mi.nativeSwappedOutPss;
18440                    dalvikPss += mi.dalvikPss;
18441                    dalvikSwapPss += mi.dalvikSwappedOutPss;
18442                    for (int j=0; j<dalvikSubitemPss.length; j++) {
18443                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18444                        dalvikSubitemSwapPss[j] +=
18445                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18446                    }
18447                    otherPss += mi.otherPss;
18448                    otherSwapPss += mi.otherSwappedOutPss;
18449                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18450                        long mem = mi.getOtherPss(j);
18451                        miscPss[j] += mem;
18452                        otherPss -= mem;
18453                        mem = mi.getOtherSwappedOutPss(j);
18454                        miscSwapPss[j] += mem;
18455                        otherSwapPss -= mem;
18456                    }
18457
18458                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18459                        cachedPss += myTotalPss;
18460                        cachedSwapPss += myTotalSwapPss;
18461                    }
18462
18463                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
18464                        if (oomIndex == (oomPss.length - 1)
18465                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
18466                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
18467                            oomPss[oomIndex] += myTotalPss;
18468                            oomSwapPss[oomIndex] += myTotalSwapPss;
18469                            if (oomProcs[oomIndex] == null) {
18470                                oomProcs[oomIndex] = new ArrayList<MemItem>();
18471                            }
18472                            oomProcs[oomIndex].add(pssItem);
18473                            break;
18474                        }
18475                    }
18476                }
18477            }
18478        }
18479
18480        long nativeProcTotalPss = 0;
18481
18482        if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
18483            // If we are showing aggregations, also look for native processes to
18484            // include so that our aggregations are more accurate.
18485            updateCpuStatsNow();
18486            mi = null;
18487            synchronized (mProcessCpuTracker) {
18488                final int N = mProcessCpuTracker.countStats();
18489                for (int i=0; i<N; i++) {
18490                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18491                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
18492                        if (mi == null) {
18493                            mi = new Debug.MemoryInfo();
18494                        }
18495                        if (!brief && !opts.oomOnly) {
18496                            Debug.getMemoryInfo(st.pid, mi);
18497                        } else {
18498                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
18499                            mi.nativePrivateDirty = (int)tmpLong[0];
18500                        }
18501
18502                        final long myTotalPss = mi.getTotalPss();
18503                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18504                        totalPss += myTotalPss;
18505                        nativeProcTotalPss += myTotalPss;
18506
18507                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
18508                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
18509                        procMems.add(pssItem);
18510
18511                        nativePss += mi.nativePss;
18512                        nativeSwapPss += mi.nativeSwappedOutPss;
18513                        dalvikPss += mi.dalvikPss;
18514                        dalvikSwapPss += mi.dalvikSwappedOutPss;
18515                        for (int j=0; j<dalvikSubitemPss.length; j++) {
18516                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18517                            dalvikSubitemSwapPss[j] +=
18518                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18519                        }
18520                        otherPss += mi.otherPss;
18521                        otherSwapPss += mi.otherSwappedOutPss;
18522                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18523                            long mem = mi.getOtherPss(j);
18524                            miscPss[j] += mem;
18525                            otherPss -= mem;
18526                            mem = mi.getOtherSwappedOutPss(j);
18527                            miscSwapPss[j] += mem;
18528                            otherSwapPss -= mem;
18529                        }
18530                        oomPss[0] += myTotalPss;
18531                        oomSwapPss[0] += myTotalSwapPss;
18532                        if (oomProcs[0] == null) {
18533                            oomProcs[0] = new ArrayList<MemItem>();
18534                        }
18535                        oomProcs[0].add(pssItem);
18536                    }
18537                }
18538            }
18539
18540            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
18541
18542            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
18543            final int dalvikId = -2;
18544            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
18545            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
18546            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18547                String label = Debug.MemoryInfo.getOtherLabel(j);
18548                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
18549            }
18550            if (dalvikSubitemPss.length > 0) {
18551                // Add dalvik subitems.
18552                for (MemItem memItem : catMems) {
18553                    int memItemStart = 0, memItemEnd = 0;
18554                    if (memItem.id == dalvikId) {
18555                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
18556                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
18557                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
18558                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
18559                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
18560                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
18561                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
18562                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
18563                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
18564                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
18565                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
18566                    } else {
18567                        continue;  // No subitems, continue.
18568                    }
18569                    memItem.subitems = new ArrayList<MemItem>();
18570                    for (int j=memItemStart; j<=memItemEnd; j++) {
18571                        final String name = Debug.MemoryInfo.getOtherLabel(
18572                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
18573                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
18574                                dalvikSubitemSwapPss[j], j));
18575                    }
18576                }
18577            }
18578
18579            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
18580            for (int j=0; j<oomPss.length; j++) {
18581                if (oomPss[j] != 0) {
18582                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
18583                            : DUMP_MEM_OOM_LABEL[j];
18584                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
18585                            DUMP_MEM_OOM_ADJ[j]);
18586                    item.subitems = oomProcs[j];
18587                    oomMems.add(item);
18588                }
18589            }
18590
18591            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
18592            if (!brief && !opts.oomOnly && !opts.isCompact) {
18593                pw.println();
18594                pw.println("Total PSS by process:");
18595                dumpMemItems(pw, "  ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
18596                pw.println();
18597            }
18598            if (!opts.isCompact) {
18599                pw.println("Total PSS by OOM adjustment:");
18600            }
18601            dumpMemItems(pw, "  ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
18602            if (!brief && !opts.oomOnly) {
18603                PrintWriter out = categoryPw != null ? categoryPw : pw;
18604                if (!opts.isCompact) {
18605                    out.println();
18606                    out.println("Total PSS by category:");
18607                }
18608                dumpMemItems(out, "  ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
18609            }
18610            if (!opts.isCompact) {
18611                pw.println();
18612            }
18613            MemInfoReader memInfo = new MemInfoReader();
18614            memInfo.readMemInfo();
18615            if (nativeProcTotalPss > 0) {
18616                synchronized (this) {
18617                    final long cachedKb = memInfo.getCachedSizeKb();
18618                    final long freeKb = memInfo.getFreeSizeKb();
18619                    final long zramKb = memInfo.getZramTotalSizeKb();
18620                    final long kernelKb = memInfo.getKernelUsedSizeKb();
18621                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
18622                            kernelKb*1024, nativeProcTotalPss*1024);
18623                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
18624                            nativeProcTotalPss);
18625                }
18626            }
18627            if (!brief) {
18628                if (!opts.isCompact) {
18629                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
18630                    pw.print(" (status ");
18631                    switch (mLastMemoryLevel) {
18632                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
18633                            pw.println("normal)");
18634                            break;
18635                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
18636                            pw.println("moderate)");
18637                            break;
18638                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
18639                            pw.println("low)");
18640                            break;
18641                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18642                            pw.println("critical)");
18643                            break;
18644                        default:
18645                            pw.print(mLastMemoryLevel);
18646                            pw.println(")");
18647                            break;
18648                    }
18649                    pw.print(" Free RAM: ");
18650                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
18651                            + memInfo.getFreeSizeKb()));
18652                    pw.print(" (");
18653                    pw.print(stringifyKBSize(cachedPss));
18654                    pw.print(" cached pss + ");
18655                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
18656                    pw.print(" cached kernel + ");
18657                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
18658                    pw.println(" free)");
18659                } else {
18660                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
18661                    pw.print(cachedPss + memInfo.getCachedSizeKb()
18662                            + memInfo.getFreeSizeKb()); pw.print(",");
18663                    pw.println(totalPss - cachedPss);
18664                }
18665            }
18666            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
18667                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
18668                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
18669            if (!opts.isCompact) {
18670                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
18671                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
18672                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
18673                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
18674                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
18675            } else {
18676                pw.print("lostram,"); pw.println(lostRAM);
18677            }
18678            if (!brief) {
18679                if (memInfo.getZramTotalSizeKb() != 0) {
18680                    if (!opts.isCompact) {
18681                        pw.print("     ZRAM: ");
18682                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
18683                                pw.print(" physical used for ");
18684                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
18685                                        - memInfo.getSwapFreeSizeKb()));
18686                                pw.print(" in swap (");
18687                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
18688                                pw.println(" total swap)");
18689                    } else {
18690                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
18691                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
18692                                pw.println(memInfo.getSwapFreeSizeKb());
18693                    }
18694                }
18695                final long[] ksm = getKsmInfo();
18696                if (!opts.isCompact) {
18697                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
18698                            || ksm[KSM_VOLATILE] != 0) {
18699                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
18700                                pw.print(" saved from shared ");
18701                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
18702                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
18703                                pw.print(" unshared; ");
18704                                pw.print(stringifyKBSize(
18705                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
18706                    }
18707                    pw.print("   Tuning: ");
18708                    pw.print(ActivityManager.staticGetMemoryClass());
18709                    pw.print(" (large ");
18710                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18711                    pw.print("), oom ");
18712                    pw.print(stringifySize(
18713                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
18714                    pw.print(", restore limit ");
18715                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
18716                    if (ActivityManager.isLowRamDeviceStatic()) {
18717                        pw.print(" (low-ram)");
18718                    }
18719                    if (ActivityManager.isHighEndGfx()) {
18720                        pw.print(" (high-end-gfx)");
18721                    }
18722                    pw.println();
18723                } else {
18724                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
18725                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
18726                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
18727                    pw.print("tuning,");
18728                    pw.print(ActivityManager.staticGetMemoryClass());
18729                    pw.print(',');
18730                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18731                    pw.print(',');
18732                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
18733                    if (ActivityManager.isLowRamDeviceStatic()) {
18734                        pw.print(",low-ram");
18735                    }
18736                    if (ActivityManager.isHighEndGfx()) {
18737                        pw.print(",high-end-gfx");
18738                    }
18739                    pw.println();
18740                }
18741            }
18742        }
18743    }
18744
18745    private final void dumpApplicationMemoryUsage(FileDescriptor fd,
18746            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18747            ArrayList<ProcessRecord> procs) {
18748        final long uptimeMs = SystemClock.uptimeMillis();
18749        final long realtimeMs = SystemClock.elapsedRealtime();
18750        final long[] tmpLong = new long[1];
18751
18752        if (procs == null) {
18753            // No Java processes.  Maybe they want to print a native process.
18754            String proc = "N/A";
18755            if (innerArgs.length > 0) {
18756                proc = innerArgs[0];
18757                if (proc.charAt(0) != '-') {
18758                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18759                            = new ArrayList<ProcessCpuTracker.Stats>();
18760                    updateCpuStatsNow();
18761                    int findPid = -1;
18762                    try {
18763                        findPid = Integer.parseInt(innerArgs[0]);
18764                    } catch (NumberFormatException e) {
18765                    }
18766                    synchronized (mProcessCpuTracker) {
18767                        final int N = mProcessCpuTracker.countStats();
18768                        for (int i=0; i<N; i++) {
18769                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18770                            if (st.pid == findPid || (st.baseName != null
18771                                    && st.baseName.equals(innerArgs[0]))) {
18772                                nativeProcs.add(st);
18773                            }
18774                        }
18775                    }
18776                    if (nativeProcs.size() > 0) {
18777                        ProtoOutputStream proto = new ProtoOutputStream(fd);
18778
18779                        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
18780                        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
18781                        Debug.MemoryInfo mi = null;
18782                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18783                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18784                            final int pid = r.pid;
18785                            final long nToken = proto.start(MemInfoProto.NATIVE_PROCESSES);
18786
18787                            proto.write(MemInfoProto.ProcessMemory.PID, pid);
18788                            proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.baseName);
18789
18790                            if (mi == null) {
18791                                mi = new Debug.MemoryInfo();
18792                            }
18793                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18794                                Debug.getMemoryInfo(pid, mi);
18795                            } else {
18796                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18797                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18798                            }
18799                            ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
18800                                    opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
18801
18802                            proto.end(nToken);
18803                        }
18804
18805                        proto.flush();
18806                        return;
18807                    }
18808                }
18809            }
18810            Log.d(TAG, "No process found for: " + innerArgs[0]);
18811            return;
18812        }
18813
18814        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18815            opts.dumpDetails = true;
18816        }
18817
18818        ProtoOutputStream proto = new ProtoOutputStream(fd);
18819
18820        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
18821        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
18822
18823        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18824        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18825        long nativePss = 0;
18826        long nativeSwapPss = 0;
18827        long dalvikPss = 0;
18828        long dalvikSwapPss = 0;
18829        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18830                EmptyArray.LONG;
18831        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18832                EmptyArray.LONG;
18833        long otherPss = 0;
18834        long otherSwapPss = 0;
18835        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18836        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18837
18838        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18839        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18840        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18841                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18842
18843        long totalPss = 0;
18844        long totalSwapPss = 0;
18845        long cachedPss = 0;
18846        long cachedSwapPss = 0;
18847        boolean hasSwapPss = false;
18848
18849        Debug.MemoryInfo mi = null;
18850        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18851            final ProcessRecord r = procs.get(i);
18852            final IApplicationThread thread;
18853            final int pid;
18854            final int oomAdj;
18855            final boolean hasActivities;
18856            synchronized (this) {
18857                thread = r.thread;
18858                pid = r.pid;
18859                oomAdj = r.getSetAdjWithServices();
18860                hasActivities = r.activities.size() > 0;
18861            }
18862            if (thread == null) {
18863                continue;
18864            }
18865            if (mi == null) {
18866                mi = new Debug.MemoryInfo();
18867            }
18868            final int reportType;
18869            final long startTime;
18870            final long endTime;
18871            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18872                reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18873                startTime = SystemClock.currentThreadTimeMillis();
18874                Debug.getMemoryInfo(pid, mi);
18875                endTime = SystemClock.currentThreadTimeMillis();
18876                hasSwapPss = mi.hasSwappedOutPss;
18877            } else {
18878                reportType = ProcessStats.ADD_PSS_EXTERNAL;
18879                startTime = SystemClock.currentThreadTimeMillis();
18880                mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
18881                endTime = SystemClock.currentThreadTimeMillis();
18882                mi.dalvikPrivateDirty = (int) tmpLong[0];
18883            }
18884            if (opts.dumpDetails) {
18885                if (opts.localOnly) {
18886                    final long aToken = proto.start(MemInfoProto.APP_PROCESSES);
18887                    final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
18888                    proto.write(MemInfoProto.ProcessMemory.PID, pid);
18889                    proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.processName);
18890                    ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
18891                            opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
18892                    proto.end(mToken);
18893                    proto.end(aToken);
18894                } else {
18895                    try {
18896                        ByteTransferPipe tp = new ByteTransferPipe();
18897                        try {
18898                            thread.dumpMemInfoProto(tp.getWriteFd(),
18899                                mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18900                                opts.dumpUnreachable, innerArgs);
18901                            proto.write(MemInfoProto.APP_PROCESSES, tp.get());
18902                        } finally {
18903                            tp.kill();
18904                        }
18905                    } catch (IOException e) {
18906                        Log.e(TAG, "Got IOException!", e);
18907                    } catch (RemoteException e) {
18908                        Log.e(TAG, "Got RemoteException!", e);
18909                    }
18910                }
18911            }
18912
18913            final long myTotalPss = mi.getTotalPss();
18914            final long myTotalUss = mi.getTotalUss();
18915            final long myTotalRss = mi.getTotalRss();
18916            final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18917
18918            synchronized (this) {
18919                if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18920                    // Record this for posterity if the process has been stable.
18921                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
18922                            reportType, endTime-startTime, r.pkgList);
18923                }
18924            }
18925
18926            if (!opts.isCheckinRequest && mi != null) {
18927                totalPss += myTotalPss;
18928                totalSwapPss += myTotalSwapPss;
18929                MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
18930                        (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
18931                        myTotalSwapPss, pid, hasActivities);
18932                procMems.add(pssItem);
18933                procMemsMap.put(pid, pssItem);
18934
18935                nativePss += mi.nativePss;
18936                nativeSwapPss += mi.nativeSwappedOutPss;
18937                dalvikPss += mi.dalvikPss;
18938                dalvikSwapPss += mi.dalvikSwappedOutPss;
18939                for (int j=0; j<dalvikSubitemPss.length; j++) {
18940                    dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18941                    dalvikSubitemSwapPss[j] +=
18942                            mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18943                }
18944                otherPss += mi.otherPss;
18945                otherSwapPss += mi.otherSwappedOutPss;
18946                for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18947                    long mem = mi.getOtherPss(j);
18948                    miscPss[j] += mem;
18949                    otherPss -= mem;
18950                    mem = mi.getOtherSwappedOutPss(j);
18951                    miscSwapPss[j] += mem;
18952                    otherSwapPss -= mem;
18953                }
18954
18955                if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18956                    cachedPss += myTotalPss;
18957                    cachedSwapPss += myTotalSwapPss;
18958                }
18959
18960                for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
18961                    if (oomIndex == (oomPss.length - 1)
18962                            || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
18963                                    && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
18964                        oomPss[oomIndex] += myTotalPss;
18965                        oomSwapPss[oomIndex] += myTotalSwapPss;
18966                        if (oomProcs[oomIndex] == null) {
18967                            oomProcs[oomIndex] = new ArrayList<MemItem>();
18968                        }
18969                        oomProcs[oomIndex].add(pssItem);
18970                        break;
18971                    }
18972                }
18973            }
18974        }
18975
18976        long nativeProcTotalPss = 0;
18977
18978        if (procs.size() > 1 && !opts.packages) {
18979            // If we are showing aggregations, also look for native processes to
18980            // include so that our aggregations are more accurate.
18981            updateCpuStatsNow();
18982            mi = null;
18983            synchronized (mProcessCpuTracker) {
18984                final int N = mProcessCpuTracker.countStats();
18985                for (int i=0; i<N; i++) {
18986                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18987                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
18988                        if (mi == null) {
18989                            mi = new Debug.MemoryInfo();
18990                        }
18991                        if (!brief && !opts.oomOnly) {
18992                            Debug.getMemoryInfo(st.pid, mi);
18993                        } else {
18994                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
18995                            mi.nativePrivateDirty = (int)tmpLong[0];
18996                        }
18997
18998                        final long myTotalPss = mi.getTotalPss();
18999                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19000                        totalPss += myTotalPss;
19001                        nativeProcTotalPss += myTotalPss;
19002
19003                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19004                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19005                        procMems.add(pssItem);
19006
19007                        nativePss += mi.nativePss;
19008                        nativeSwapPss += mi.nativeSwappedOutPss;
19009                        dalvikPss += mi.dalvikPss;
19010                        dalvikSwapPss += mi.dalvikSwappedOutPss;
19011                        for (int j=0; j<dalvikSubitemPss.length; j++) {
19012                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19013                            dalvikSubitemSwapPss[j] +=
19014                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19015                        }
19016                        otherPss += mi.otherPss;
19017                        otherSwapPss += mi.otherSwappedOutPss;
19018                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19019                            long mem = mi.getOtherPss(j);
19020                            miscPss[j] += mem;
19021                            otherPss -= mem;
19022                            mem = mi.getOtherSwappedOutPss(j);
19023                            miscSwapPss[j] += mem;
19024                            otherSwapPss -= mem;
19025                        }
19026                        oomPss[0] += myTotalPss;
19027                        oomSwapPss[0] += myTotalSwapPss;
19028                        if (oomProcs[0] == null) {
19029                            oomProcs[0] = new ArrayList<MemItem>();
19030                        }
19031                        oomProcs[0].add(pssItem);
19032                    }
19033                }
19034            }
19035
19036            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19037
19038            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19039            final int dalvikId = -2;
19040            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19041            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19042            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19043                String label = Debug.MemoryInfo.getOtherLabel(j);
19044                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19045            }
19046            if (dalvikSubitemPss.length > 0) {
19047                // Add dalvik subitems.
19048                for (MemItem memItem : catMems) {
19049                    int memItemStart = 0, memItemEnd = 0;
19050                    if (memItem.id == dalvikId) {
19051                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19052                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19053                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19054                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19055                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19056                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19057                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19058                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19059                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19060                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19061                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19062                    } else {
19063                        continue;  // No subitems, continue.
19064                    }
19065                    memItem.subitems = new ArrayList<MemItem>();
19066                    for (int j=memItemStart; j<=memItemEnd; j++) {
19067                        final String name = Debug.MemoryInfo.getOtherLabel(
19068                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
19069                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19070                                dalvikSubitemSwapPss[j], j));
19071                    }
19072                }
19073            }
19074
19075            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19076            for (int j=0; j<oomPss.length; j++) {
19077                if (oomPss[j] != 0) {
19078                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19079                            : DUMP_MEM_OOM_LABEL[j];
19080                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19081                            DUMP_MEM_OOM_ADJ[j]);
19082                    item.subitems = oomProcs[j];
19083                    oomMems.add(item);
19084                }
19085            }
19086
19087            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19088            if (!opts.oomOnly) {
19089                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_PROCESS, "proc",
19090                        procMems, true, opts.dumpSwapPss);
19091            }
19092            dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
19093                    oomMems, false, opts.dumpSwapPss);
19094            if (!brief && !opts.oomOnly) {
19095                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_CATEGORY, "cat",
19096                        catMems, true, opts.dumpSwapPss);
19097            }
19098            MemInfoReader memInfo = new MemInfoReader();
19099            memInfo.readMemInfo();
19100            if (nativeProcTotalPss > 0) {
19101                synchronized (this) {
19102                    final long cachedKb = memInfo.getCachedSizeKb();
19103                    final long freeKb = memInfo.getFreeSizeKb();
19104                    final long zramKb = memInfo.getZramTotalSizeKb();
19105                    final long kernelKb = memInfo.getKernelUsedSizeKb();
19106                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19107                            kernelKb*1024, nativeProcTotalPss*1024);
19108                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19109                            nativeProcTotalPss);
19110                }
19111            }
19112            if (!brief) {
19113                proto.write(MemInfoProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
19114                proto.write(MemInfoProto.STATUS, mLastMemoryLevel);
19115                proto.write(MemInfoProto.CACHED_PSS_KB, cachedPss);
19116                proto.write(MemInfoProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
19117                proto.write(MemInfoProto.FREE_KB, memInfo.getFreeSizeKb());
19118            }
19119            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19120                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19121                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19122            proto.write(MemInfoProto.USED_PSS_KB, totalPss - cachedPss);
19123            proto.write(MemInfoProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
19124            proto.write(MemInfoProto.LOST_RAM_KB, lostRAM);
19125            if (!brief) {
19126                if (memInfo.getZramTotalSizeKb() != 0) {
19127                    proto.write(MemInfoProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
19128                    proto.write(MemInfoProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
19129                            memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
19130                    proto.write(MemInfoProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
19131                }
19132                final long[] ksm = getKsmInfo();
19133                proto.write(MemInfoProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
19134                proto.write(MemInfoProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
19135                proto.write(MemInfoProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
19136                proto.write(MemInfoProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
19137
19138                proto.write(MemInfoProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
19139                proto.write(MemInfoProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
19140                proto.write(MemInfoProto.OOM_KB,
19141                        mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
19142                proto.write(MemInfoProto.RESTORE_LIMIT_KB,
19143                        mProcessList.getCachedRestoreThresholdKb());
19144
19145                proto.write(MemInfoProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
19146                proto.write(MemInfoProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
19147            }
19148        }
19149
19150        proto.flush();
19151    }
19152
19153    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
19154            long memtrack, String name) {
19155        sb.append("  ");
19156        sb.append(ProcessList.makeOomAdjString(oomAdj));
19157        sb.append(' ');
19158        sb.append(ProcessList.makeProcStateString(procState));
19159        sb.append(' ');
19160        ProcessList.appendRamKb(sb, pss);
19161        sb.append(": ");
19162        sb.append(name);
19163        if (memtrack > 0) {
19164            sb.append(" (");
19165            sb.append(stringifyKBSize(memtrack));
19166            sb.append(" memtrack)");
19167        }
19168    }
19169
19170    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
19171        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
19172        sb.append(" (pid ");
19173        sb.append(mi.pid);
19174        sb.append(") ");
19175        sb.append(mi.adjType);
19176        sb.append('\n');
19177        if (mi.adjReason != null) {
19178            sb.append("                      ");
19179            sb.append(mi.adjReason);
19180            sb.append('\n');
19181        }
19182    }
19183
19184    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
19185        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
19186        for (int i=0, N=memInfos.size(); i<N; i++) {
19187            ProcessMemInfo mi = memInfos.get(i);
19188            infoMap.put(mi.pid, mi);
19189        }
19190        updateCpuStatsNow();
19191        long[] memtrackTmp = new long[1];
19192        final List<ProcessCpuTracker.Stats> stats;
19193        // Get a list of Stats that have vsize > 0
19194        synchronized (mProcessCpuTracker) {
19195            stats = mProcessCpuTracker.getStats((st) -> {
19196                return st.vsize > 0;
19197            });
19198        }
19199        final int statsCount = stats.size();
19200        for (int i = 0; i < statsCount; i++) {
19201            ProcessCpuTracker.Stats st = stats.get(i);
19202            long pss = Debug.getPss(st.pid, null, memtrackTmp);
19203            if (pss > 0) {
19204                if (infoMap.indexOfKey(st.pid) < 0) {
19205                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19206                            ProcessList.NATIVE_ADJ, -1, "native", null);
19207                    mi.pss = pss;
19208                    mi.memtrack = memtrackTmp[0];
19209                    memInfos.add(mi);
19210                }
19211            }
19212        }
19213
19214        long totalPss = 0;
19215        long totalMemtrack = 0;
19216        for (int i=0, N=memInfos.size(); i<N; i++) {
19217            ProcessMemInfo mi = memInfos.get(i);
19218            if (mi.pss == 0) {
19219                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19220                mi.memtrack = memtrackTmp[0];
19221            }
19222            totalPss += mi.pss;
19223            totalMemtrack += mi.memtrack;
19224        }
19225        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
19226            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
19227                if (lhs.oomAdj != rhs.oomAdj) {
19228                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
19229                }
19230                if (lhs.pss != rhs.pss) {
19231                    return lhs.pss < rhs.pss ? 1 : -1;
19232                }
19233                return 0;
19234            }
19235        });
19236
19237        StringBuilder tag = new StringBuilder(128);
19238        StringBuilder stack = new StringBuilder(128);
19239        tag.append("Low on memory -- ");
19240        appendMemBucket(tag, totalPss, "total", false);
19241        appendMemBucket(stack, totalPss, "total", true);
19242
19243        StringBuilder fullNativeBuilder = new StringBuilder(1024);
19244        StringBuilder shortNativeBuilder = new StringBuilder(1024);
19245        StringBuilder fullJavaBuilder = new StringBuilder(1024);
19246
19247        boolean firstLine = true;
19248        int lastOomAdj = Integer.MIN_VALUE;
19249        long extraNativeRam = 0;
19250        long extraNativeMemtrack = 0;
19251        long cachedPss = 0;
19252        for (int i=0, N=memInfos.size(); i<N; i++) {
19253            ProcessMemInfo mi = memInfos.get(i);
19254
19255            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19256                cachedPss += mi.pss;
19257            }
19258
19259            if (mi.oomAdj != ProcessList.NATIVE_ADJ
19260                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
19261                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
19262                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
19263                if (lastOomAdj != mi.oomAdj) {
19264                    lastOomAdj = mi.oomAdj;
19265                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19266                        tag.append(" / ");
19267                    }
19268                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19269                        if (firstLine) {
19270                            stack.append(":");
19271                            firstLine = false;
19272                        }
19273                        stack.append("\n\t at ");
19274                    } else {
19275                        stack.append("$");
19276                    }
19277                } else {
19278                    tag.append(" ");
19279                    stack.append("$");
19280                }
19281                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19282                    appendMemBucket(tag, mi.pss, mi.name, false);
19283                }
19284                appendMemBucket(stack, mi.pss, mi.name, true);
19285                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
19286                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
19287                    stack.append("(");
19288                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
19289                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
19290                            stack.append(DUMP_MEM_OOM_LABEL[k]);
19291                            stack.append(":");
19292                            stack.append(DUMP_MEM_OOM_ADJ[k]);
19293                        }
19294                    }
19295                    stack.append(")");
19296                }
19297            }
19298
19299            appendMemInfo(fullNativeBuilder, mi);
19300            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
19301                // The short form only has native processes that are >= 512K.
19302                if (mi.pss >= 512) {
19303                    appendMemInfo(shortNativeBuilder, mi);
19304                } else {
19305                    extraNativeRam += mi.pss;
19306                    extraNativeMemtrack += mi.memtrack;
19307                }
19308            } else {
19309                // Short form has all other details, but if we have collected RAM
19310                // from smaller native processes let's dump a summary of that.
19311                if (extraNativeRam > 0) {
19312                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
19313                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
19314                    shortNativeBuilder.append('\n');
19315                    extraNativeRam = 0;
19316                }
19317                appendMemInfo(fullJavaBuilder, mi);
19318            }
19319        }
19320
19321        fullJavaBuilder.append("           ");
19322        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
19323        fullJavaBuilder.append(": TOTAL");
19324        if (totalMemtrack > 0) {
19325            fullJavaBuilder.append(" (");
19326            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
19327            fullJavaBuilder.append(" memtrack)");
19328        } else {
19329        }
19330        fullJavaBuilder.append("\n");
19331
19332        MemInfoReader memInfo = new MemInfoReader();
19333        memInfo.readMemInfo();
19334        final long[] infos = memInfo.getRawInfo();
19335
19336        StringBuilder memInfoBuilder = new StringBuilder(1024);
19337        Debug.getMemInfo(infos);
19338        memInfoBuilder.append("  MemInfo: ");
19339        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
19340        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
19341        memInfoBuilder.append(stringifyKBSize(
19342                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
19343        memInfoBuilder.append(stringifyKBSize(
19344                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
19345        memInfoBuilder.append(stringifyKBSize(
19346                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
19347        memInfoBuilder.append("           ");
19348        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
19349        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
19350        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
19351        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
19352        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
19353            memInfoBuilder.append("  ZRAM: ");
19354            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
19355            memInfoBuilder.append(" RAM, ");
19356            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
19357            memInfoBuilder.append(" swap total, ");
19358            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
19359            memInfoBuilder.append(" swap free\n");
19360        }
19361        final long[] ksm = getKsmInfo();
19362        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19363                || ksm[KSM_VOLATILE] != 0) {
19364            memInfoBuilder.append("  KSM: ");
19365            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
19366            memInfoBuilder.append(" saved from shared ");
19367            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
19368            memInfoBuilder.append("\n       ");
19369            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
19370            memInfoBuilder.append(" unshared; ");
19371            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
19372            memInfoBuilder.append(" volatile\n");
19373        }
19374        memInfoBuilder.append("  Free RAM: ");
19375        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19376                + memInfo.getFreeSizeKb()));
19377        memInfoBuilder.append("\n");
19378        memInfoBuilder.append("  Used RAM: ");
19379        memInfoBuilder.append(stringifyKBSize(
19380                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
19381        memInfoBuilder.append("\n");
19382        memInfoBuilder.append("  Lost RAM: ");
19383        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
19384                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19385                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
19386        memInfoBuilder.append("\n");
19387        Slog.i(TAG, "Low on memory:");
19388        Slog.i(TAG, shortNativeBuilder.toString());
19389        Slog.i(TAG, fullJavaBuilder.toString());
19390        Slog.i(TAG, memInfoBuilder.toString());
19391
19392        StringBuilder dropBuilder = new StringBuilder(1024);
19393        /*
19394        StringWriter oomSw = new StringWriter();
19395        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
19396        StringWriter catSw = new StringWriter();
19397        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19398        String[] emptyArgs = new String[] { };
19399        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
19400        oomPw.flush();
19401        String oomString = oomSw.toString();
19402        */
19403        dropBuilder.append("Low on memory:");
19404        dropBuilder.append(stack);
19405        dropBuilder.append('\n');
19406        dropBuilder.append(fullNativeBuilder);
19407        dropBuilder.append(fullJavaBuilder);
19408        dropBuilder.append('\n');
19409        dropBuilder.append(memInfoBuilder);
19410        dropBuilder.append('\n');
19411        /*
19412        dropBuilder.append(oomString);
19413        dropBuilder.append('\n');
19414        */
19415        StringWriter catSw = new StringWriter();
19416        synchronized (ActivityManagerService.this) {
19417            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19418            String[] emptyArgs = new String[] { };
19419            catPw.println();
19420            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
19421            catPw.println();
19422            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
19423                    false, null).dumpLocked();
19424            catPw.println();
19425            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
19426            catPw.flush();
19427        }
19428        dropBuilder.append(catSw.toString());
19429        addErrorToDropBox("lowmem", null, "system_server", null,
19430                null, tag.toString(), dropBuilder.toString(), null, null);
19431        //Slog.i(TAG, "Sent to dropbox:");
19432        //Slog.i(TAG, dropBuilder.toString());
19433        synchronized (ActivityManagerService.this) {
19434            long now = SystemClock.uptimeMillis();
19435            if (mLastMemUsageReportTime < now) {
19436                mLastMemUsageReportTime = now;
19437            }
19438        }
19439    }
19440
19441    /**
19442     * Searches array of arguments for the specified string
19443     * @param args array of argument strings
19444     * @param value value to search for
19445     * @return true if the value is contained in the array
19446     */
19447    private static boolean scanArgs(String[] args, String value) {
19448        if (args != null) {
19449            for (String arg : args) {
19450                if (value.equals(arg)) {
19451                    return true;
19452                }
19453            }
19454        }
19455        return false;
19456    }
19457
19458    private final boolean removeDyingProviderLocked(ProcessRecord proc,
19459            ContentProviderRecord cpr, boolean always) {
19460        final boolean inLaunching = mLaunchingProviders.contains(cpr);
19461
19462        if (!inLaunching || always) {
19463            synchronized (cpr) {
19464                cpr.launchingApp = null;
19465                cpr.notifyAll();
19466            }
19467            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
19468            String names[] = cpr.info.authority.split(";");
19469            for (int j = 0; j < names.length; j++) {
19470                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
19471            }
19472        }
19473
19474        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
19475            ContentProviderConnection conn = cpr.connections.get(i);
19476            if (conn.waiting) {
19477                // If this connection is waiting for the provider, then we don't
19478                // need to mess with its process unless we are always removing
19479                // or for some reason the provider is not currently launching.
19480                if (inLaunching && !always) {
19481                    continue;
19482                }
19483            }
19484            ProcessRecord capp = conn.client;
19485            conn.dead = true;
19486            if (conn.stableCount > 0) {
19487                if (!capp.persistent && capp.thread != null
19488                        && capp.pid != 0
19489                        && capp.pid != MY_PID) {
19490                    capp.kill("depends on provider "
19491                            + cpr.name.flattenToShortString()
19492                            + " in dying proc " + (proc != null ? proc.processName : "??")
19493                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
19494                }
19495            } else if (capp.thread != null && conn.provider.provider != null) {
19496                try {
19497                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
19498                } catch (RemoteException e) {
19499                }
19500                // In the protocol here, we don't expect the client to correctly
19501                // clean up this connection, we'll just remove it.
19502                cpr.connections.remove(i);
19503                if (conn.client.conProviders.remove(conn)) {
19504                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
19505                }
19506            }
19507        }
19508
19509        if (inLaunching && always) {
19510            mLaunchingProviders.remove(cpr);
19511        }
19512        return inLaunching;
19513    }
19514
19515    /**
19516     * Main code for cleaning up a process when it has gone away.  This is
19517     * called both as a result of the process dying, or directly when stopping
19518     * a process when running in single process mode.
19519     *
19520     * @return Returns true if the given process has been restarted, so the
19521     * app that was passed in must remain on the process lists.
19522     */
19523    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
19524            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
19525        if (index >= 0) {
19526            removeLruProcessLocked(app);
19527            ProcessList.remove(app.pid);
19528        }
19529
19530        mProcessesToGc.remove(app);
19531        mPendingPssProcesses.remove(app);
19532
19533        // Dismiss any open dialogs.
19534        if (app.crashDialog != null && !app.forceCrashReport) {
19535            app.crashDialog.dismiss();
19536            app.crashDialog = null;
19537        }
19538        if (app.anrDialog != null) {
19539            app.anrDialog.dismiss();
19540            app.anrDialog = null;
19541        }
19542        if (app.waitDialog != null) {
19543            app.waitDialog.dismiss();
19544            app.waitDialog = null;
19545        }
19546
19547        app.crashing = false;
19548        app.notResponding = false;
19549
19550        app.resetPackageList(mProcessStats);
19551        app.unlinkDeathRecipient();
19552        app.makeInactive(mProcessStats);
19553        app.waitingToKill = null;
19554        app.forcingToImportant = null;
19555        updateProcessForegroundLocked(app, false, false);
19556        app.foregroundActivities = false;
19557        app.hasShownUi = false;
19558        app.treatLikeActivity = false;
19559        app.hasAboveClient = false;
19560        app.hasClientActivities = false;
19561
19562        mServices.killServicesLocked(app, allowRestart);
19563
19564        boolean restart = false;
19565
19566        // Remove published content providers.
19567        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
19568            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
19569            final boolean always = app.bad || !allowRestart;
19570            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
19571            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
19572                // We left the provider in the launching list, need to
19573                // restart it.
19574                restart = true;
19575            }
19576
19577            cpr.provider = null;
19578            cpr.proc = null;
19579        }
19580        app.pubProviders.clear();
19581
19582        // Take care of any launching providers waiting for this process.
19583        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
19584            restart = true;
19585        }
19586
19587        // Unregister from connected content providers.
19588        if (!app.conProviders.isEmpty()) {
19589            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
19590                ContentProviderConnection conn = app.conProviders.get(i);
19591                conn.provider.connections.remove(conn);
19592                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
19593                        conn.provider.name);
19594            }
19595            app.conProviders.clear();
19596        }
19597
19598        // At this point there may be remaining entries in mLaunchingProviders
19599        // where we were the only one waiting, so they are no longer of use.
19600        // Look for these and clean up if found.
19601        // XXX Commented out for now.  Trying to figure out a way to reproduce
19602        // the actual situation to identify what is actually going on.
19603        if (false) {
19604            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19605                ContentProviderRecord cpr = mLaunchingProviders.get(i);
19606                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
19607                    synchronized (cpr) {
19608                        cpr.launchingApp = null;
19609                        cpr.notifyAll();
19610                    }
19611                }
19612            }
19613        }
19614
19615        skipCurrentReceiverLocked(app);
19616
19617        // Unregister any receivers.
19618        for (int i = app.receivers.size() - 1; i >= 0; i--) {
19619            removeReceiverLocked(app.receivers.valueAt(i));
19620        }
19621        app.receivers.clear();
19622
19623        // If the app is undergoing backup, tell the backup manager about it
19624        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
19625            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
19626                    + mBackupTarget.appInfo + " died during backup");
19627            mHandler.post(new Runnable() {
19628                @Override
19629                public void run(){
19630                    try {
19631                        IBackupManager bm = IBackupManager.Stub.asInterface(
19632                                ServiceManager.getService(Context.BACKUP_SERVICE));
19633                        bm.agentDisconnected(app.info.packageName);
19634                    } catch (RemoteException e) {
19635                        // can't happen; backup manager is local
19636                    }
19637                }
19638            });
19639        }
19640
19641        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
19642            ProcessChangeItem item = mPendingProcessChanges.get(i);
19643            if (app.pid > 0 && item.pid == app.pid) {
19644                mPendingProcessChanges.remove(i);
19645                mAvailProcessChanges.add(item);
19646            }
19647        }
19648        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
19649                null).sendToTarget();
19650
19651        // If the caller is restarting this app, then leave it in its
19652        // current lists and let the caller take care of it.
19653        if (restarting) {
19654            return false;
19655        }
19656
19657        if (!app.persistent || app.isolated) {
19658            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
19659                    "Removing non-persistent process during cleanup: " + app);
19660            if (!replacingPid) {
19661                removeProcessNameLocked(app.processName, app.uid, app);
19662            }
19663            if (mHeavyWeightProcess == app) {
19664                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
19665                        mHeavyWeightProcess.userId, 0));
19666                mHeavyWeightProcess = null;
19667            }
19668        } else if (!app.removed) {
19669            // This app is persistent, so we need to keep its record around.
19670            // If it is not already on the pending app list, add it there
19671            // and start a new process for it.
19672            if (mPersistentStartingProcesses.indexOf(app) < 0) {
19673                mPersistentStartingProcesses.add(app);
19674                restart = true;
19675            }
19676        }
19677        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
19678                TAG_CLEANUP, "Clean-up removing on hold: " + app);
19679        mProcessesOnHold.remove(app);
19680
19681        if (app == mHomeProcess) {
19682            mHomeProcess = null;
19683        }
19684        if (app == mPreviousProcess) {
19685            mPreviousProcess = null;
19686        }
19687
19688        if (restart && !app.isolated) {
19689            // We have components that still need to be running in the
19690            // process, so re-launch it.
19691            if (index < 0) {
19692                ProcessList.remove(app.pid);
19693            }
19694            addProcessNameLocked(app);
19695            app.pendingStart = false;
19696            startProcessLocked(app, "restart", app.processName);
19697            return true;
19698        } else if (app.pid > 0 && app.pid != MY_PID) {
19699            // Goodbye!
19700            boolean removed;
19701            synchronized (mPidsSelfLocked) {
19702                mPidsSelfLocked.remove(app.pid);
19703                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
19704            }
19705            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
19706            if (app.isolated) {
19707                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
19708            }
19709            app.setPid(0);
19710        }
19711        return false;
19712    }
19713
19714    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
19715        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19716            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19717            if (cpr.launchingApp == app) {
19718                return true;
19719            }
19720        }
19721        return false;
19722    }
19723
19724    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
19725        // Look through the content providers we are waiting to have launched,
19726        // and if any run in this process then either schedule a restart of
19727        // the process or kill the client waiting for it if this process has
19728        // gone bad.
19729        boolean restart = false;
19730        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19731            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19732            if (cpr.launchingApp == app) {
19733                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
19734                    restart = true;
19735                } else {
19736                    removeDyingProviderLocked(app, cpr, true);
19737                }
19738            }
19739        }
19740        return restart;
19741    }
19742
19743    // =========================================================
19744    // SERVICES
19745    // =========================================================
19746
19747    @Override
19748    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
19749        enforceNotIsolatedCaller("getServices");
19750
19751        final int callingUid = Binder.getCallingUid();
19752        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
19753            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
19754        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
19755            callingUid);
19756        synchronized (this) {
19757            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
19758                allowed, canInteractAcrossUsers);
19759        }
19760    }
19761
19762    @Override
19763    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
19764        enforceNotIsolatedCaller("getRunningServiceControlPanel");
19765        synchronized (this) {
19766            return mServices.getRunningServiceControlPanelLocked(name);
19767        }
19768    }
19769
19770    @Override
19771    public ComponentName startService(IApplicationThread caller, Intent service,
19772            String resolvedType, boolean requireForeground, String callingPackage, int userId)
19773            throws TransactionTooLargeException {
19774        enforceNotIsolatedCaller("startService");
19775        // Refuse possible leaked file descriptors
19776        if (service != null && service.hasFileDescriptors() == true) {
19777            throw new IllegalArgumentException("File descriptors passed in Intent");
19778        }
19779
19780        if (callingPackage == null) {
19781            throw new IllegalArgumentException("callingPackage cannot be null");
19782        }
19783
19784        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
19785                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
19786        synchronized(this) {
19787            final int callingPid = Binder.getCallingPid();
19788            final int callingUid = Binder.getCallingUid();
19789            final long origId = Binder.clearCallingIdentity();
19790            ComponentName res;
19791            try {
19792                res = mServices.startServiceLocked(caller, service,
19793                        resolvedType, callingPid, callingUid,
19794                        requireForeground, callingPackage, userId);
19795            } finally {
19796                Binder.restoreCallingIdentity(origId);
19797            }
19798            return res;
19799        }
19800    }
19801
19802    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
19803            boolean fgRequired, String callingPackage, int userId)
19804            throws TransactionTooLargeException {
19805        synchronized(this) {
19806            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
19807                    "startServiceInPackage: " + service + " type=" + resolvedType);
19808            final long origId = Binder.clearCallingIdentity();
19809            ComponentName res;
19810            try {
19811                res = mServices.startServiceLocked(null, service,
19812                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
19813            } finally {
19814                Binder.restoreCallingIdentity(origId);
19815            }
19816            return res;
19817        }
19818    }
19819
19820    @Override
19821    public int stopService(IApplicationThread caller, Intent service,
19822            String resolvedType, int userId) {
19823        enforceNotIsolatedCaller("stopService");
19824        // Refuse possible leaked file descriptors
19825        if (service != null && service.hasFileDescriptors() == true) {
19826            throw new IllegalArgumentException("File descriptors passed in Intent");
19827        }
19828
19829        synchronized(this) {
19830            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
19831        }
19832    }
19833
19834    @Override
19835    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
19836        enforceNotIsolatedCaller("peekService");
19837        // Refuse possible leaked file descriptors
19838        if (service != null && service.hasFileDescriptors() == true) {
19839            throw new IllegalArgumentException("File descriptors passed in Intent");
19840        }
19841
19842        if (callingPackage == null) {
19843            throw new IllegalArgumentException("callingPackage cannot be null");
19844        }
19845
19846        synchronized(this) {
19847            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
19848        }
19849    }
19850
19851    @Override
19852    public boolean stopServiceToken(ComponentName className, IBinder token,
19853            int startId) {
19854        synchronized(this) {
19855            return mServices.stopServiceTokenLocked(className, token, startId);
19856        }
19857    }
19858
19859    @Override
19860    public void setServiceForeground(ComponentName className, IBinder token,
19861            int id, Notification notification, int flags) {
19862        synchronized(this) {
19863            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
19864        }
19865    }
19866
19867    @Override
19868    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
19869            boolean requireFull, String name, String callerPackage) {
19870        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
19871                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
19872    }
19873
19874    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
19875            String className, int flags) {
19876        boolean result = false;
19877        // For apps that don't have pre-defined UIDs, check for permission
19878        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
19879            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
19880                if (ActivityManager.checkUidPermission(
19881                        INTERACT_ACROSS_USERS,
19882                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
19883                    ComponentName comp = new ComponentName(aInfo.packageName, className);
19884                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
19885                            + " requests FLAG_SINGLE_USER, but app does not hold "
19886                            + INTERACT_ACROSS_USERS;
19887                    Slog.w(TAG, msg);
19888                    throw new SecurityException(msg);
19889                }
19890                // Permission passed
19891                result = true;
19892            }
19893        } else if ("system".equals(componentProcessName)) {
19894            result = true;
19895        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
19896            // Phone app and persistent apps are allowed to export singleuser providers.
19897            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
19898                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
19899        }
19900        if (DEBUG_MU) Slog.v(TAG_MU,
19901                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
19902                + Integer.toHexString(flags) + ") = " + result);
19903        return result;
19904    }
19905
19906    /**
19907     * Checks to see if the caller is in the same app as the singleton
19908     * component, or the component is in a special app. It allows special apps
19909     * to export singleton components but prevents exporting singleton
19910     * components for regular apps.
19911     */
19912    boolean isValidSingletonCall(int callingUid, int componentUid) {
19913        int componentAppId = UserHandle.getAppId(componentUid);
19914        return UserHandle.isSameApp(callingUid, componentUid)
19915                || componentAppId == SYSTEM_UID
19916                || componentAppId == PHONE_UID
19917                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
19918                        == PackageManager.PERMISSION_GRANTED;
19919    }
19920
19921    public int bindService(IApplicationThread caller, IBinder token, Intent service,
19922            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
19923            int userId) throws TransactionTooLargeException {
19924        enforceNotIsolatedCaller("bindService");
19925
19926        // Refuse possible leaked file descriptors
19927        if (service != null && service.hasFileDescriptors() == true) {
19928            throw new IllegalArgumentException("File descriptors passed in Intent");
19929        }
19930
19931        if (callingPackage == null) {
19932            throw new IllegalArgumentException("callingPackage cannot be null");
19933        }
19934
19935        synchronized(this) {
19936            return mServices.bindServiceLocked(caller, token, service,
19937                    resolvedType, connection, flags, callingPackage, userId);
19938        }
19939    }
19940
19941    public boolean unbindService(IServiceConnection connection) {
19942        synchronized (this) {
19943            return mServices.unbindServiceLocked(connection);
19944        }
19945    }
19946
19947    public void publishService(IBinder token, Intent intent, IBinder service) {
19948        // Refuse possible leaked file descriptors
19949        if (intent != null && intent.hasFileDescriptors() == true) {
19950            throw new IllegalArgumentException("File descriptors passed in Intent");
19951        }
19952
19953        synchronized(this) {
19954            if (!(token instanceof ServiceRecord)) {
19955                throw new IllegalArgumentException("Invalid service token");
19956            }
19957            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
19958        }
19959    }
19960
19961    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
19962        // Refuse possible leaked file descriptors
19963        if (intent != null && intent.hasFileDescriptors() == true) {
19964            throw new IllegalArgumentException("File descriptors passed in Intent");
19965        }
19966
19967        synchronized(this) {
19968            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
19969        }
19970    }
19971
19972    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
19973        synchronized(this) {
19974            if (!(token instanceof ServiceRecord)) {
19975                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
19976                throw new IllegalArgumentException("Invalid service token");
19977            }
19978            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
19979        }
19980    }
19981
19982    // =========================================================
19983    // BACKUP AND RESTORE
19984    // =========================================================
19985
19986    // Cause the target app to be launched if necessary and its backup agent
19987    // instantiated.  The backup agent will invoke backupAgentCreated() on the
19988    // activity manager to announce its creation.
19989    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
19990        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
19991        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
19992
19993        IPackageManager pm = AppGlobals.getPackageManager();
19994        ApplicationInfo app = null;
19995        try {
19996            app = pm.getApplicationInfo(packageName, 0, userId);
19997        } catch (RemoteException e) {
19998            // can't happen; package manager is process-local
19999        }
20000        if (app == null) {
20001            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
20002            return false;
20003        }
20004
20005        int oldBackupUid;
20006        int newBackupUid;
20007
20008        synchronized(this) {
20009            // !!! TODO: currently no check here that we're already bound
20010            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
20011            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20012            synchronized (stats) {
20013                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
20014            }
20015
20016            // Backup agent is now in use, its package can't be stopped.
20017            try {
20018                AppGlobals.getPackageManager().setPackageStoppedState(
20019                        app.packageName, false, UserHandle.getUserId(app.uid));
20020            } catch (RemoteException e) {
20021            } catch (IllegalArgumentException e) {
20022                Slog.w(TAG, "Failed trying to unstop package "
20023                        + app.packageName + ": " + e);
20024            }
20025
20026            BackupRecord r = new BackupRecord(ss, app, backupMode);
20027            ComponentName hostingName =
20028                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
20029                            ? new ComponentName(app.packageName, app.backupAgentName)
20030                            : new ComponentName("android", "FullBackupAgent");
20031            // startProcessLocked() returns existing proc's record if it's already running
20032            ProcessRecord proc = startProcessLocked(app.processName, app,
20033                    false, 0, "backup", hostingName, false, false, false);
20034            if (proc == null) {
20035                Slog.e(TAG, "Unable to start backup agent process " + r);
20036                return false;
20037            }
20038
20039            // If the app is a regular app (uid >= 10000) and not the system server or phone
20040            // process, etc, then mark it as being in full backup so that certain calls to the
20041            // process can be blocked. This is not reset to false anywhere because we kill the
20042            // process after the full backup is done and the ProcessRecord will vaporize anyway.
20043            if (UserHandle.isApp(app.uid) &&
20044                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
20045                proc.inFullBackup = true;
20046            }
20047            r.app = proc;
20048            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20049            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
20050            mBackupTarget = r;
20051            mBackupAppName = app.packageName;
20052
20053            // Try not to kill the process during backup
20054            updateOomAdjLocked(proc, true);
20055
20056            // If the process is already attached, schedule the creation of the backup agent now.
20057            // If it is not yet live, this will be done when it attaches to the framework.
20058            if (proc.thread != null) {
20059                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
20060                try {
20061                    proc.thread.scheduleCreateBackupAgent(app,
20062                            compatibilityInfoForPackageLocked(app), backupMode);
20063                } catch (RemoteException e) {
20064                    // Will time out on the backup manager side
20065                }
20066            } else {
20067                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
20068            }
20069            // Invariants: at this point, the target app process exists and the application
20070            // is either already running or in the process of coming up.  mBackupTarget and
20071            // mBackupAppName describe the app, so that when it binds back to the AM we
20072            // know that it's scheduled for a backup-agent operation.
20073        }
20074
20075        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20076        if (oldBackupUid != -1) {
20077            js.removeBackingUpUid(oldBackupUid);
20078        }
20079        if (newBackupUid != -1) {
20080            js.addBackingUpUid(newBackupUid);
20081        }
20082
20083        return true;
20084    }
20085
20086    @Override
20087    public void clearPendingBackup() {
20088        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
20089        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
20090
20091        synchronized (this) {
20092            mBackupTarget = null;
20093            mBackupAppName = null;
20094        }
20095
20096        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20097        js.clearAllBackingUpUids();
20098    }
20099
20100    // A backup agent has just come up
20101    public void backupAgentCreated(String agentPackageName, IBinder agent) {
20102        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
20103                + " = " + agent);
20104
20105        synchronized(this) {
20106            if (!agentPackageName.equals(mBackupAppName)) {
20107                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
20108                return;
20109            }
20110        }
20111
20112        long oldIdent = Binder.clearCallingIdentity();
20113        try {
20114            IBackupManager bm = IBackupManager.Stub.asInterface(
20115                    ServiceManager.getService(Context.BACKUP_SERVICE));
20116            bm.agentConnected(agentPackageName, agent);
20117        } catch (RemoteException e) {
20118            // can't happen; the backup manager service is local
20119        } catch (Exception e) {
20120            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
20121            e.printStackTrace();
20122        } finally {
20123            Binder.restoreCallingIdentity(oldIdent);
20124        }
20125    }
20126
20127    // done with this agent
20128    public void unbindBackupAgent(ApplicationInfo appInfo) {
20129        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
20130        if (appInfo == null) {
20131            Slog.w(TAG, "unbind backup agent for null app");
20132            return;
20133        }
20134
20135        int oldBackupUid;
20136
20137        synchronized(this) {
20138            try {
20139                if (mBackupAppName == null) {
20140                    Slog.w(TAG, "Unbinding backup agent with no active backup");
20141                    return;
20142                }
20143
20144                if (!mBackupAppName.equals(appInfo.packageName)) {
20145                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
20146                    return;
20147                }
20148
20149                // Not backing this app up any more; reset its OOM adjustment
20150                final ProcessRecord proc = mBackupTarget.app;
20151                updateOomAdjLocked(proc, true);
20152                proc.inFullBackup = false;
20153
20154                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20155
20156                // If the app crashed during backup, 'thread' will be null here
20157                if (proc.thread != null) {
20158                    try {
20159                        proc.thread.scheduleDestroyBackupAgent(appInfo,
20160                                compatibilityInfoForPackageLocked(appInfo));
20161                    } catch (Exception e) {
20162                        Slog.e(TAG, "Exception when unbinding backup agent:");
20163                        e.printStackTrace();
20164                    }
20165                }
20166            } finally {
20167                mBackupTarget = null;
20168                mBackupAppName = null;
20169            }
20170        }
20171
20172        if (oldBackupUid != -1) {
20173            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20174            js.removeBackingUpUid(oldBackupUid);
20175        }
20176    }
20177
20178    // =========================================================
20179    // BROADCASTS
20180    // =========================================================
20181
20182    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
20183        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
20184            return false;
20185        }
20186        // Easy case -- we have the app's ProcessRecord.
20187        if (record != null) {
20188            return record.info.isInstantApp();
20189        }
20190        // Otherwise check with PackageManager.
20191        if (callerPackage == null) {
20192            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
20193            throw new IllegalArgumentException("Calling application did not provide package name");
20194        }
20195        mAppOpsService.checkPackage(uid, callerPackage);
20196        try {
20197            IPackageManager pm = AppGlobals.getPackageManager();
20198            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
20199        } catch (RemoteException e) {
20200            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
20201            return true;
20202        }
20203    }
20204
20205    boolean isPendingBroadcastProcessLocked(int pid) {
20206        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20207                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
20208    }
20209
20210    void skipPendingBroadcastLocked(int pid) {
20211            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
20212            for (BroadcastQueue queue : mBroadcastQueues) {
20213                queue.skipPendingBroadcastLocked(pid);
20214            }
20215    }
20216
20217    // The app just attached; send any pending broadcasts that it should receive
20218    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
20219        boolean didSomething = false;
20220        for (BroadcastQueue queue : mBroadcastQueues) {
20221            didSomething |= queue.sendPendingBroadcastsLocked(app);
20222        }
20223        return didSomething;
20224    }
20225
20226    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20227            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
20228            int flags) {
20229        enforceNotIsolatedCaller("registerReceiver");
20230        ArrayList<Intent> stickyIntents = null;
20231        ProcessRecord callerApp = null;
20232        final boolean visibleToInstantApps
20233                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
20234        int callingUid;
20235        int callingPid;
20236        boolean instantApp;
20237        synchronized(this) {
20238            if (caller != null) {
20239                callerApp = getRecordForAppLocked(caller);
20240                if (callerApp == null) {
20241                    throw new SecurityException(
20242                            "Unable to find app for caller " + caller
20243                            + " (pid=" + Binder.getCallingPid()
20244                            + ") when registering receiver " + receiver);
20245                }
20246                if (callerApp.info.uid != SYSTEM_UID &&
20247                        !callerApp.pkgList.containsKey(callerPackage) &&
20248                        !"android".equals(callerPackage)) {
20249                    throw new SecurityException("Given caller package " + callerPackage
20250                            + " is not running in process " + callerApp);
20251                }
20252                callingUid = callerApp.info.uid;
20253                callingPid = callerApp.pid;
20254            } else {
20255                callerPackage = null;
20256                callingUid = Binder.getCallingUid();
20257                callingPid = Binder.getCallingPid();
20258            }
20259
20260            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20261            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20262                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
20263
20264            Iterator<String> actions = filter.actionsIterator();
20265            if (actions == null) {
20266                ArrayList<String> noAction = new ArrayList<String>(1);
20267                noAction.add(null);
20268                actions = noAction.iterator();
20269            }
20270
20271            // Collect stickies of users
20272            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
20273            while (actions.hasNext()) {
20274                String action = actions.next();
20275                for (int id : userIds) {
20276                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
20277                    if (stickies != null) {
20278                        ArrayList<Intent> intents = stickies.get(action);
20279                        if (intents != null) {
20280                            if (stickyIntents == null) {
20281                                stickyIntents = new ArrayList<Intent>();
20282                            }
20283                            stickyIntents.addAll(intents);
20284                        }
20285                    }
20286                }
20287            }
20288        }
20289
20290        ArrayList<Intent> allSticky = null;
20291        if (stickyIntents != null) {
20292            final ContentResolver resolver = mContext.getContentResolver();
20293            // Look for any matching sticky broadcasts...
20294            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
20295                Intent intent = stickyIntents.get(i);
20296                // Don't provided intents that aren't available to instant apps.
20297                if (instantApp &&
20298                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
20299                    continue;
20300                }
20301                // If intent has scheme "content", it will need to acccess
20302                // provider that needs to lock mProviderMap in ActivityThread
20303                // and also it may need to wait application response, so we
20304                // cannot lock ActivityManagerService here.
20305                if (filter.match(resolver, intent, true, TAG) >= 0) {
20306                    if (allSticky == null) {
20307                        allSticky = new ArrayList<Intent>();
20308                    }
20309                    allSticky.add(intent);
20310                }
20311            }
20312        }
20313
20314        // The first sticky in the list is returned directly back to the client.
20315        Intent sticky = allSticky != null ? allSticky.get(0) : null;
20316        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
20317        if (receiver == null) {
20318            return sticky;
20319        }
20320
20321        synchronized (this) {
20322            if (callerApp != null && (callerApp.thread == null
20323                    || callerApp.thread.asBinder() != caller.asBinder())) {
20324                // Original caller already died
20325                return null;
20326            }
20327            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20328            if (rl == null) {
20329                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
20330                        userId, receiver);
20331                if (rl.app != null) {
20332                    rl.app.receivers.add(rl);
20333                } else {
20334                    try {
20335                        receiver.asBinder().linkToDeath(rl, 0);
20336                    } catch (RemoteException e) {
20337                        return sticky;
20338                    }
20339                    rl.linkedToDeath = true;
20340                }
20341                mRegisteredReceivers.put(receiver.asBinder(), rl);
20342            } else if (rl.uid != callingUid) {
20343                throw new IllegalArgumentException(
20344                        "Receiver requested to register for uid " + callingUid
20345                        + " was previously registered for uid " + rl.uid
20346                        + " callerPackage is " + callerPackage);
20347            } else if (rl.pid != callingPid) {
20348                throw new IllegalArgumentException(
20349                        "Receiver requested to register for pid " + callingPid
20350                        + " was previously registered for pid " + rl.pid
20351                        + " callerPackage is " + callerPackage);
20352            } else if (rl.userId != userId) {
20353                throw new IllegalArgumentException(
20354                        "Receiver requested to register for user " + userId
20355                        + " was previously registered for user " + rl.userId
20356                        + " callerPackage is " + callerPackage);
20357            }
20358            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
20359                    permission, callingUid, userId, instantApp, visibleToInstantApps);
20360            rl.add(bf);
20361            if (!bf.debugCheck()) {
20362                Slog.w(TAG, "==> For Dynamic broadcast");
20363            }
20364            mReceiverResolver.addFilter(bf);
20365
20366            // Enqueue broadcasts for all existing stickies that match
20367            // this filter.
20368            if (allSticky != null) {
20369                ArrayList receivers = new ArrayList();
20370                receivers.add(bf);
20371
20372                final int stickyCount = allSticky.size();
20373                for (int i = 0; i < stickyCount; i++) {
20374                    Intent intent = allSticky.get(i);
20375                    BroadcastQueue queue = broadcastQueueForIntent(intent);
20376                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
20377                            null, -1, -1, false, null, null, OP_NONE, null, receivers,
20378                            null, 0, null, null, false, true, true, -1);
20379                    queue.enqueueParallelBroadcastLocked(r);
20380                    queue.scheduleBroadcastsLocked();
20381                }
20382            }
20383
20384            return sticky;
20385        }
20386    }
20387
20388    public void unregisterReceiver(IIntentReceiver receiver) {
20389        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
20390
20391        final long origId = Binder.clearCallingIdentity();
20392        try {
20393            boolean doTrim = false;
20394
20395            synchronized(this) {
20396                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20397                if (rl != null) {
20398                    final BroadcastRecord r = rl.curBroadcast;
20399                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
20400                        final boolean doNext = r.queue.finishReceiverLocked(
20401                                r, r.resultCode, r.resultData, r.resultExtras,
20402                                r.resultAbort, false);
20403                        if (doNext) {
20404                            doTrim = true;
20405                            r.queue.processNextBroadcast(false);
20406                        }
20407                    }
20408
20409                    if (rl.app != null) {
20410                        rl.app.receivers.remove(rl);
20411                    }
20412                    removeReceiverLocked(rl);
20413                    if (rl.linkedToDeath) {
20414                        rl.linkedToDeath = false;
20415                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
20416                    }
20417                }
20418            }
20419
20420            // If we actually concluded any broadcasts, we might now be able
20421            // to trim the recipients' apps from our working set
20422            if (doTrim) {
20423                trimApplications();
20424                return;
20425            }
20426
20427        } finally {
20428            Binder.restoreCallingIdentity(origId);
20429        }
20430    }
20431
20432    void removeReceiverLocked(ReceiverList rl) {
20433        mRegisteredReceivers.remove(rl.receiver.asBinder());
20434        for (int i = rl.size() - 1; i >= 0; i--) {
20435            mReceiverResolver.removeFilter(rl.get(i));
20436        }
20437    }
20438
20439    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
20440        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20441            ProcessRecord r = mLruProcesses.get(i);
20442            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
20443                try {
20444                    r.thread.dispatchPackageBroadcast(cmd, packages);
20445                } catch (RemoteException ex) {
20446                }
20447            }
20448        }
20449    }
20450
20451    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
20452            int callingUid, int[] users) {
20453        // TODO: come back and remove this assumption to triage all broadcasts
20454        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
20455
20456        List<ResolveInfo> receivers = null;
20457        try {
20458            HashSet<ComponentName> singleUserReceivers = null;
20459            boolean scannedFirstReceivers = false;
20460            for (int user : users) {
20461                // Skip users that have Shell restrictions, with exception of always permitted
20462                // Shell broadcasts
20463                if (callingUid == SHELL_UID
20464                        && mUserController.hasUserRestriction(
20465                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
20466                        && !isPermittedShellBroadcast(intent)) {
20467                    continue;
20468                }
20469                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
20470                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
20471                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
20472                    // If this is not the system user, we need to check for
20473                    // any receivers that should be filtered out.
20474                    for (int i=0; i<newReceivers.size(); i++) {
20475                        ResolveInfo ri = newReceivers.get(i);
20476                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
20477                            newReceivers.remove(i);
20478                            i--;
20479                        }
20480                    }
20481                }
20482                if (newReceivers != null && newReceivers.size() == 0) {
20483                    newReceivers = null;
20484                }
20485                if (receivers == null) {
20486                    receivers = newReceivers;
20487                } else if (newReceivers != null) {
20488                    // We need to concatenate the additional receivers
20489                    // found with what we have do far.  This would be easy,
20490                    // but we also need to de-dup any receivers that are
20491                    // singleUser.
20492                    if (!scannedFirstReceivers) {
20493                        // Collect any single user receivers we had already retrieved.
20494                        scannedFirstReceivers = true;
20495                        for (int i=0; i<receivers.size(); i++) {
20496                            ResolveInfo ri = receivers.get(i);
20497                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20498                                ComponentName cn = new ComponentName(
20499                                        ri.activityInfo.packageName, ri.activityInfo.name);
20500                                if (singleUserReceivers == null) {
20501                                    singleUserReceivers = new HashSet<ComponentName>();
20502                                }
20503                                singleUserReceivers.add(cn);
20504                            }
20505                        }
20506                    }
20507                    // Add the new results to the existing results, tracking
20508                    // and de-dupping single user receivers.
20509                    for (int i=0; i<newReceivers.size(); i++) {
20510                        ResolveInfo ri = newReceivers.get(i);
20511                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20512                            ComponentName cn = new ComponentName(
20513                                    ri.activityInfo.packageName, ri.activityInfo.name);
20514                            if (singleUserReceivers == null) {
20515                                singleUserReceivers = new HashSet<ComponentName>();
20516                            }
20517                            if (!singleUserReceivers.contains(cn)) {
20518                                singleUserReceivers.add(cn);
20519                                receivers.add(ri);
20520                            }
20521                        } else {
20522                            receivers.add(ri);
20523                        }
20524                    }
20525                }
20526            }
20527        } catch (RemoteException ex) {
20528            // pm is in same process, this will never happen.
20529        }
20530        return receivers;
20531    }
20532
20533    private boolean isPermittedShellBroadcast(Intent intent) {
20534        // remote bugreport should always be allowed to be taken
20535        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
20536    }
20537
20538    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
20539            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
20540        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
20541            // Don't yell about broadcasts sent via shell
20542            return;
20543        }
20544
20545        final String action = intent.getAction();
20546        if (isProtectedBroadcast
20547                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
20548                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
20549                || Intent.ACTION_MEDIA_BUTTON.equals(action)
20550                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
20551                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
20552                || Intent.ACTION_MASTER_CLEAR.equals(action)
20553                || Intent.ACTION_FACTORY_RESET.equals(action)
20554                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20555                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
20556                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
20557                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
20558                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
20559                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
20560                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
20561            // Broadcast is either protected, or it's a public action that
20562            // we've relaxed, so it's fine for system internals to send.
20563            return;
20564        }
20565
20566        // This broadcast may be a problem...  but there are often system components that
20567        // want to send an internal broadcast to themselves, which is annoying to have to
20568        // explicitly list each action as a protected broadcast, so we will check for that
20569        // one safe case and allow it: an explicit broadcast, only being received by something
20570        // that has protected itself.
20571        if (receivers != null && receivers.size() > 0
20572                && (intent.getPackage() != null || intent.getComponent() != null)) {
20573            boolean allProtected = true;
20574            for (int i = receivers.size()-1; i >= 0; i--) {
20575                Object target = receivers.get(i);
20576                if (target instanceof ResolveInfo) {
20577                    ResolveInfo ri = (ResolveInfo)target;
20578                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
20579                        allProtected = false;
20580                        break;
20581                    }
20582                } else {
20583                    BroadcastFilter bf = (BroadcastFilter)target;
20584                    if (bf.requiredPermission == null) {
20585                        allProtected = false;
20586                        break;
20587                    }
20588                }
20589            }
20590            if (allProtected) {
20591                // All safe!
20592                return;
20593            }
20594        }
20595
20596        // The vast majority of broadcasts sent from system internals
20597        // should be protected to avoid security holes, so yell loudly
20598        // to ensure we examine these cases.
20599        if (callerApp != null) {
20600            Log.wtf(TAG, "Sending non-protected broadcast " + action
20601                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
20602                    new Throwable());
20603        } else {
20604            Log.wtf(TAG, "Sending non-protected broadcast " + action
20605                            + " from system uid " + UserHandle.formatUid(callingUid)
20606                            + " pkg " + callerPackage,
20607                    new Throwable());
20608        }
20609    }
20610
20611    final int broadcastIntentLocked(ProcessRecord callerApp,
20612            String callerPackage, Intent intent, String resolvedType,
20613            IIntentReceiver resultTo, int resultCode, String resultData,
20614            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
20615            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
20616        intent = new Intent(intent);
20617
20618        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
20619        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
20620        if (callerInstantApp) {
20621            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20622        }
20623
20624        // By default broadcasts do not go to stopped apps.
20625        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
20626
20627        // If we have not finished booting, don't allow this to launch new processes.
20628        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
20629            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20630        }
20631
20632        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
20633                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
20634                + " ordered=" + ordered + " userid=" + userId);
20635        if ((resultTo != null) && !ordered) {
20636            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
20637        }
20638
20639        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20640                ALLOW_NON_FULL, "broadcast", callerPackage);
20641
20642        // Make sure that the user who is receiving this broadcast or its parent is running.
20643        // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
20644        if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
20645            if ((callingUid != SYSTEM_UID
20646                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
20647                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
20648                Slog.w(TAG, "Skipping broadcast of " + intent
20649                        + ": user " + userId + " and its parent (if any) are stopped");
20650                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
20651            }
20652        }
20653
20654        BroadcastOptions brOptions = null;
20655        if (bOptions != null) {
20656            brOptions = new BroadcastOptions(bOptions);
20657            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
20658                // See if the caller is allowed to do this.  Note we are checking against
20659                // the actual real caller (not whoever provided the operation as say a
20660                // PendingIntent), because that who is actually supplied the arguments.
20661                if (checkComponentPermission(
20662                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
20663                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
20664                        != PackageManager.PERMISSION_GRANTED) {
20665                    String msg = "Permission Denial: " + intent.getAction()
20666                            + " broadcast from " + callerPackage + " (pid=" + callingPid
20667                            + ", uid=" + callingUid + ")"
20668                            + " requires "
20669                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
20670                    Slog.w(TAG, msg);
20671                    throw new SecurityException(msg);
20672                }
20673            }
20674        }
20675
20676        // Verify that protected broadcasts are only being sent by system code,
20677        // and that system code is only sending protected broadcasts.
20678        final String action = intent.getAction();
20679        final boolean isProtectedBroadcast;
20680        try {
20681            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
20682        } catch (RemoteException e) {
20683            Slog.w(TAG, "Remote exception", e);
20684            return ActivityManager.BROADCAST_SUCCESS;
20685        }
20686
20687        final boolean isCallerSystem;
20688        switch (UserHandle.getAppId(callingUid)) {
20689            case ROOT_UID:
20690            case SYSTEM_UID:
20691            case PHONE_UID:
20692            case BLUETOOTH_UID:
20693            case NFC_UID:
20694            case SE_UID:
20695                isCallerSystem = true;
20696                break;
20697            default:
20698                isCallerSystem = (callerApp != null) && callerApp.persistent;
20699                break;
20700        }
20701
20702        // First line security check before anything else: stop non-system apps from
20703        // sending protected broadcasts.
20704        if (!isCallerSystem) {
20705            if (isProtectedBroadcast) {
20706                String msg = "Permission Denial: not allowed to send broadcast "
20707                        + action + " from pid="
20708                        + callingPid + ", uid=" + callingUid;
20709                Slog.w(TAG, msg);
20710                throw new SecurityException(msg);
20711
20712            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20713                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
20714                // Special case for compatibility: we don't want apps to send this,
20715                // but historically it has not been protected and apps may be using it
20716                // to poke their own app widget.  So, instead of making it protected,
20717                // just limit it to the caller.
20718                if (callerPackage == null) {
20719                    String msg = "Permission Denial: not allowed to send broadcast "
20720                            + action + " from unknown caller.";
20721                    Slog.w(TAG, msg);
20722                    throw new SecurityException(msg);
20723                } else if (intent.getComponent() != null) {
20724                    // They are good enough to send to an explicit component...  verify
20725                    // it is being sent to the calling app.
20726                    if (!intent.getComponent().getPackageName().equals(
20727                            callerPackage)) {
20728                        String msg = "Permission Denial: not allowed to send broadcast "
20729                                + action + " to "
20730                                + intent.getComponent().getPackageName() + " from "
20731                                + callerPackage;
20732                        Slog.w(TAG, msg);
20733                        throw new SecurityException(msg);
20734                    }
20735                } else {
20736                    // Limit broadcast to their own package.
20737                    intent.setPackage(callerPackage);
20738                }
20739            }
20740        }
20741
20742        if (action != null) {
20743            if (getBackgroundLaunchBroadcasts().contains(action)) {
20744                if (DEBUG_BACKGROUND_CHECK) {
20745                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
20746                }
20747                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
20748            }
20749
20750            switch (action) {
20751                case Intent.ACTION_UID_REMOVED:
20752                case Intent.ACTION_PACKAGE_REMOVED:
20753                case Intent.ACTION_PACKAGE_CHANGED:
20754                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
20755                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
20756                case Intent.ACTION_PACKAGES_SUSPENDED:
20757                case Intent.ACTION_PACKAGES_UNSUSPENDED:
20758                    // Handle special intents: if this broadcast is from the package
20759                    // manager about a package being removed, we need to remove all of
20760                    // its activities from the history stack.
20761                    if (checkComponentPermission(
20762                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
20763                            callingPid, callingUid, -1, true)
20764                            != PackageManager.PERMISSION_GRANTED) {
20765                        String msg = "Permission Denial: " + intent.getAction()
20766                                + " broadcast from " + callerPackage + " (pid=" + callingPid
20767                                + ", uid=" + callingUid + ")"
20768                                + " requires "
20769                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
20770                        Slog.w(TAG, msg);
20771                        throw new SecurityException(msg);
20772                    }
20773                    switch (action) {
20774                        case Intent.ACTION_UID_REMOVED:
20775                            final int uid = getUidFromIntent(intent);
20776                            if (uid >= 0) {
20777                                mBatteryStatsService.removeUid(uid);
20778                                mAppOpsService.uidRemoved(uid);
20779                            }
20780                            break;
20781                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
20782                            // If resources are unavailable just force stop all those packages
20783                            // and flush the attribute cache as well.
20784                            String list[] =
20785                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
20786                            if (list != null && list.length > 0) {
20787                                for (int i = 0; i < list.length; i++) {
20788                                    forceStopPackageLocked(list[i], -1, false, true, true,
20789                                            false, false, userId, "storage unmount");
20790                                }
20791                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
20792                                sendPackageBroadcastLocked(
20793                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
20794                                        list, userId);
20795                            }
20796                            break;
20797                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
20798                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
20799                            break;
20800                        case Intent.ACTION_PACKAGE_REMOVED:
20801                        case Intent.ACTION_PACKAGE_CHANGED:
20802                            Uri data = intent.getData();
20803                            String ssp;
20804                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
20805                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
20806                                final boolean replacing =
20807                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
20808                                final boolean killProcess =
20809                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
20810                                final boolean fullUninstall = removed && !replacing;
20811                                if (removed) {
20812                                    if (killProcess) {
20813                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
20814                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
20815                                                false, true, true, false, fullUninstall, userId,
20816                                                removed ? "pkg removed" : "pkg changed");
20817                                    }
20818                                    final int cmd = killProcess
20819                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
20820                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
20821                                    sendPackageBroadcastLocked(cmd,
20822                                            new String[] {ssp}, userId);
20823                                    if (fullUninstall) {
20824                                        mAppOpsService.packageRemoved(
20825                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
20826
20827                                        // Remove all permissions granted from/to this package
20828                                        removeUriPermissionsForPackageLocked(ssp, userId, true,
20829                                                false);
20830
20831                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
20832
20833                                        mServices.forceStopPackageLocked(ssp, userId);
20834                                        mAppWarnings.onPackageUninstalled(ssp);
20835                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
20836                                        mBatteryStatsService.notePackageUninstalled(ssp);
20837                                    }
20838                                } else {
20839                                    if (killProcess) {
20840                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
20841                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
20842                                                userId, ProcessList.INVALID_ADJ,
20843                                                false, true, true, false, "change " + ssp);
20844                                    }
20845                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
20846                                            intent.getStringArrayExtra(
20847                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
20848                                }
20849                            }
20850                            break;
20851                        case Intent.ACTION_PACKAGES_SUSPENDED:
20852                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
20853                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
20854                                    intent.getAction());
20855                            final String[] packageNames = intent.getStringArrayExtra(
20856                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
20857                            final int userHandle = intent.getIntExtra(
20858                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
20859
20860                            synchronized(ActivityManagerService.this) {
20861                                mRecentTasks.onPackagesSuspendedChanged(
20862                                        packageNames, suspended, userHandle);
20863                            }
20864                            break;
20865                    }
20866                    break;
20867                case Intent.ACTION_PACKAGE_REPLACED:
20868                {
20869                    final Uri data = intent.getData();
20870                    final String ssp;
20871                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20872                        ApplicationInfo aInfo = null;
20873                        try {
20874                            aInfo = AppGlobals.getPackageManager()
20875                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
20876                        } catch (RemoteException ignore) {}
20877                        if (aInfo == null) {
20878                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
20879                                    + " ssp=" + ssp + " data=" + data);
20880                            return ActivityManager.BROADCAST_SUCCESS;
20881                        }
20882                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
20883                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
20884                                new String[] {ssp}, userId);
20885                    }
20886                    break;
20887                }
20888                case Intent.ACTION_PACKAGE_ADDED:
20889                {
20890                    // Special case for adding a package: by default turn on compatibility mode.
20891                    Uri data = intent.getData();
20892                    String ssp;
20893                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20894                        final boolean replacing =
20895                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
20896                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
20897
20898                        try {
20899                            ApplicationInfo ai = AppGlobals.getPackageManager().
20900                                    getApplicationInfo(ssp, 0, 0);
20901                            mBatteryStatsService.notePackageInstalled(ssp,
20902                                    ai != null ? ai.versionCode : 0);
20903                        } catch (RemoteException e) {
20904                        }
20905                    }
20906                    break;
20907                }
20908                case Intent.ACTION_PACKAGE_DATA_CLEARED:
20909                {
20910                    Uri data = intent.getData();
20911                    String ssp;
20912                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20913                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
20914                        mAppWarnings.onPackageDataCleared(ssp);
20915                    }
20916                    break;
20917                }
20918                case Intent.ACTION_TIMEZONE_CHANGED:
20919                    // If this is the time zone changed action, queue up a message that will reset
20920                    // the timezone of all currently running processes. This message will get
20921                    // queued up before the broadcast happens.
20922                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
20923                    break;
20924                case Intent.ACTION_TIME_CHANGED:
20925                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
20926                    // the tri-state value it may contain and "unknown".
20927                    // For convenience we re-use the Intent extra values.
20928                    final int NO_EXTRA_VALUE_FOUND = -1;
20929                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
20930                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
20931                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
20932                    // Only send a message if the time preference is available.
20933                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
20934                        Message updateTimePreferenceMsg =
20935                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
20936                                        timeFormatPreferenceMsgValue, 0);
20937                        mHandler.sendMessage(updateTimePreferenceMsg);
20938                    }
20939                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20940                    synchronized (stats) {
20941                        stats.noteCurrentTimeChangedLocked();
20942                    }
20943                    break;
20944                case Intent.ACTION_CLEAR_DNS_CACHE:
20945                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
20946                    break;
20947                case Proxy.PROXY_CHANGE_ACTION:
20948                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
20949                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
20950                    break;
20951                case android.hardware.Camera.ACTION_NEW_PICTURE:
20952                case android.hardware.Camera.ACTION_NEW_VIDEO:
20953                    // In N we just turned these off; in O we are turing them back on partly,
20954                    // only for registered receivers.  This will still address the main problem
20955                    // (a spam of apps waking up when a picture is taken putting significant
20956                    // memory pressure on the system at a bad point), while still allowing apps
20957                    // that are already actively running to know about this happening.
20958                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20959                    break;
20960                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
20961                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
20962                    break;
20963                case "com.android.launcher.action.INSTALL_SHORTCUT":
20964                    // As of O, we no longer support this broadcasts, even for pre-O apps.
20965                    // Apps should now be using ShortcutManager.pinRequestShortcut().
20966                    Log.w(TAG, "Broadcast " + action
20967                            + " no longer supported. It will not be delivered.");
20968                    return ActivityManager.BROADCAST_SUCCESS;
20969            }
20970
20971            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
20972                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
20973                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
20974                final int uid = getUidFromIntent(intent);
20975                if (uid != -1) {
20976                    final UidRecord uidRec = mActiveUids.get(uid);
20977                    if (uidRec != null) {
20978                        uidRec.updateHasInternetPermission();
20979                    }
20980                }
20981            }
20982        }
20983
20984        // Add to the sticky list if requested.
20985        if (sticky) {
20986            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
20987                    callingPid, callingUid)
20988                    != PackageManager.PERMISSION_GRANTED) {
20989                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
20990                        + callingPid + ", uid=" + callingUid
20991                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
20992                Slog.w(TAG, msg);
20993                throw new SecurityException(msg);
20994            }
20995            if (requiredPermissions != null && requiredPermissions.length > 0) {
20996                Slog.w(TAG, "Can't broadcast sticky intent " + intent
20997                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
20998                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
20999            }
21000            if (intent.getComponent() != null) {
21001                throw new SecurityException(
21002                        "Sticky broadcasts can't target a specific component");
21003            }
21004            // We use userId directly here, since the "all" target is maintained
21005            // as a separate set of sticky broadcasts.
21006            if (userId != UserHandle.USER_ALL) {
21007                // But first, if this is not a broadcast to all users, then
21008                // make sure it doesn't conflict with an existing broadcast to
21009                // all users.
21010                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
21011                        UserHandle.USER_ALL);
21012                if (stickies != null) {
21013                    ArrayList<Intent> list = stickies.get(intent.getAction());
21014                    if (list != null) {
21015                        int N = list.size();
21016                        int i;
21017                        for (i=0; i<N; i++) {
21018                            if (intent.filterEquals(list.get(i))) {
21019                                throw new IllegalArgumentException(
21020                                        "Sticky broadcast " + intent + " for user "
21021                                        + userId + " conflicts with existing global broadcast");
21022                            }
21023                        }
21024                    }
21025                }
21026            }
21027            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21028            if (stickies == null) {
21029                stickies = new ArrayMap<>();
21030                mStickyBroadcasts.put(userId, stickies);
21031            }
21032            ArrayList<Intent> list = stickies.get(intent.getAction());
21033            if (list == null) {
21034                list = new ArrayList<>();
21035                stickies.put(intent.getAction(), list);
21036            }
21037            final int stickiesCount = list.size();
21038            int i;
21039            for (i = 0; i < stickiesCount; i++) {
21040                if (intent.filterEquals(list.get(i))) {
21041                    // This sticky already exists, replace it.
21042                    list.set(i, new Intent(intent));
21043                    break;
21044                }
21045            }
21046            if (i >= stickiesCount) {
21047                list.add(new Intent(intent));
21048            }
21049        }
21050
21051        int[] users;
21052        if (userId == UserHandle.USER_ALL) {
21053            // Caller wants broadcast to go to all started users.
21054            users = mUserController.getStartedUserArray();
21055        } else {
21056            // Caller wants broadcast to go to one specific user.
21057            users = new int[] {userId};
21058        }
21059
21060        // Figure out who all will receive this broadcast.
21061        List receivers = null;
21062        List<BroadcastFilter> registeredReceivers = null;
21063        // Need to resolve the intent to interested receivers...
21064        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
21065                 == 0) {
21066            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
21067        }
21068        if (intent.getComponent() == null) {
21069            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
21070                // Query one target user at a time, excluding shell-restricted users
21071                for (int i = 0; i < users.length; i++) {
21072                    if (mUserController.hasUserRestriction(
21073                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
21074                        continue;
21075                    }
21076                    List<BroadcastFilter> registeredReceiversForUser =
21077                            mReceiverResolver.queryIntent(intent,
21078                                    resolvedType, false /*defaultOnly*/, users[i]);
21079                    if (registeredReceivers == null) {
21080                        registeredReceivers = registeredReceiversForUser;
21081                    } else if (registeredReceiversForUser != null) {
21082                        registeredReceivers.addAll(registeredReceiversForUser);
21083                    }
21084                }
21085            } else {
21086                registeredReceivers = mReceiverResolver.queryIntent(intent,
21087                        resolvedType, false /*defaultOnly*/, userId);
21088            }
21089        }
21090
21091        final boolean replacePending =
21092                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
21093
21094        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
21095                + " replacePending=" + replacePending);
21096
21097        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
21098        if (!ordered && NR > 0) {
21099            // If we are not serializing this broadcast, then send the
21100            // registered receivers separately so they don't wait for the
21101            // components to be launched.
21102            if (isCallerSystem) {
21103                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21104                        isProtectedBroadcast, registeredReceivers);
21105            }
21106            final BroadcastQueue queue = broadcastQueueForIntent(intent);
21107            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21108                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21109                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
21110                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
21111            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
21112            final boolean replaced = replacePending
21113                    && (queue.replaceParallelBroadcastLocked(r) != null);
21114            // Note: We assume resultTo is null for non-ordered broadcasts.
21115            if (!replaced) {
21116                queue.enqueueParallelBroadcastLocked(r);
21117                queue.scheduleBroadcastsLocked();
21118            }
21119            registeredReceivers = null;
21120            NR = 0;
21121        }
21122
21123        // Merge into one list.
21124        int ir = 0;
21125        if (receivers != null) {
21126            // A special case for PACKAGE_ADDED: do not allow the package
21127            // being added to see this broadcast.  This prevents them from
21128            // using this as a back door to get run as soon as they are
21129            // installed.  Maybe in the future we want to have a special install
21130            // broadcast or such for apps, but we'd like to deliberately make
21131            // this decision.
21132            String skipPackages[] = null;
21133            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
21134                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
21135                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
21136                Uri data = intent.getData();
21137                if (data != null) {
21138                    String pkgName = data.getSchemeSpecificPart();
21139                    if (pkgName != null) {
21140                        skipPackages = new String[] { pkgName };
21141                    }
21142                }
21143            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
21144                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21145            }
21146            if (skipPackages != null && (skipPackages.length > 0)) {
21147                for (String skipPackage : skipPackages) {
21148                    if (skipPackage != null) {
21149                        int NT = receivers.size();
21150                        for (int it=0; it<NT; it++) {
21151                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
21152                            if (curt.activityInfo.packageName.equals(skipPackage)) {
21153                                receivers.remove(it);
21154                                it--;
21155                                NT--;
21156                            }
21157                        }
21158                    }
21159                }
21160            }
21161
21162            int NT = receivers != null ? receivers.size() : 0;
21163            int it = 0;
21164            ResolveInfo curt = null;
21165            BroadcastFilter curr = null;
21166            while (it < NT && ir < NR) {
21167                if (curt == null) {
21168                    curt = (ResolveInfo)receivers.get(it);
21169                }
21170                if (curr == null) {
21171                    curr = registeredReceivers.get(ir);
21172                }
21173                if (curr.getPriority() >= curt.priority) {
21174                    // Insert this broadcast record into the final list.
21175                    receivers.add(it, curr);
21176                    ir++;
21177                    curr = null;
21178                    it++;
21179                    NT++;
21180                } else {
21181                    // Skip to the next ResolveInfo in the final list.
21182                    it++;
21183                    curt = null;
21184                }
21185            }
21186        }
21187        while (ir < NR) {
21188            if (receivers == null) {
21189                receivers = new ArrayList();
21190            }
21191            receivers.add(registeredReceivers.get(ir));
21192            ir++;
21193        }
21194
21195        if (isCallerSystem) {
21196            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21197                    isProtectedBroadcast, receivers);
21198        }
21199
21200        if ((receivers != null && receivers.size() > 0)
21201                || resultTo != null) {
21202            BroadcastQueue queue = broadcastQueueForIntent(intent);
21203            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21204                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21205                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
21206                    resultData, resultExtras, ordered, sticky, false, userId);
21207
21208            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
21209                    + ": prev had " + queue.mOrderedBroadcasts.size());
21210            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
21211                    "Enqueueing broadcast " + r.intent.getAction());
21212
21213            final BroadcastRecord oldRecord =
21214                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
21215            if (oldRecord != null) {
21216                // Replaced, fire the result-to receiver.
21217                if (oldRecord.resultTo != null) {
21218                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
21219                    try {
21220                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
21221                                oldRecord.intent,
21222                                Activity.RESULT_CANCELED, null, null,
21223                                false, false, oldRecord.userId);
21224                    } catch (RemoteException e) {
21225                        Slog.w(TAG, "Failure ["
21226                                + queue.mQueueName + "] sending broadcast result of "
21227                                + intent, e);
21228
21229                    }
21230                }
21231            } else {
21232                queue.enqueueOrderedBroadcastLocked(r);
21233                queue.scheduleBroadcastsLocked();
21234            }
21235        } else {
21236            // There was nobody interested in the broadcast, but we still want to record
21237            // that it happened.
21238            if (intent.getComponent() == null && intent.getPackage() == null
21239                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21240                // This was an implicit broadcast... let's record it for posterity.
21241                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
21242            }
21243        }
21244
21245        return ActivityManager.BROADCAST_SUCCESS;
21246    }
21247
21248    /**
21249     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21250     */
21251    private int getUidFromIntent(Intent intent) {
21252        if (intent == null) {
21253            return -1;
21254        }
21255        final Bundle intentExtras = intent.getExtras();
21256        return intent.hasExtra(Intent.EXTRA_UID)
21257                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
21258    }
21259
21260    final void rotateBroadcastStatsIfNeededLocked() {
21261        final long now = SystemClock.elapsedRealtime();
21262        if (mCurBroadcastStats == null ||
21263                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
21264            mLastBroadcastStats = mCurBroadcastStats;
21265            if (mLastBroadcastStats != null) {
21266                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
21267                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
21268            }
21269            mCurBroadcastStats = new BroadcastStats();
21270        }
21271    }
21272
21273    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
21274            int skipCount, long dispatchTime) {
21275        rotateBroadcastStatsIfNeededLocked();
21276        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
21277    }
21278
21279    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21280        rotateBroadcastStatsIfNeededLocked();
21281        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
21282    }
21283
21284    final Intent verifyBroadcastLocked(Intent intent) {
21285        // Refuse possible leaked file descriptors
21286        if (intent != null && intent.hasFileDescriptors() == true) {
21287            throw new IllegalArgumentException("File descriptors passed in Intent");
21288        }
21289
21290        int flags = intent.getFlags();
21291
21292        if (!mProcessesReady) {
21293            // if the caller really truly claims to know what they're doing, go
21294            // ahead and allow the broadcast without launching any receivers
21295            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
21296                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
21297            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21298                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
21299                        + " before boot completion");
21300                throw new IllegalStateException("Cannot broadcast before boot completed");
21301            }
21302        }
21303
21304        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
21305            throw new IllegalArgumentException(
21306                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
21307        }
21308
21309        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21310            switch (Binder.getCallingUid()) {
21311                case ROOT_UID:
21312                case SHELL_UID:
21313                    break;
21314                default:
21315                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
21316                            + Binder.getCallingUid());
21317                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
21318                    break;
21319            }
21320        }
21321
21322        return intent;
21323    }
21324
21325    public final int broadcastIntent(IApplicationThread caller,
21326            Intent intent, String resolvedType, IIntentReceiver resultTo,
21327            int resultCode, String resultData, Bundle resultExtras,
21328            String[] requiredPermissions, int appOp, Bundle bOptions,
21329            boolean serialized, boolean sticky, int userId) {
21330        enforceNotIsolatedCaller("broadcastIntent");
21331        synchronized(this) {
21332            intent = verifyBroadcastLocked(intent);
21333
21334            final ProcessRecord callerApp = getRecordForAppLocked(caller);
21335            final int callingPid = Binder.getCallingPid();
21336            final int callingUid = Binder.getCallingUid();
21337            final long origId = Binder.clearCallingIdentity();
21338            int res = broadcastIntentLocked(callerApp,
21339                    callerApp != null ? callerApp.info.packageName : null,
21340                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
21341                    requiredPermissions, appOp, bOptions, serialized, sticky,
21342                    callingPid, callingUid, userId);
21343            Binder.restoreCallingIdentity(origId);
21344            return res;
21345        }
21346    }
21347
21348
21349    int broadcastIntentInPackage(String packageName, int uid,
21350            Intent intent, String resolvedType, IIntentReceiver resultTo,
21351            int resultCode, String resultData, Bundle resultExtras,
21352            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
21353            int userId) {
21354        synchronized(this) {
21355            intent = verifyBroadcastLocked(intent);
21356
21357            final long origId = Binder.clearCallingIdentity();
21358            String[] requiredPermissions = requiredPermission == null ? null
21359                    : new String[] {requiredPermission};
21360            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
21361                    resultTo, resultCode, resultData, resultExtras,
21362                    requiredPermissions, OP_NONE, bOptions, serialized,
21363                    sticky, -1, uid, userId);
21364            Binder.restoreCallingIdentity(origId);
21365            return res;
21366        }
21367    }
21368
21369    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
21370        // Refuse possible leaked file descriptors
21371        if (intent != null && intent.hasFileDescriptors() == true) {
21372            throw new IllegalArgumentException("File descriptors passed in Intent");
21373        }
21374
21375        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21376                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
21377
21378        synchronized(this) {
21379            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
21380                    != PackageManager.PERMISSION_GRANTED) {
21381                String msg = "Permission Denial: unbroadcastIntent() from pid="
21382                        + Binder.getCallingPid()
21383                        + ", uid=" + Binder.getCallingUid()
21384                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21385                Slog.w(TAG, msg);
21386                throw new SecurityException(msg);
21387            }
21388            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21389            if (stickies != null) {
21390                ArrayList<Intent> list = stickies.get(intent.getAction());
21391                if (list != null) {
21392                    int N = list.size();
21393                    int i;
21394                    for (i=0; i<N; i++) {
21395                        if (intent.filterEquals(list.get(i))) {
21396                            list.remove(i);
21397                            break;
21398                        }
21399                    }
21400                    if (list.size() <= 0) {
21401                        stickies.remove(intent.getAction());
21402                    }
21403                }
21404                if (stickies.size() <= 0) {
21405                    mStickyBroadcasts.remove(userId);
21406                }
21407            }
21408        }
21409    }
21410
21411    void backgroundServicesFinishedLocked(int userId) {
21412        for (BroadcastQueue queue : mBroadcastQueues) {
21413            queue.backgroundServicesFinishedLocked(userId);
21414        }
21415    }
21416
21417    public void finishReceiver(IBinder who, int resultCode, String resultData,
21418            Bundle resultExtras, boolean resultAbort, int flags) {
21419        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
21420
21421        // Refuse possible leaked file descriptors
21422        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
21423            throw new IllegalArgumentException("File descriptors passed in Bundle");
21424        }
21425
21426        final long origId = Binder.clearCallingIdentity();
21427        try {
21428            boolean doNext = false;
21429            BroadcastRecord r;
21430
21431            synchronized(this) {
21432                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
21433                        ? mFgBroadcastQueue : mBgBroadcastQueue;
21434                r = queue.getMatchingOrderedReceiver(who);
21435                if (r != null) {
21436                    doNext = r.queue.finishReceiverLocked(r, resultCode,
21437                        resultData, resultExtras, resultAbort, true);
21438                }
21439            }
21440
21441            if (doNext) {
21442                r.queue.processNextBroadcast(false);
21443            }
21444            trimApplications();
21445        } finally {
21446            Binder.restoreCallingIdentity(origId);
21447        }
21448    }
21449
21450    // =========================================================
21451    // INSTRUMENTATION
21452    // =========================================================
21453
21454    public boolean startInstrumentation(ComponentName className,
21455            String profileFile, int flags, Bundle arguments,
21456            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
21457            int userId, String abiOverride) {
21458        enforceNotIsolatedCaller("startInstrumentation");
21459        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21460                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
21461        // Refuse possible leaked file descriptors
21462        if (arguments != null && arguments.hasFileDescriptors()) {
21463            throw new IllegalArgumentException("File descriptors passed in Bundle");
21464        }
21465
21466        synchronized(this) {
21467            InstrumentationInfo ii = null;
21468            ApplicationInfo ai = null;
21469            try {
21470                ii = mContext.getPackageManager().getInstrumentationInfo(
21471                    className, STOCK_PM_FLAGS);
21472                ai = AppGlobals.getPackageManager().getApplicationInfo(
21473                        ii.targetPackage, STOCK_PM_FLAGS, userId);
21474            } catch (PackageManager.NameNotFoundException e) {
21475            } catch (RemoteException e) {
21476            }
21477            if (ii == null) {
21478                reportStartInstrumentationFailureLocked(watcher, className,
21479                        "Unable to find instrumentation info for: " + className);
21480                return false;
21481            }
21482            if (ai == null) {
21483                reportStartInstrumentationFailureLocked(watcher, className,
21484                        "Unable to find instrumentation target package: " + ii.targetPackage);
21485                return false;
21486            }
21487            if (!ai.hasCode()) {
21488                reportStartInstrumentationFailureLocked(watcher, className,
21489                        "Instrumentation target has no code: " + ii.targetPackage);
21490                return false;
21491            }
21492
21493            int match = mContext.getPackageManager().checkSignatures(
21494                    ii.targetPackage, ii.packageName);
21495            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
21496                String msg = "Permission Denial: starting instrumentation "
21497                        + className + " from pid="
21498                        + Binder.getCallingPid()
21499                        + ", uid=" + Binder.getCallingPid()
21500                        + " not allowed because package " + ii.packageName
21501                        + " does not have a signature matching the target "
21502                        + ii.targetPackage;
21503                reportStartInstrumentationFailureLocked(watcher, className, msg);
21504                throw new SecurityException(msg);
21505            }
21506
21507            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
21508            activeInstr.mClass = className;
21509            String defProcess = ai.processName;;
21510            if (ii.targetProcesses == null) {
21511                activeInstr.mTargetProcesses = new String[]{ai.processName};
21512            } else if (ii.targetProcesses.equals("*")) {
21513                activeInstr.mTargetProcesses = new String[0];
21514            } else {
21515                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
21516                defProcess = activeInstr.mTargetProcesses[0];
21517            }
21518            activeInstr.mTargetInfo = ai;
21519            activeInstr.mProfileFile = profileFile;
21520            activeInstr.mArguments = arguments;
21521            activeInstr.mWatcher = watcher;
21522            activeInstr.mUiAutomationConnection = uiAutomationConnection;
21523            activeInstr.mResultClass = className;
21524
21525            final long origId = Binder.clearCallingIdentity();
21526            // Instrumentation can kill and relaunch even persistent processes
21527            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
21528                    "start instr");
21529            // Inform usage stats to make the target package active
21530            if (mUsageStatsService != null) {
21531                mUsageStatsService.reportEvent(ii.targetPackage, userId,
21532                        UsageEvents.Event.SYSTEM_INTERACTION);
21533            }
21534            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
21535            app.instr = activeInstr;
21536            activeInstr.mFinished = false;
21537            activeInstr.mRunningProcesses.add(app);
21538            if (!mActiveInstrumentation.contains(activeInstr)) {
21539                mActiveInstrumentation.add(activeInstr);
21540            }
21541            Binder.restoreCallingIdentity(origId);
21542        }
21543
21544        return true;
21545    }
21546
21547    /**
21548     * Report errors that occur while attempting to start Instrumentation.  Always writes the
21549     * error to the logs, but if somebody is watching, send the report there too.  This enables
21550     * the "am" command to report errors with more information.
21551     *
21552     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
21553     * @param cn The component name of the instrumentation.
21554     * @param report The error report.
21555     */
21556    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
21557            ComponentName cn, String report) {
21558        Slog.w(TAG, report);
21559        if (watcher != null) {
21560            Bundle results = new Bundle();
21561            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
21562            results.putString("Error", report);
21563            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
21564        }
21565    }
21566
21567    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
21568        if (app.instr == null) {
21569            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21570            return;
21571        }
21572
21573        if (!app.instr.mFinished && results != null) {
21574            if (app.instr.mCurResults == null) {
21575                app.instr.mCurResults = new Bundle(results);
21576            } else {
21577                app.instr.mCurResults.putAll(results);
21578            }
21579        }
21580    }
21581
21582    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
21583        int userId = UserHandle.getCallingUserId();
21584        // Refuse possible leaked file descriptors
21585        if (results != null && results.hasFileDescriptors()) {
21586            throw new IllegalArgumentException("File descriptors passed in Intent");
21587        }
21588
21589        synchronized(this) {
21590            ProcessRecord app = getRecordForAppLocked(target);
21591            if (app == null) {
21592                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
21593                return;
21594            }
21595            final long origId = Binder.clearCallingIdentity();
21596            addInstrumentationResultsLocked(app, results);
21597            Binder.restoreCallingIdentity(origId);
21598        }
21599    }
21600
21601    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
21602        if (app.instr == null) {
21603            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21604            return;
21605        }
21606
21607        if (!app.instr.mFinished) {
21608            if (app.instr.mWatcher != null) {
21609                Bundle finalResults = app.instr.mCurResults;
21610                if (finalResults != null) {
21611                    if (app.instr.mCurResults != null && results != null) {
21612                        finalResults.putAll(results);
21613                    }
21614                } else {
21615                    finalResults = results;
21616                }
21617                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
21618                        app.instr.mClass, resultCode, finalResults);
21619            }
21620
21621            // Can't call out of the system process with a lock held, so post a message.
21622            if (app.instr.mUiAutomationConnection != null) {
21623                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
21624                        app.instr.mUiAutomationConnection).sendToTarget();
21625            }
21626            app.instr.mFinished = true;
21627        }
21628
21629        app.instr.removeProcess(app);
21630        app.instr = null;
21631
21632        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
21633                "finished inst");
21634    }
21635
21636    public void finishInstrumentation(IApplicationThread target,
21637            int resultCode, Bundle results) {
21638        int userId = UserHandle.getCallingUserId();
21639        // Refuse possible leaked file descriptors
21640        if (results != null && results.hasFileDescriptors()) {
21641            throw new IllegalArgumentException("File descriptors passed in Intent");
21642        }
21643
21644        synchronized(this) {
21645            ProcessRecord app = getRecordForAppLocked(target);
21646            if (app == null) {
21647                Slog.w(TAG, "finishInstrumentation: no app for " + target);
21648                return;
21649            }
21650            final long origId = Binder.clearCallingIdentity();
21651            finishInstrumentationLocked(app, resultCode, results);
21652            Binder.restoreCallingIdentity(origId);
21653        }
21654    }
21655
21656    // =========================================================
21657    // CONFIGURATION
21658    // =========================================================
21659
21660    public ConfigurationInfo getDeviceConfigurationInfo() {
21661        ConfigurationInfo config = new ConfigurationInfo();
21662        synchronized (this) {
21663            final Configuration globalConfig = getGlobalConfiguration();
21664            config.reqTouchScreen = globalConfig.touchscreen;
21665            config.reqKeyboardType = globalConfig.keyboard;
21666            config.reqNavigation = globalConfig.navigation;
21667            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
21668                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
21669                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
21670            }
21671            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
21672                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
21673                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
21674            }
21675            config.reqGlEsVersion = GL_ES_VERSION;
21676        }
21677        return config;
21678    }
21679
21680    ActivityStack getFocusedStack() {
21681        return mStackSupervisor.getFocusedStack();
21682    }
21683
21684    @Override
21685    public StackInfo getFocusedStackInfo() throws RemoteException {
21686        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
21687        long ident = Binder.clearCallingIdentity();
21688        try {
21689            synchronized (this) {
21690                ActivityStack focusedStack = getFocusedStack();
21691                if (focusedStack != null) {
21692                    return mStackSupervisor.getStackInfo(focusedStack.mStackId);
21693                }
21694                return null;
21695            }
21696        } finally {
21697            Binder.restoreCallingIdentity(ident);
21698        }
21699    }
21700
21701    public Configuration getConfiguration() {
21702        Configuration ci;
21703        synchronized(this) {
21704            ci = new Configuration(getGlobalConfiguration());
21705            ci.userSetLocale = false;
21706        }
21707        return ci;
21708    }
21709
21710    @Override
21711    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
21712        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
21713        synchronized (this) {
21714            mSuppressResizeConfigChanges = suppress;
21715        }
21716    }
21717
21718    /**
21719     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
21720     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
21721     *       activity and clearing the task at the same time.
21722     */
21723    @Override
21724    // TODO: API should just be about changing windowing modes...
21725    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
21726        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
21727                "moveTasksToFullscreenStack()");
21728        synchronized (this) {
21729            final long origId = Binder.clearCallingIdentity();
21730            try {
21731                final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
21732                if (stack != null){
21733                    if (!stack.isActivityTypeStandardOrUndefined()) {
21734                        throw new IllegalArgumentException(
21735                                "You can't move tasks from non-standard stacks.");
21736                    }
21737                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
21738                }
21739            } finally {
21740                Binder.restoreCallingIdentity(origId);
21741            }
21742        }
21743    }
21744
21745    @Override
21746    public void updatePersistentConfiguration(Configuration values) {
21747        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
21748        enforceWriteSettingsPermission("updatePersistentConfiguration()");
21749        if (values == null) {
21750            throw new NullPointerException("Configuration must not be null");
21751        }
21752
21753        int userId = UserHandle.getCallingUserId();
21754
21755        synchronized(this) {
21756            updatePersistentConfigurationLocked(values, userId);
21757        }
21758    }
21759
21760    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
21761        final long origId = Binder.clearCallingIdentity();
21762        try {
21763            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
21764        } finally {
21765            Binder.restoreCallingIdentity(origId);
21766        }
21767    }
21768
21769    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
21770        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
21771                FONT_SCALE, 1.0f, userId);
21772
21773        synchronized (this) {
21774            if (getGlobalConfiguration().fontScale == scaleFactor) {
21775                return;
21776            }
21777
21778            final Configuration configuration
21779                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
21780            configuration.fontScale = scaleFactor;
21781            updatePersistentConfigurationLocked(configuration, userId);
21782        }
21783    }
21784
21785    private void enforceWriteSettingsPermission(String func) {
21786        int uid = Binder.getCallingUid();
21787        if (uid == ROOT_UID) {
21788            return;
21789        }
21790
21791        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
21792                Settings.getPackageNameForUid(mContext, uid), false)) {
21793            return;
21794        }
21795
21796        String msg = "Permission Denial: " + func + " from pid="
21797                + Binder.getCallingPid()
21798                + ", uid=" + uid
21799                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
21800        Slog.w(TAG, msg);
21801        throw new SecurityException(msg);
21802    }
21803
21804    @Override
21805    public boolean updateConfiguration(Configuration values) {
21806        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
21807
21808        synchronized(this) {
21809            if (values == null && mWindowManager != null) {
21810                // sentinel: fetch the current configuration from the window manager
21811                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
21812            }
21813
21814            if (mWindowManager != null) {
21815                // Update OOM levels based on display size.
21816                mProcessList.applyDisplaySize(mWindowManager);
21817            }
21818
21819            final long origId = Binder.clearCallingIdentity();
21820            try {
21821                if (values != null) {
21822                    Settings.System.clearConfiguration(values);
21823                }
21824                updateConfigurationLocked(values, null, false, false /* persistent */,
21825                        UserHandle.USER_NULL, false /* deferResume */,
21826                        mTmpUpdateConfigurationResult);
21827                return mTmpUpdateConfigurationResult.changes != 0;
21828            } finally {
21829                Binder.restoreCallingIdentity(origId);
21830            }
21831        }
21832    }
21833
21834    void updateUserConfigurationLocked() {
21835        final Configuration configuration = new Configuration(getGlobalConfiguration());
21836        final int currentUserId = mUserController.getCurrentUserId();
21837        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
21838                currentUserId, Settings.System.canWrite(mContext));
21839        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
21840                false /* persistent */, currentUserId, false /* deferResume */);
21841    }
21842
21843    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21844            boolean initLocale) {
21845        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
21846    }
21847
21848    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21849            boolean initLocale, boolean deferResume) {
21850        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
21851        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
21852                UserHandle.USER_NULL, deferResume);
21853    }
21854
21855    // To cache the list of supported system locales
21856    private String[] mSupportedSystemLocales = null;
21857
21858    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21859            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
21860        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
21861                deferResume, null /* result */);
21862    }
21863
21864    /**
21865     * Do either or both things: (1) change the current configuration, and (2)
21866     * make sure the given activity is running with the (now) current
21867     * configuration.  Returns true if the activity has been left running, or
21868     * false if <var>starting</var> is being destroyed to match the new
21869     * configuration.
21870     *
21871     * @param userId is only used when persistent parameter is set to true to persist configuration
21872     *               for that particular user
21873     */
21874    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21875            boolean initLocale, boolean persistent, int userId, boolean deferResume,
21876            UpdateConfigurationResult result) {
21877        int changes = 0;
21878        boolean kept = true;
21879
21880        if (mWindowManager != null) {
21881            mWindowManager.deferSurfaceLayout();
21882        }
21883        try {
21884            if (values != null) {
21885                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
21886                        deferResume);
21887            }
21888
21889            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
21890        } finally {
21891            if (mWindowManager != null) {
21892                mWindowManager.continueSurfaceLayout();
21893            }
21894        }
21895
21896        if (result != null) {
21897            result.changes = changes;
21898            result.activityRelaunched = !kept;
21899        }
21900        return kept;
21901    }
21902
21903    /** Update default (global) configuration and notify listeners about changes. */
21904    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
21905            boolean persistent, int userId, boolean deferResume) {
21906        mTempConfig.setTo(getGlobalConfiguration());
21907        final int changes = mTempConfig.updateFrom(values);
21908        if (changes == 0) {
21909            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
21910            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
21911            // performDisplayOverrideConfigUpdate in order to send the new display configuration
21912            // (even if there are no actual changes) to unfreeze the window.
21913            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
21914            return 0;
21915        }
21916
21917        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
21918                "Updating global configuration to: " + values);
21919
21920        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
21921
21922        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
21923            final LocaleList locales = values.getLocales();
21924            int bestLocaleIndex = 0;
21925            if (locales.size() > 1) {
21926                if (mSupportedSystemLocales == null) {
21927                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
21928                }
21929                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
21930            }
21931            SystemProperties.set("persist.sys.locale",
21932                    locales.get(bestLocaleIndex).toLanguageTag());
21933            LocaleList.setDefault(locales, bestLocaleIndex);
21934            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
21935                    locales.get(bestLocaleIndex)));
21936        }
21937
21938        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
21939        mTempConfig.seq = mConfigurationSeq;
21940
21941        // Update stored global config and notify everyone about the change.
21942        mStackSupervisor.onConfigurationChanged(mTempConfig);
21943
21944        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
21945        // TODO(multi-display): Update UsageEvents#Event to include displayId.
21946        mUsageStatsService.reportConfigurationChange(mTempConfig,
21947                mUserController.getCurrentUserId());
21948
21949        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
21950        mShowDialogs = shouldShowDialogs(mTempConfig);
21951
21952        AttributeCache ac = AttributeCache.instance();
21953        if (ac != null) {
21954            ac.updateConfiguration(mTempConfig);
21955        }
21956
21957        // Make sure all resources in our process are updated right now, so that anyone who is going
21958        // to retrieve resource values after we return will be sure to get the new ones. This is
21959        // especially important during boot, where the first config change needs to guarantee all
21960        // resources have that config before following boot code is executed.
21961        mSystemThread.applyConfigurationToResources(mTempConfig);
21962
21963        // We need another copy of global config because we're scheduling some calls instead of
21964        // running them in place. We need to be sure that object we send will be handled unchanged.
21965        final Configuration configCopy = new Configuration(mTempConfig);
21966        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
21967            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
21968            msg.obj = configCopy;
21969            msg.arg1 = userId;
21970            mHandler.sendMessage(msg);
21971        }
21972
21973        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21974            ProcessRecord app = mLruProcesses.get(i);
21975            try {
21976                if (app.thread != null) {
21977                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
21978                            + app.processName + " new config " + configCopy);
21979                    mLifecycleManager.scheduleTransaction(app.thread,
21980                            ConfigurationChangeItem.obtain(configCopy));
21981                }
21982            } catch (Exception e) {
21983                Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
21984            }
21985        }
21986
21987        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
21988        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
21989                | Intent.FLAG_RECEIVER_FOREGROUND
21990                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21991        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
21992                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
21993                UserHandle.USER_ALL);
21994        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
21995            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
21996            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
21997                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
21998                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21999            if (initLocale || !mProcessesReady) {
22000                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
22001            }
22002            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22003                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22004                    UserHandle.USER_ALL);
22005        }
22006
22007        // Override configuration of the default display duplicates global config, so we need to
22008        // update it also. This will also notify WindowManager about changes.
22009        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
22010                DEFAULT_DISPLAY);
22011
22012        return changes;
22013    }
22014
22015    @Override
22016    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
22017        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
22018
22019        synchronized (this) {
22020            // Check if display is initialized in AM.
22021            if (!mStackSupervisor.isDisplayAdded(displayId)) {
22022                // Call might come when display is not yet added or has already been removed.
22023                if (DEBUG_CONFIGURATION) {
22024                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
22025                            + displayId);
22026                }
22027                return false;
22028            }
22029
22030            if (values == null && mWindowManager != null) {
22031                // sentinel: fetch the current configuration from the window manager
22032                values = mWindowManager.computeNewConfiguration(displayId);
22033            }
22034
22035            if (mWindowManager != null) {
22036                // Update OOM levels based on display size.
22037                mProcessList.applyDisplaySize(mWindowManager);
22038            }
22039
22040            final long origId = Binder.clearCallingIdentity();
22041            try {
22042                if (values != null) {
22043                    Settings.System.clearConfiguration(values);
22044                }
22045                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
22046                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
22047                return mTmpUpdateConfigurationResult.changes != 0;
22048            } finally {
22049                Binder.restoreCallingIdentity(origId);
22050            }
22051        }
22052    }
22053
22054    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
22055            boolean deferResume, int displayId) {
22056        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
22057                displayId, null /* result */);
22058    }
22059
22060    /**
22061     * Updates override configuration specific for the selected display. If no config is provided,
22062     * new one will be computed in WM based on current display info.
22063     */
22064    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
22065            ActivityRecord starting, boolean deferResume, int displayId,
22066            UpdateConfigurationResult result) {
22067        int changes = 0;
22068        boolean kept = true;
22069
22070        if (mWindowManager != null) {
22071            mWindowManager.deferSurfaceLayout();
22072        }
22073        try {
22074            if (values != null) {
22075                if (displayId == DEFAULT_DISPLAY) {
22076                    // Override configuration of the default display duplicates global config, so
22077                    // we're calling global config update instead for default display. It will also
22078                    // apply the correct override config.
22079                    changes = updateGlobalConfiguration(values, false /* initLocale */,
22080                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
22081                } else {
22082                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
22083                }
22084            }
22085
22086            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22087        } finally {
22088            if (mWindowManager != null) {
22089                mWindowManager.continueSurfaceLayout();
22090            }
22091        }
22092
22093        if (result != null) {
22094            result.changes = changes;
22095            result.activityRelaunched = !kept;
22096        }
22097        return kept;
22098    }
22099
22100    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
22101            int displayId) {
22102        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
22103        final int changes = mTempConfig.updateFrom(values);
22104        if (changes != 0) {
22105            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
22106                    + mTempConfig + " for displayId=" + displayId);
22107            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
22108
22109            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
22110            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
22111                mAppWarnings.onDensityChanged();
22112
22113                killAllBackgroundProcessesExcept(N,
22114                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
22115            }
22116        }
22117
22118        // Update the configuration with WM first and check if any of the stacks need to be resized
22119        // due to the configuration change. If so, resize the stacks now and do any relaunches if
22120        // necessary. This way we don't need to relaunch again afterwards in
22121        // ensureActivityConfigurationLocked().
22122        if (mWindowManager != null) {
22123            final int[] resizedStacks =
22124                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
22125            if (resizedStacks != null) {
22126                for (int stackId : resizedStacks) {
22127                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
22128                }
22129            }
22130        }
22131
22132        return changes;
22133    }
22134
22135    /** Applies latest configuration and/or visibility updates if needed. */
22136    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
22137        boolean kept = true;
22138        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
22139        // mainStack is null during startup.
22140        if (mainStack != null) {
22141            if (changes != 0 && starting == null) {
22142                // If the configuration changed, and the caller is not already
22143                // in the process of starting an activity, then find the top
22144                // activity to check if its configuration needs to change.
22145                starting = mainStack.topRunningActivityLocked();
22146            }
22147
22148            if (starting != null) {
22149                kept = starting.ensureActivityConfigurationLocked(changes,
22150                        false /* preserveWindow */);
22151                // And we need to make sure at this point that all other activities
22152                // are made visible with the correct configuration.
22153                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
22154                        !PRESERVE_WINDOWS);
22155            }
22156        }
22157
22158        return kept;
22159    }
22160
22161    /** Helper method that requests bounds from WM and applies them to stack. */
22162    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
22163        final Rect newStackBounds = new Rect();
22164        final ActivityStack stack = mStackSupervisor.getStack(stackId);
22165
22166        // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
22167        if (stack == null) {
22168            final StringWriter writer = new StringWriter();
22169            final PrintWriter printWriter = new PrintWriter(writer);
22170            mStackSupervisor.dumpDisplays(printWriter);
22171            printWriter.flush();
22172
22173            Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
22174        }
22175
22176        stack.getBoundsForNewConfiguration(newStackBounds);
22177        mStackSupervisor.resizeStackLocked(
22178                stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
22179                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
22180                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
22181    }
22182
22183    /**
22184     * Decide based on the configuration whether we should show the ANR,
22185     * crash, etc dialogs.  The idea is that if there is no affordance to
22186     * press the on-screen buttons, or the user experience would be more
22187     * greatly impacted than the crash itself, we shouldn't show the dialog.
22188     *
22189     * A thought: SystemUI might also want to get told about this, the Power
22190     * dialog / global actions also might want different behaviors.
22191     */
22192    private static boolean shouldShowDialogs(Configuration config) {
22193        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
22194                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
22195                                   && config.navigation == Configuration.NAVIGATION_NONAV);
22196        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
22197        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
22198                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
22199                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
22200                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
22201        return inputMethodExists && uiModeSupportsDialogs;
22202    }
22203
22204    @Override
22205    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
22206        synchronized (this) {
22207            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
22208            if (srec != null) {
22209                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
22210            }
22211        }
22212        return false;
22213    }
22214
22215    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22216            Intent resultData) {
22217
22218        synchronized (this) {
22219            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22220            if (r != null) {
22221                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22222            }
22223            return false;
22224        }
22225    }
22226
22227    public int getLaunchedFromUid(IBinder activityToken) {
22228        ActivityRecord srec;
22229        synchronized (this) {
22230            srec = ActivityRecord.forTokenLocked(activityToken);
22231        }
22232        if (srec == null) {
22233            return -1;
22234        }
22235        return srec.launchedFromUid;
22236    }
22237
22238    public String getLaunchedFromPackage(IBinder activityToken) {
22239        ActivityRecord srec;
22240        synchronized (this) {
22241            srec = ActivityRecord.forTokenLocked(activityToken);
22242        }
22243        if (srec == null) {
22244            return null;
22245        }
22246        return srec.launchedFromPackage;
22247    }
22248
22249    // =========================================================
22250    // LIFETIME MANAGEMENT
22251    // =========================================================
22252
22253    // Returns whether the app is receiving broadcast.
22254    // If receiving, fetch all broadcast queues which the app is
22255    // the current [or imminent] receiver on.
22256    private boolean isReceivingBroadcastLocked(ProcessRecord app,
22257            ArraySet<BroadcastQueue> receivingQueues) {
22258        final int N = app.curReceivers.size();
22259        if (N > 0) {
22260            for (int i = 0; i < N; i++) {
22261                receivingQueues.add(app.curReceivers.valueAt(i).queue);
22262            }
22263            return true;
22264        }
22265
22266        // It's not the current receiver, but it might be starting up to become one
22267        for (BroadcastQueue queue : mBroadcastQueues) {
22268            final BroadcastRecord r = queue.mPendingBroadcast;
22269            if (r != null && r.curApp == app) {
22270                // found it; report which queue it's in
22271                receivingQueues.add(queue);
22272            }
22273        }
22274
22275        return !receivingQueues.isEmpty();
22276    }
22277
22278    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
22279            int targetUid, ComponentName targetComponent, String targetProcess) {
22280        if (!mTrackingAssociations) {
22281            return null;
22282        }
22283        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22284                = mAssociations.get(targetUid);
22285        if (components == null) {
22286            components = new ArrayMap<>();
22287            mAssociations.put(targetUid, components);
22288        }
22289        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22290        if (sourceUids == null) {
22291            sourceUids = new SparseArray<>();
22292            components.put(targetComponent, sourceUids);
22293        }
22294        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22295        if (sourceProcesses == null) {
22296            sourceProcesses = new ArrayMap<>();
22297            sourceUids.put(sourceUid, sourceProcesses);
22298        }
22299        Association ass = sourceProcesses.get(sourceProcess);
22300        if (ass == null) {
22301            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
22302                    targetProcess);
22303            sourceProcesses.put(sourceProcess, ass);
22304        }
22305        ass.mCount++;
22306        ass.mNesting++;
22307        if (ass.mNesting == 1) {
22308            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
22309            ass.mLastState = sourceState;
22310        }
22311        return ass;
22312    }
22313
22314    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
22315            ComponentName targetComponent) {
22316        if (!mTrackingAssociations) {
22317            return;
22318        }
22319        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22320                = mAssociations.get(targetUid);
22321        if (components == null) {
22322            return;
22323        }
22324        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22325        if (sourceUids == null) {
22326            return;
22327        }
22328        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22329        if (sourceProcesses == null) {
22330            return;
22331        }
22332        Association ass = sourceProcesses.get(sourceProcess);
22333        if (ass == null || ass.mNesting <= 0) {
22334            return;
22335        }
22336        ass.mNesting--;
22337        if (ass.mNesting == 0) {
22338            long uptime = SystemClock.uptimeMillis();
22339            ass.mTime += uptime - ass.mStartTime;
22340            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22341                    += uptime - ass.mLastStateUptime;
22342            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
22343        }
22344    }
22345
22346    private void noteUidProcessState(final int uid, final int state) {
22347        mBatteryStatsService.noteUidProcessState(uid, state);
22348        if (mTrackingAssociations) {
22349            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
22350                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
22351                        = mAssociations.valueAt(i1);
22352                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
22353                    SparseArray<ArrayMap<String, Association>> sourceUids
22354                            = targetComponents.valueAt(i2);
22355                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
22356                    if (sourceProcesses != null) {
22357                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
22358                            Association ass = sourceProcesses.valueAt(i4);
22359                            if (ass.mNesting >= 1) {
22360                                // currently associated
22361                                long uptime = SystemClock.uptimeMillis();
22362                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22363                                        += uptime - ass.mLastStateUptime;
22364                                ass.mLastState = state;
22365                                ass.mLastStateUptime = uptime;
22366                            }
22367                        }
22368                    }
22369                }
22370            }
22371        }
22372    }
22373
22374    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
22375            boolean doingAll, long now) {
22376        if (mAdjSeq == app.adjSeq) {
22377            // This adjustment has already been computed.
22378            return app.curRawAdj;
22379        }
22380
22381        if (app.thread == null) {
22382            app.adjSeq = mAdjSeq;
22383            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22384            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22385            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
22386        }
22387
22388        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
22389        app.adjSource = null;
22390        app.adjTarget = null;
22391        app.empty = false;
22392        app.cached = false;
22393
22394        final int activitiesSize = app.activities.size();
22395
22396        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
22397            // The max adjustment doesn't allow this app to be anything
22398            // below foreground, so it is not worth doing work for it.
22399            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
22400            app.adjType = "fixed";
22401            app.adjSeq = mAdjSeq;
22402            app.curRawAdj = app.maxAdj;
22403            app.foregroundActivities = false;
22404            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22405            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
22406            // System processes can do UI, and when they do we want to have
22407            // them trim their memory after the user leaves the UI.  To
22408            // facilitate this, here we need to determine whether or not it
22409            // is currently showing UI.
22410            app.systemNoUi = true;
22411            if (app == TOP_APP) {
22412                app.systemNoUi = false;
22413                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22414                app.adjType = "pers-top-activity";
22415            } else if (app.hasTopUi) {
22416                app.systemNoUi = false;
22417                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22418                app.adjType = "pers-top-ui";
22419            } else if (activitiesSize > 0) {
22420                for (int j = 0; j < activitiesSize; j++) {
22421                    final ActivityRecord r = app.activities.get(j);
22422                    if (r.visible) {
22423                        app.systemNoUi = false;
22424                    }
22425                }
22426            }
22427            if (!app.systemNoUi) {
22428                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
22429            }
22430            return (app.curAdj=app.maxAdj);
22431        }
22432
22433        app.systemNoUi = false;
22434
22435        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
22436
22437        // Determine the importance of the process, starting with most
22438        // important to least, and assign an appropriate OOM adjustment.
22439        int adj;
22440        int schedGroup;
22441        int procState;
22442        boolean foregroundActivities = false;
22443        mTmpBroadcastQueue.clear();
22444        if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
22445            // The last app on the list is the foreground app.
22446            adj = ProcessList.FOREGROUND_APP_ADJ;
22447            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22448            app.adjType = "top-activity";
22449            foregroundActivities = true;
22450            procState = PROCESS_STATE_CUR_TOP;
22451            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22452        } else if (app.instr != null) {
22453            // Don't want to kill running instrumentation.
22454            adj = ProcessList.FOREGROUND_APP_ADJ;
22455            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22456            app.adjType = "instrumentation";
22457            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22458            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
22459        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
22460            // An app that is currently receiving a broadcast also
22461            // counts as being in the foreground for OOM killer purposes.
22462            // It's placed in a sched group based on the nature of the
22463            // broadcast as reflected by which queue it's active in.
22464            adj = ProcessList.FOREGROUND_APP_ADJ;
22465            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
22466                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22467            app.adjType = "broadcast";
22468            procState = ActivityManager.PROCESS_STATE_RECEIVER;
22469            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
22470        } else if (app.executingServices.size() > 0) {
22471            // An app that is currently executing a service callback also
22472            // counts as being in the foreground.
22473            adj = ProcessList.FOREGROUND_APP_ADJ;
22474            schedGroup = app.execServicesFg ?
22475                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22476            app.adjType = "exec-service";
22477            procState = ActivityManager.PROCESS_STATE_SERVICE;
22478            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
22479            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
22480        } else if (app == TOP_APP) {
22481            adj = ProcessList.FOREGROUND_APP_ADJ;
22482            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22483            app.adjType = "top-sleeping";
22484            foregroundActivities = true;
22485            procState = PROCESS_STATE_CUR_TOP;
22486            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22487        } else {
22488            // As far as we know the process is empty.  We may change our mind later.
22489            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22490            // At this point we don't actually know the adjustment.  Use the cached adj
22491            // value that the caller wants us to.
22492            adj = cachedAdj;
22493            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22494            app.cached = true;
22495            app.empty = true;
22496            app.adjType = "cch-empty";
22497            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
22498        }
22499
22500        // Examine all activities if not already foreground.
22501        if (!foregroundActivities && activitiesSize > 0) {
22502            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
22503            for (int j = 0; j < activitiesSize; j++) {
22504                final ActivityRecord r = app.activities.get(j);
22505                if (r.app != app) {
22506                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
22507                            + " instead of expected " + app);
22508                    if (r.app == null || (r.app.uid == app.uid)) {
22509                        // Only fix things up when they look sane
22510                        r.setProcess(app);
22511                    } else {
22512                        continue;
22513                    }
22514                }
22515                if (r.visible) {
22516                    // App has a visible activity; only upgrade adjustment.
22517                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
22518                        adj = ProcessList.VISIBLE_APP_ADJ;
22519                        app.adjType = "vis-activity";
22520                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22521                    }
22522                    if (procState > PROCESS_STATE_CUR_TOP) {
22523                        procState = PROCESS_STATE_CUR_TOP;
22524                        app.adjType = "vis-activity";
22525                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22526                    }
22527                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22528                    app.cached = false;
22529                    app.empty = false;
22530                    foregroundActivities = true;
22531                    final TaskRecord task = r.getTask();
22532                    if (task != null && minLayer > 0) {
22533                        final int layer = task.mLayerRank;
22534                        if (layer >= 0 && minLayer > layer) {
22535                            minLayer = layer;
22536                        }
22537                    }
22538                    break;
22539                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
22540                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22541                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22542                        app.adjType = "pause-activity";
22543                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22544                    }
22545                    if (procState > PROCESS_STATE_CUR_TOP) {
22546                        procState = PROCESS_STATE_CUR_TOP;
22547                        app.adjType = "pause-activity";
22548                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22549                    }
22550                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22551                    app.cached = false;
22552                    app.empty = false;
22553                    foregroundActivities = true;
22554                } else if (r.state == ActivityState.STOPPING) {
22555                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22556                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22557                        app.adjType = "stop-activity";
22558                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22559                    }
22560                    // For the process state, we will at this point consider the
22561                    // process to be cached.  It will be cached either as an activity
22562                    // or empty depending on whether the activity is finishing.  We do
22563                    // this so that we can treat the process as cached for purposes of
22564                    // memory trimming (determing current memory level, trim command to
22565                    // send to process) since there can be an arbitrary number of stopping
22566                    // processes and they should soon all go into the cached state.
22567                    if (!r.finishing) {
22568                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22569                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22570                            app.adjType = "stop-activity";
22571                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22572                        }
22573                    }
22574                    app.cached = false;
22575                    app.empty = false;
22576                    foregroundActivities = true;
22577                } else {
22578                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22579                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
22580                        app.adjType = "cch-act";
22581                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
22582                    }
22583                }
22584            }
22585            if (adj == ProcessList.VISIBLE_APP_ADJ) {
22586                adj += minLayer;
22587            }
22588        }
22589        if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
22590            procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
22591            app.adjType = "cch-rec";
22592            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached recent: " + app);
22593        }
22594
22595        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22596                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
22597            if (app.foregroundServices) {
22598                // The user is aware of this app, so make it visible.
22599                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22600                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22601                app.cached = false;
22602                app.adjType = "fg-service";
22603                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22604                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
22605            } else if (app.hasOverlayUi) {
22606                // The process is display an overlay UI.
22607                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22608                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22609                app.cached = false;
22610                app.adjType = "has-overlay-ui";
22611                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22612                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
22613            }
22614        }
22615
22616        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22617                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22618            if (app.forcingToImportant != null) {
22619                // This is currently used for toasts...  they are not interactive, and
22620                // we don't want them to cause the app to become fully foreground (and
22621                // thus out of background check), so we yes the best background level we can.
22622                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22623                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22624                app.cached = false;
22625                app.adjType = "force-imp";
22626                app.adjSource = app.forcingToImportant;
22627                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22628                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
22629            }
22630        }
22631
22632        if (app == mHeavyWeightProcess) {
22633            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
22634                // We don't want to kill the current heavy-weight process.
22635                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
22636                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22637                app.cached = false;
22638                app.adjType = "heavy";
22639                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22640            }
22641            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22642                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
22643                app.adjType = "heavy";
22644                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22645            }
22646        }
22647
22648        if (app == mHomeProcess) {
22649            if (adj > ProcessList.HOME_APP_ADJ) {
22650                // This process is hosting what we currently consider to be the
22651                // home app, so we don't want to let it go into the background.
22652                adj = ProcessList.HOME_APP_ADJ;
22653                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22654                app.cached = false;
22655                app.adjType = "home";
22656                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22657            }
22658            if (procState > ActivityManager.PROCESS_STATE_HOME) {
22659                procState = ActivityManager.PROCESS_STATE_HOME;
22660                app.adjType = "home";
22661                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22662            }
22663        }
22664
22665        if (app == mPreviousProcess && app.activities.size() > 0) {
22666            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
22667                // This was the previous process that showed UI to the user.
22668                // We want to try to keep it around more aggressively, to give
22669                // a good experience around switching between two apps.
22670                adj = ProcessList.PREVIOUS_APP_ADJ;
22671                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22672                app.cached = false;
22673                app.adjType = "previous";
22674                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
22675            }
22676            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22677                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22678                app.adjType = "previous";
22679                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
22680            }
22681        }
22682
22683        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
22684                + " reason=" + app.adjType);
22685
22686        // By default, we use the computed adjustment.  It may be changed if
22687        // there are applications dependent on our services or providers, but
22688        // this gives us a baseline and makes sure we don't get into an
22689        // infinite recursion.
22690        app.adjSeq = mAdjSeq;
22691        app.curRawAdj = adj;
22692        app.hasStartedServices = false;
22693
22694        if (mBackupTarget != null && app == mBackupTarget.app) {
22695            // If possible we want to avoid killing apps while they're being backed up
22696            if (adj > ProcessList.BACKUP_APP_ADJ) {
22697                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
22698                adj = ProcessList.BACKUP_APP_ADJ;
22699                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22700                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22701                }
22702                app.adjType = "backup";
22703                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22704                app.cached = false;
22705            }
22706            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
22707                procState = ActivityManager.PROCESS_STATE_BACKUP;
22708                app.adjType = "backup";
22709                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22710            }
22711        }
22712
22713        boolean mayBeTop = false;
22714        String mayBeTopType = null;
22715        Object mayBeTopSource = null;
22716        Object mayBeTopTarget = null;
22717
22718        for (int is = app.services.size()-1;
22719                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22720                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22721                        || procState > ActivityManager.PROCESS_STATE_TOP);
22722                is--) {
22723            ServiceRecord s = app.services.valueAt(is);
22724            if (s.startRequested) {
22725                app.hasStartedServices = true;
22726                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
22727                    procState = ActivityManager.PROCESS_STATE_SERVICE;
22728                    app.adjType = "started-services";
22729                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
22730                }
22731                if (app.hasShownUi && app != mHomeProcess) {
22732                    // If this process has shown some UI, let it immediately
22733                    // go to the LRU list because it may be pretty heavy with
22734                    // UI stuff.  We'll tag it with a label just to help
22735                    // debug and understand what is going on.
22736                    if (adj > ProcessList.SERVICE_ADJ) {
22737                        app.adjType = "cch-started-ui-services";
22738                    }
22739                } else {
22740                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
22741                        // This service has seen some activity within
22742                        // recent memory, so we will keep its process ahead
22743                        // of the background processes.
22744                        if (adj > ProcessList.SERVICE_ADJ) {
22745                            adj = ProcessList.SERVICE_ADJ;
22746                            app.adjType = "started-services";
22747                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
22748                            app.cached = false;
22749                        }
22750                    }
22751                    // If we have let the service slide into the background
22752                    // state, still have some text describing what it is doing
22753                    // even though the service no longer has an impact.
22754                    if (adj > ProcessList.SERVICE_ADJ) {
22755                        app.adjType = "cch-started-services";
22756                    }
22757                }
22758            }
22759
22760            for (int conni = s.connections.size()-1;
22761                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22762                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22763                            || procState > ActivityManager.PROCESS_STATE_TOP);
22764                    conni--) {
22765                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
22766                for (int i = 0;
22767                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
22768                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22769                                || procState > ActivityManager.PROCESS_STATE_TOP);
22770                        i++) {
22771                    // XXX should compute this based on the max of
22772                    // all connected clients.
22773                    ConnectionRecord cr = clist.get(i);
22774                    if (cr.binding.client == app) {
22775                        // Binding to ourself is not interesting.
22776                        continue;
22777                    }
22778
22779                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
22780                        ProcessRecord client = cr.binding.client;
22781                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
22782                                TOP_APP, doingAll, now);
22783                        int clientProcState = client.curProcState;
22784                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22785                            // If the other app is cached for any reason, for purposes here
22786                            // we are going to consider it empty.  The specific cached state
22787                            // doesn't propagate except under certain conditions.
22788                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22789                        }
22790                        String adjType = null;
22791                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
22792                            // Not doing bind OOM management, so treat
22793                            // this guy more like a started service.
22794                            if (app.hasShownUi && app != mHomeProcess) {
22795                                // If this process has shown some UI, let it immediately
22796                                // go to the LRU list because it may be pretty heavy with
22797                                // UI stuff.  We'll tag it with a label just to help
22798                                // debug and understand what is going on.
22799                                if (adj > clientAdj) {
22800                                    adjType = "cch-bound-ui-services";
22801                                }
22802                                app.cached = false;
22803                                clientAdj = adj;
22804                                clientProcState = procState;
22805                            } else {
22806                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
22807                                    // This service has not seen activity within
22808                                    // recent memory, so allow it to drop to the
22809                                    // LRU list if there is no other reason to keep
22810                                    // it around.  We'll also tag it with a label just
22811                                    // to help debug and undertand what is going on.
22812                                    if (adj > clientAdj) {
22813                                        adjType = "cch-bound-services";
22814                                    }
22815                                    clientAdj = adj;
22816                                }
22817                            }
22818                        }
22819                        if (adj > clientAdj) {
22820                            // If this process has recently shown UI, and
22821                            // the process that is binding to it is less
22822                            // important than being visible, then we don't
22823                            // care about the binding as much as we care
22824                            // about letting this process get into the LRU
22825                            // list to be killed and restarted if needed for
22826                            // memory.
22827                            if (app.hasShownUi && app != mHomeProcess
22828                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22829                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
22830                                    adjType = "cch-bound-ui-services";
22831                                }
22832                            } else {
22833                                int newAdj;
22834                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
22835                                        |Context.BIND_IMPORTANT)) != 0) {
22836                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
22837                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
22838                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
22839                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
22840                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22841                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
22842                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
22843                                    newAdj = clientAdj;
22844                                } else {
22845                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
22846                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
22847                                    } else {
22848                                        newAdj = adj;
22849                                    }
22850                                }
22851                                if (!client.cached) {
22852                                    app.cached = false;
22853                                }
22854                                if (adj >  newAdj) {
22855                                    adj = newAdj;
22856                                    adjType = "service";
22857                                }
22858                            }
22859                        }
22860                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
22861                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
22862                            // This will treat important bound services identically to
22863                            // the top app, which may behave differently than generic
22864                            // foreground work.
22865                            if (client.curSchedGroup > schedGroup) {
22866                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
22867                                    schedGroup = client.curSchedGroup;
22868                                } else {
22869                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22870                                }
22871                            }
22872                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
22873                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
22874                                    // Special handling of clients who are in the top state.
22875                                    // We *may* want to consider this process to be in the
22876                                    // top state as well, but only if there is not another
22877                                    // reason for it to be running.  Being on the top is a
22878                                    // special state, meaning you are specifically running
22879                                    // for the current top app.  If the process is already
22880                                    // running in the background for some other reason, it
22881                                    // is more important to continue considering it to be
22882                                    // in the background state.
22883                                    mayBeTop = true;
22884                                    mayBeTopType = "service";
22885                                    mayBeTopSource = cr.binding.client;
22886                                    mayBeTopTarget = s.name;
22887                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22888                                } else {
22889                                    // Special handling for above-top states (persistent
22890                                    // processes).  These should not bring the current process
22891                                    // into the top state, since they are not on top.  Instead
22892                                    // give them the best state after that.
22893                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
22894                                        clientProcState =
22895                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22896                                    } else if (mWakefulness
22897                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
22898                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
22899                                                    != 0) {
22900                                        clientProcState =
22901                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22902                                    } else {
22903                                        clientProcState =
22904                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22905                                    }
22906                                }
22907                            }
22908                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
22909                            if (clientProcState <
22910                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22911                                clientProcState =
22912                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22913                            }
22914                        } else {
22915                            if (clientProcState <
22916                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
22917                                clientProcState =
22918                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
22919                            }
22920                        }
22921                        if (procState > clientProcState) {
22922                            procState = clientProcState;
22923                            if (adjType == null) {
22924                                adjType = "service";
22925                            }
22926                        }
22927                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22928                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
22929                            app.pendingUiClean = true;
22930                        }
22931                        if (adjType != null) {
22932                            app.adjType = adjType;
22933                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
22934                                    .REASON_SERVICE_IN_USE;
22935                            app.adjSource = cr.binding.client;
22936                            app.adjSourceProcState = clientProcState;
22937                            app.adjTarget = s.name;
22938                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
22939                                    + ": " + app + ", due to " + cr.binding.client
22940                                    + " adj=" + adj + " procState=" + procState);
22941                        }
22942                    }
22943                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
22944                        app.treatLikeActivity = true;
22945                    }
22946                    final ActivityRecord a = cr.activity;
22947                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
22948                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
22949                            (a.visible || a.state == ActivityState.RESUMED ||
22950                             a.state == ActivityState.PAUSING)) {
22951                            adj = ProcessList.FOREGROUND_APP_ADJ;
22952                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
22953                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
22954                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
22955                                } else {
22956                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22957                                }
22958                            }
22959                            app.cached = false;
22960                            app.adjType = "service";
22961                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
22962                                    .REASON_SERVICE_IN_USE;
22963                            app.adjSource = a;
22964                            app.adjSourceProcState = procState;
22965                            app.adjTarget = s.name;
22966                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
22967                                    + app);
22968                        }
22969                    }
22970                }
22971            }
22972        }
22973
22974        for (int provi = app.pubProviders.size()-1;
22975                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22976                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22977                        || procState > ActivityManager.PROCESS_STATE_TOP);
22978                provi--) {
22979            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
22980            for (int i = cpr.connections.size()-1;
22981                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22982                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22983                            || procState > ActivityManager.PROCESS_STATE_TOP);
22984                    i--) {
22985                ContentProviderConnection conn = cpr.connections.get(i);
22986                ProcessRecord client = conn.client;
22987                if (client == app) {
22988                    // Being our own client is not interesting.
22989                    continue;
22990                }
22991                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
22992                int clientProcState = client.curProcState;
22993                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22994                    // If the other app is cached for any reason, for purposes here
22995                    // we are going to consider it empty.
22996                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22997                }
22998                String adjType = null;
22999                if (adj > clientAdj) {
23000                    if (app.hasShownUi && app != mHomeProcess
23001                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23002                        adjType = "cch-ui-provider";
23003                    } else {
23004                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
23005                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
23006                        adjType = "provider";
23007                    }
23008                    app.cached &= client.cached;
23009                }
23010                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23011                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23012                        // Special handling of clients who are in the top state.
23013                        // We *may* want to consider this process to be in the
23014                        // top state as well, but only if there is not another
23015                        // reason for it to be running.  Being on the top is a
23016                        // special state, meaning you are specifically running
23017                        // for the current top app.  If the process is already
23018                        // running in the background for some other reason, it
23019                        // is more important to continue considering it to be
23020                        // in the background state.
23021                        mayBeTop = true;
23022                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23023                        mayBeTopType = adjType = "provider-top";
23024                        mayBeTopSource = client;
23025                        mayBeTopTarget = cpr.name;
23026                    } else {
23027                        // Special handling for above-top states (persistent
23028                        // processes).  These should not bring the current process
23029                        // into the top state, since they are not on top.  Instead
23030                        // give them the best state after that.
23031                        clientProcState =
23032                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23033                        if (adjType == null) {
23034                            adjType = "provider";
23035                        }
23036                    }
23037                }
23038                if (procState > clientProcState) {
23039                    procState = clientProcState;
23040                }
23041                if (client.curSchedGroup > schedGroup) {
23042                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23043                }
23044                if (adjType != null) {
23045                    app.adjType = adjType;
23046                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23047                            .REASON_PROVIDER_IN_USE;
23048                    app.adjSource = client;
23049                    app.adjSourceProcState = clientProcState;
23050                    app.adjTarget = cpr.name;
23051                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
23052                            + ": " + app + ", due to " + client
23053                            + " adj=" + adj + " procState=" + procState);
23054                }
23055            }
23056            // If the provider has external (non-framework) process
23057            // dependencies, ensure that its adjustment is at least
23058            // FOREGROUND_APP_ADJ.
23059            if (cpr.hasExternalProcessHandles()) {
23060                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
23061                    adj = ProcessList.FOREGROUND_APP_ADJ;
23062                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23063                    app.cached = false;
23064                    app.adjType = "ext-provider";
23065                    app.adjTarget = cpr.name;
23066                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
23067                }
23068                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23069                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23070                }
23071            }
23072        }
23073
23074        if (app.lastProviderTime > 0 &&
23075                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
23076            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23077                adj = ProcessList.PREVIOUS_APP_ADJ;
23078                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23079                app.cached = false;
23080                app.adjType = "recent-provider";
23081                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
23082            }
23083            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23084                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23085                app.adjType = "recent-provider";
23086                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
23087            }
23088        }
23089
23090        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
23091            // A client of one of our services or providers is in the top state.  We
23092            // *may* want to be in the top state, but not if we are already running in
23093            // the background for some other reason.  For the decision here, we are going
23094            // to pick out a few specific states that we want to remain in when a client
23095            // is top (states that tend to be longer-term) and otherwise allow it to go
23096            // to the top state.
23097            switch (procState) {
23098                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
23099                case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
23100                    // Something else is keeping it at this level, just leave it.
23101                    break;
23102                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
23103                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
23104                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
23105                case ActivityManager.PROCESS_STATE_SERVICE:
23106                    // These all are longer-term states, so pull them up to the top
23107                    // of the background states, but not all the way to the top state.
23108                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23109                    app.adjType = mayBeTopType;
23110                    app.adjSource = mayBeTopSource;
23111                    app.adjTarget = mayBeTopTarget;
23112                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
23113                            + ": " + app + ", due to " + mayBeTopSource
23114                            + " adj=" + adj + " procState=" + procState);
23115                    break;
23116                default:
23117                    // Otherwise, top is a better choice, so take it.
23118                    procState = ActivityManager.PROCESS_STATE_TOP;
23119                    app.adjType = mayBeTopType;
23120                    app.adjSource = mayBeTopSource;
23121                    app.adjTarget = mayBeTopTarget;
23122                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
23123                            + ": " + app + ", due to " + mayBeTopSource
23124                            + " adj=" + adj + " procState=" + procState);
23125                    break;
23126            }
23127        }
23128
23129        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
23130            if (app.hasClientActivities) {
23131                // This is a cached process, but with client activities.  Mark it so.
23132                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
23133                app.adjType = "cch-client-act";
23134            } else if (app.treatLikeActivity) {
23135                // This is a cached process, but somebody wants us to treat it like it has
23136                // an activity, okay!
23137                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23138                app.adjType = "cch-as-act";
23139            }
23140        }
23141
23142        if (adj == ProcessList.SERVICE_ADJ) {
23143            if (doingAll) {
23144                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
23145                mNewNumServiceProcs++;
23146                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
23147                if (!app.serviceb) {
23148                    // This service isn't far enough down on the LRU list to
23149                    // normally be a B service, but if we are low on RAM and it
23150                    // is large we want to force it down since we would prefer to
23151                    // keep launcher over it.
23152                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
23153                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
23154                        app.serviceHighRam = true;
23155                        app.serviceb = true;
23156                        //Slog.i(TAG, "ADJ " + app + " high ram!");
23157                    } else {
23158                        mNewNumAServiceProcs++;
23159                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
23160                    }
23161                } else {
23162                    app.serviceHighRam = false;
23163                }
23164            }
23165            if (app.serviceb) {
23166                adj = ProcessList.SERVICE_B_ADJ;
23167            }
23168        }
23169
23170        app.curRawAdj = adj;
23171
23172        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
23173        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
23174        if (adj > app.maxAdj) {
23175            adj = app.maxAdj;
23176            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
23177                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23178            }
23179        }
23180
23181        // Do final modification to adj.  Everything we do between here and applying
23182        // the final setAdj must be done in this function, because we will also use
23183        // it when computing the final cached adj later.  Note that we don't need to
23184        // worry about this for max adj above, since max adj will always be used to
23185        // keep it out of the cached vaues.
23186        app.curAdj = app.modifyRawOomAdj(adj);
23187        app.curSchedGroup = schedGroup;
23188        app.curProcState = procState;
23189        app.foregroundActivities = foregroundActivities;
23190
23191        return app.curRawAdj;
23192    }
23193
23194    /**
23195     * Record new PSS sample for a process.
23196     */
23197    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
23198            long rss, int statType, long pssDuration, long now) {
23199        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
23200                swapPss * 1024, rss * 1024, statType, procState, pssDuration);
23201        proc.lastPssTime = now;
23202        proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
23203        if (DEBUG_PSS) Slog.d(TAG_PSS,
23204                "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
23205                + " state=" + ProcessList.makeProcStateString(procState));
23206        if (proc.initialIdlePss == 0) {
23207            proc.initialIdlePss = pss;
23208        }
23209        proc.lastPss = pss;
23210        proc.lastSwapPss = swapPss;
23211        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
23212            proc.lastCachedPss = pss;
23213            proc.lastCachedSwapPss = swapPss;
23214        }
23215
23216        final SparseArray<Pair<Long, String>> watchUids
23217                = mMemWatchProcesses.getMap().get(proc.processName);
23218        Long check = null;
23219        if (watchUids != null) {
23220            Pair<Long, String> val = watchUids.get(proc.uid);
23221            if (val == null) {
23222                val = watchUids.get(0);
23223            }
23224            if (val != null) {
23225                check = val.first;
23226            }
23227        }
23228        if (check != null) {
23229            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
23230                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23231                if (!isDebuggable) {
23232                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
23233                        isDebuggable = true;
23234                    }
23235                }
23236                if (isDebuggable) {
23237                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
23238                    final ProcessRecord myProc = proc;
23239                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
23240                    mMemWatchDumpProcName = proc.processName;
23241                    mMemWatchDumpFile = heapdumpFile.toString();
23242                    mMemWatchDumpPid = proc.pid;
23243                    mMemWatchDumpUid = proc.uid;
23244                    BackgroundThread.getHandler().post(new Runnable() {
23245                        @Override
23246                        public void run() {
23247                            revokeUriPermission(ActivityThread.currentActivityThread()
23248                                            .getApplicationThread(),
23249                                    null, DumpHeapActivity.JAVA_URI,
23250                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
23251                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
23252                                    UserHandle.myUserId());
23253                            ParcelFileDescriptor fd = null;
23254                            try {
23255                                heapdumpFile.delete();
23256                                fd = ParcelFileDescriptor.open(heapdumpFile,
23257                                        ParcelFileDescriptor.MODE_CREATE |
23258                                                ParcelFileDescriptor.MODE_TRUNCATE |
23259                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
23260                                                ParcelFileDescriptor.MODE_APPEND);
23261                                IApplicationThread thread = myProc.thread;
23262                                if (thread != null) {
23263                                    try {
23264                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
23265                                                "Requesting dump heap from "
23266                                                + myProc + " to " + heapdumpFile);
23267                                        thread.dumpHeap(/* managed= */ true,
23268                                                /* mallocInfo= */ false, /* runGc= */ false,
23269                                                heapdumpFile.toString(), fd);
23270                                    } catch (RemoteException e) {
23271                                    }
23272                                }
23273                            } catch (FileNotFoundException e) {
23274                                e.printStackTrace();
23275                            } finally {
23276                                if (fd != null) {
23277                                    try {
23278                                        fd.close();
23279                                    } catch (IOException e) {
23280                                    }
23281                                }
23282                            }
23283                        }
23284                    });
23285                } else {
23286                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
23287                            + ", but debugging not enabled");
23288                }
23289            }
23290        }
23291    }
23292
23293    /**
23294     * Schedule PSS collection of a process.
23295     */
23296    void requestPssLocked(ProcessRecord proc, int procState) {
23297        if (mPendingPssProcesses.contains(proc)) {
23298            return;
23299        }
23300        if (mPendingPssProcesses.size() == 0) {
23301            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23302        }
23303        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
23304        proc.pssProcState = procState;
23305        proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
23306        mPendingPssProcesses.add(proc);
23307    }
23308
23309    /**
23310     * Schedule PSS collection of all processes.
23311     */
23312    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
23313        if (!always) {
23314            if (now < (mLastFullPssTime +
23315                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
23316                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
23317                return;
23318            }
23319        }
23320        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs!  memLowered=" + memLowered);
23321        mLastFullPssTime = now;
23322        mFullPssPending = true;
23323        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
23324        mPendingPssProcesses.clear();
23325        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23326            ProcessRecord app = mLruProcesses.get(i);
23327            if (app.thread == null
23328                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
23329                continue;
23330            }
23331            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
23332                app.pssProcState = app.setProcState;
23333                app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
23334                        : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
23335                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
23336                        app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
23337                mPendingPssProcesses.add(app);
23338            }
23339        }
23340        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23341    }
23342
23343    public void setTestPssMode(boolean enabled) {
23344        synchronized (this) {
23345            mTestPssMode = enabled;
23346            if (enabled) {
23347                // Whenever we enable the mode, we want to take a snapshot all of current
23348                // process mem use.
23349                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
23350            }
23351        }
23352    }
23353
23354    /**
23355     * Ask a given process to GC right now.
23356     */
23357    final void performAppGcLocked(ProcessRecord app) {
23358        try {
23359            app.lastRequestedGc = SystemClock.uptimeMillis();
23360            if (app.thread != null) {
23361                if (app.reportLowMemory) {
23362                    app.reportLowMemory = false;
23363                    app.thread.scheduleLowMemory();
23364                } else {
23365                    app.thread.processInBackground();
23366                }
23367            }
23368        } catch (Exception e) {
23369            // whatever.
23370        }
23371    }
23372
23373    /**
23374     * Returns true if things are idle enough to perform GCs.
23375     */
23376    private final boolean canGcNowLocked() {
23377        boolean processingBroadcasts = false;
23378        for (BroadcastQueue q : mBroadcastQueues) {
23379            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
23380                processingBroadcasts = true;
23381            }
23382        }
23383        return !processingBroadcasts
23384                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
23385    }
23386
23387    /**
23388     * Perform GCs on all processes that are waiting for it, but only
23389     * if things are idle.
23390     */
23391    final void performAppGcsLocked() {
23392        final int N = mProcessesToGc.size();
23393        if (N <= 0) {
23394            return;
23395        }
23396        if (canGcNowLocked()) {
23397            while (mProcessesToGc.size() > 0) {
23398                ProcessRecord proc = mProcessesToGc.remove(0);
23399                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
23400                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
23401                            <= SystemClock.uptimeMillis()) {
23402                        // To avoid spamming the system, we will GC processes one
23403                        // at a time, waiting a few seconds between each.
23404                        performAppGcLocked(proc);
23405                        scheduleAppGcsLocked();
23406                        return;
23407                    } else {
23408                        // It hasn't been long enough since we last GCed this
23409                        // process...  put it in the list to wait for its time.
23410                        addProcessToGcListLocked(proc);
23411                        break;
23412                    }
23413                }
23414            }
23415
23416            scheduleAppGcsLocked();
23417        }
23418    }
23419
23420    /**
23421     * If all looks good, perform GCs on all processes waiting for them.
23422     */
23423    final void performAppGcsIfAppropriateLocked() {
23424        if (canGcNowLocked()) {
23425            performAppGcsLocked();
23426            return;
23427        }
23428        // Still not idle, wait some more.
23429        scheduleAppGcsLocked();
23430    }
23431
23432    /**
23433     * Schedule the execution of all pending app GCs.
23434     */
23435    final void scheduleAppGcsLocked() {
23436        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
23437
23438        if (mProcessesToGc.size() > 0) {
23439            // Schedule a GC for the time to the next process.
23440            ProcessRecord proc = mProcessesToGc.get(0);
23441            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
23442
23443            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
23444            long now = SystemClock.uptimeMillis();
23445            if (when < (now+mConstants.GC_TIMEOUT)) {
23446                when = now + mConstants.GC_TIMEOUT;
23447            }
23448            mHandler.sendMessageAtTime(msg, when);
23449        }
23450    }
23451
23452    /**
23453     * Add a process to the array of processes waiting to be GCed.  Keeps the
23454     * list in sorted order by the last GC time.  The process can't already be
23455     * on the list.
23456     */
23457    final void addProcessToGcListLocked(ProcessRecord proc) {
23458        boolean added = false;
23459        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
23460            if (mProcessesToGc.get(i).lastRequestedGc <
23461                    proc.lastRequestedGc) {
23462                added = true;
23463                mProcessesToGc.add(i+1, proc);
23464                break;
23465            }
23466        }
23467        if (!added) {
23468            mProcessesToGc.add(0, proc);
23469        }
23470    }
23471
23472    /**
23473     * Set up to ask a process to GC itself.  This will either do it
23474     * immediately, or put it on the list of processes to gc the next
23475     * time things are idle.
23476     */
23477    final void scheduleAppGcLocked(ProcessRecord app) {
23478        long now = SystemClock.uptimeMillis();
23479        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
23480            return;
23481        }
23482        if (!mProcessesToGc.contains(app)) {
23483            addProcessToGcListLocked(app);
23484            scheduleAppGcsLocked();
23485        }
23486    }
23487
23488    final void checkExcessivePowerUsageLocked() {
23489        updateCpuStatsNow();
23490
23491        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
23492        boolean doCpuKills = true;
23493        if (mLastPowerCheckUptime == 0) {
23494            doCpuKills = false;
23495        }
23496        final long curUptime = SystemClock.uptimeMillis();
23497        final long uptimeSince = curUptime - mLastPowerCheckUptime;
23498        mLastPowerCheckUptime = curUptime;
23499        int i = mLruProcesses.size();
23500        while (i > 0) {
23501            i--;
23502            ProcessRecord app = mLruProcesses.get(i);
23503            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
23504                if (app.lastCpuTime <= 0) {
23505                    continue;
23506                }
23507                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
23508                if (DEBUG_POWER) {
23509                    StringBuilder sb = new StringBuilder(128);
23510                    sb.append("CPU for ");
23511                    app.toShortString(sb);
23512                    sb.append(": over ");
23513                    TimeUtils.formatDuration(uptimeSince, sb);
23514                    sb.append(" used ");
23515                    TimeUtils.formatDuration(cputimeUsed, sb);
23516                    sb.append(" (");
23517                    sb.append((cputimeUsed*100)/uptimeSince);
23518                    sb.append("%)");
23519                    Slog.i(TAG_POWER, sb.toString());
23520                }
23521                // If the process has used too much CPU over the last duration, the
23522                // user probably doesn't want this, so kill!
23523                if (doCpuKills && uptimeSince > 0) {
23524                    // What is the limit for this process?
23525                    int cpuLimit;
23526                    long checkDur = curUptime - app.whenUnimportant;
23527                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
23528                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
23529                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
23530                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
23531                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
23532                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
23533                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
23534                    } else {
23535                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
23536                    }
23537                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
23538                        synchronized (stats) {
23539                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
23540                                    uptimeSince, cputimeUsed);
23541                        }
23542                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
23543                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
23544                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
23545                    }
23546                }
23547                app.lastCpuTime = app.curCpuTime;
23548            }
23549        }
23550    }
23551
23552    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
23553            long nowElapsed) {
23554        boolean success = true;
23555
23556        if (app.curRawAdj != app.setRawAdj) {
23557            app.setRawAdj = app.curRawAdj;
23558        }
23559
23560        int changes = 0;
23561
23562        if (app.curAdj != app.setAdj) {
23563            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
23564            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
23565                String msg = "Set " + app.pid + " " + app.processName + " adj "
23566                        + app.curAdj + ": " + app.adjType;
23567                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23568            }
23569            app.setAdj = app.curAdj;
23570            app.verifiedAdj = ProcessList.INVALID_ADJ;
23571        }
23572
23573        if (app.setSchedGroup != app.curSchedGroup) {
23574            int oldSchedGroup = app.setSchedGroup;
23575            app.setSchedGroup = app.curSchedGroup;
23576            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
23577                String msg = "Setting sched group of " + app.processName
23578                        + " to " + app.curSchedGroup;
23579                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23580            }
23581            if (app.waitingToKill != null && app.curReceivers.isEmpty()
23582                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
23583                app.kill(app.waitingToKill, true);
23584                success = false;
23585            } else {
23586                int processGroup;
23587                switch (app.curSchedGroup) {
23588                    case ProcessList.SCHED_GROUP_BACKGROUND:
23589                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
23590                        break;
23591                    case ProcessList.SCHED_GROUP_TOP_APP:
23592                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
23593                        processGroup = THREAD_GROUP_TOP_APP;
23594                        break;
23595                    default:
23596                        processGroup = THREAD_GROUP_DEFAULT;
23597                        break;
23598                }
23599                long oldId = Binder.clearCallingIdentity();
23600                try {
23601                    setProcessGroup(app.pid, processGroup);
23602                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
23603                        // do nothing if we already switched to RT
23604                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23605                            mVrController.onTopProcChangedLocked(app);
23606                            if (mUseFifoUiScheduling) {
23607                                // Switch UI pipeline for app to SCHED_FIFO
23608                                app.savedPriority = Process.getThreadPriority(app.pid);
23609                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
23610                                if (app.renderThreadTid != 0) {
23611                                    scheduleAsFifoPriority(app.renderThreadTid,
23612                                        /* suppressLogs */true);
23613                                    if (DEBUG_OOM_ADJ) {
23614                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
23615                                            app.renderThreadTid + ") to FIFO");
23616                                    }
23617                                } else {
23618                                    if (DEBUG_OOM_ADJ) {
23619                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
23620                                    }
23621                                }
23622                            } else {
23623                                // Boost priority for top app UI and render threads
23624                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
23625                                if (app.renderThreadTid != 0) {
23626                                    try {
23627                                        setThreadPriority(app.renderThreadTid,
23628                                                TOP_APP_PRIORITY_BOOST);
23629                                    } catch (IllegalArgumentException e) {
23630                                        // thread died, ignore
23631                                    }
23632                                }
23633                            }
23634                        }
23635                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
23636                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23637                        mVrController.onTopProcChangedLocked(app);
23638                        if (mUseFifoUiScheduling) {
23639                            try {
23640                                // Reset UI pipeline to SCHED_OTHER
23641                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
23642                                setThreadPriority(app.pid, app.savedPriority);
23643                                if (app.renderThreadTid != 0) {
23644                                    setThreadScheduler(app.renderThreadTid,
23645                                        SCHED_OTHER, 0);
23646                                    setThreadPriority(app.renderThreadTid, -4);
23647                                }
23648                            } catch (IllegalArgumentException e) {
23649                                Slog.w(TAG,
23650                                        "Failed to set scheduling policy, thread does not exist:\n"
23651                                                + e);
23652                            } catch (SecurityException e) {
23653                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
23654                            }
23655                        } else {
23656                            // Reset priority for top app UI and render threads
23657                            setThreadPriority(app.pid, 0);
23658                            if (app.renderThreadTid != 0) {
23659                                setThreadPriority(app.renderThreadTid, 0);
23660                            }
23661                        }
23662                    }
23663                } catch (Exception e) {
23664                    if (false) {
23665                        Slog.w(TAG, "Failed setting process group of " + app.pid
23666                                + " to " + app.curSchedGroup);
23667                        Slog.w(TAG, "at location", e);
23668                    }
23669                } finally {
23670                    Binder.restoreCallingIdentity(oldId);
23671                }
23672            }
23673        }
23674        if (app.repForegroundActivities != app.foregroundActivities) {
23675            app.repForegroundActivities = app.foregroundActivities;
23676            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
23677        }
23678        if (app.repProcState != app.curProcState) {
23679            app.repProcState = app.curProcState;
23680            if (app.thread != null) {
23681                try {
23682                    if (false) {
23683                        //RuntimeException h = new RuntimeException("here");
23684                        Slog.i(TAG, "Sending new process state " + app.repProcState
23685                                + " to " + app /*, h*/);
23686                    }
23687                    app.thread.setProcessState(app.repProcState);
23688                } catch (RemoteException e) {
23689                }
23690            }
23691        }
23692        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
23693                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
23694            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
23695                // Experimental code to more aggressively collect pss while
23696                // running test...  the problem is that this tends to collect
23697                // the data right when a process is transitioning between process
23698                // states, which well tend to give noisy data.
23699                long start = SystemClock.uptimeMillis();
23700                long startTime = SystemClock.currentThreadTimeMillis();
23701                long pss = Debug.getPss(app.pid, mTmpLong, null);
23702                long endTime = SystemClock.currentThreadTimeMillis();
23703                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
23704                        mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
23705                mPendingPssProcesses.remove(app);
23706                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
23707                        + " to " + app.curProcState + ": "
23708                        + (SystemClock.uptimeMillis()-start) + "ms");
23709            }
23710            app.lastStateTime = now;
23711            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
23712                    app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
23713            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
23714                    + ProcessList.makeProcStateString(app.setProcState) + " to "
23715                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
23716                    + (app.nextPssTime-now) + ": " + app);
23717        } else {
23718            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
23719                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
23720                    mTestPssMode)))) {
23721                requestPssLocked(app, app.setProcState);
23722                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
23723                        app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
23724            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
23725                    "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
23726        }
23727        if (app.setProcState != app.curProcState) {
23728            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
23729                String msg = "Proc state change of " + app.processName
23730                        + " to " + app.curProcState;
23731                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23732            }
23733            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
23734            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
23735            if (setImportant && !curImportant) {
23736                // This app is no longer something we consider important enough to allow to
23737                // use arbitrary amounts of battery power.  Note
23738                // its current CPU time to later know to kill it if
23739                // it is not behaving well.
23740                app.whenUnimportant = now;
23741                app.lastCpuTime = 0;
23742            }
23743            // Inform UsageStats of important process state change
23744            // Must be called before updating setProcState
23745            maybeUpdateUsageStatsLocked(app, nowElapsed);
23746
23747            app.setProcState = app.curProcState;
23748            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
23749                app.notCachedSinceIdle = false;
23750            }
23751            if (!doingAll) {
23752                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
23753            } else {
23754                app.procStateChanged = true;
23755            }
23756        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
23757                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
23758            // For apps that sit around for a long time in the interactive state, we need
23759            // to report this at least once a day so they don't go idle.
23760            maybeUpdateUsageStatsLocked(app, nowElapsed);
23761        }
23762
23763        if (changes != 0) {
23764            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23765                    "Changes in " + app + ": " + changes);
23766            int i = mPendingProcessChanges.size()-1;
23767            ProcessChangeItem item = null;
23768            while (i >= 0) {
23769                item = mPendingProcessChanges.get(i);
23770                if (item.pid == app.pid) {
23771                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23772                            "Re-using existing item: " + item);
23773                    break;
23774                }
23775                i--;
23776            }
23777            if (i < 0) {
23778                // No existing item in pending changes; need a new one.
23779                final int NA = mAvailProcessChanges.size();
23780                if (NA > 0) {
23781                    item = mAvailProcessChanges.remove(NA-1);
23782                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23783                            "Retrieving available item: " + item);
23784                } else {
23785                    item = new ProcessChangeItem();
23786                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23787                            "Allocating new item: " + item);
23788                }
23789                item.changes = 0;
23790                item.pid = app.pid;
23791                item.uid = app.info.uid;
23792                if (mPendingProcessChanges.size() == 0) {
23793                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23794                            "*** Enqueueing dispatch processes changed!");
23795                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
23796                }
23797                mPendingProcessChanges.add(item);
23798            }
23799            item.changes |= changes;
23800            item.foregroundActivities = app.repForegroundActivities;
23801            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23802                    "Item " + Integer.toHexString(System.identityHashCode(item))
23803                    + " " + app.toShortString() + ": changes=" + item.changes
23804                    + " foreground=" + item.foregroundActivities
23805                    + " type=" + app.adjType + " source=" + app.adjSource
23806                    + " target=" + app.adjTarget);
23807        }
23808
23809        return success;
23810    }
23811
23812    private boolean isEphemeralLocked(int uid) {
23813        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
23814        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
23815            return false;
23816        }
23817        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
23818                packages[0]);
23819    }
23820
23821    @VisibleForTesting
23822    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
23823        final UidRecord.ChangeItem pendingChange;
23824        if (uidRec == null || uidRec.pendingChange == null) {
23825            if (mPendingUidChanges.size() == 0) {
23826                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23827                        "*** Enqueueing dispatch uid changed!");
23828                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
23829            }
23830            final int NA = mAvailUidChanges.size();
23831            if (NA > 0) {
23832                pendingChange = mAvailUidChanges.remove(NA-1);
23833                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23834                        "Retrieving available item: " + pendingChange);
23835            } else {
23836                pendingChange = new UidRecord.ChangeItem();
23837                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23838                        "Allocating new item: " + pendingChange);
23839            }
23840            if (uidRec != null) {
23841                uidRec.pendingChange = pendingChange;
23842                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
23843                    // If this uid is going away, and we haven't yet reported it is gone,
23844                    // then do so now.
23845                    change |= UidRecord.CHANGE_IDLE;
23846                }
23847            } else if (uid < 0) {
23848                throw new IllegalArgumentException("No UidRecord or uid");
23849            }
23850            pendingChange.uidRecord = uidRec;
23851            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
23852            mPendingUidChanges.add(pendingChange);
23853        } else {
23854            pendingChange = uidRec.pendingChange;
23855            // If there is no change in idle or active state, then keep whatever was pending.
23856            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
23857                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
23858                        | UidRecord.CHANGE_ACTIVE));
23859            }
23860            // If there is no change in cached or uncached state, then keep whatever was pending.
23861            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
23862                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
23863                        | UidRecord.CHANGE_UNCACHED));
23864            }
23865            // If this is a report of the UID being gone, then we shouldn't keep any previous
23866            // report of it being active or cached.  (That is, a gone uid is never active,
23867            // and never cached.)
23868            if ((change & UidRecord.CHANGE_GONE) != 0) {
23869                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
23870                if (!uidRec.idle) {
23871                    // If this uid is going away, and we haven't yet reported it is gone,
23872                    // then do so now.
23873                    change |= UidRecord.CHANGE_IDLE;
23874                }
23875            }
23876        }
23877        pendingChange.change = change;
23878        pendingChange.processState = uidRec != null
23879                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
23880        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
23881        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
23882        if (uidRec != null) {
23883            uidRec.lastReportedChange = change;
23884            uidRec.updateLastDispatchedProcStateSeq(change);
23885        }
23886
23887        // Directly update the power manager, since we sit on top of it and it is critical
23888        // it be kept in sync (so wake locks will be held as soon as appropriate).
23889        if (mLocalPowerManager != null) {
23890            // TO DO: dispatch cached/uncached changes here, so we don't need to report
23891            // all proc state changes.
23892            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
23893                mLocalPowerManager.uidActive(pendingChange.uid);
23894            }
23895            if ((change & UidRecord.CHANGE_IDLE) != 0) {
23896                mLocalPowerManager.uidIdle(pendingChange.uid);
23897            }
23898            if ((change & UidRecord.CHANGE_GONE) != 0) {
23899                mLocalPowerManager.uidGone(pendingChange.uid);
23900            } else {
23901                mLocalPowerManager.updateUidProcState(pendingChange.uid,
23902                        pendingChange.processState);
23903            }
23904        }
23905    }
23906
23907    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
23908            String authority) {
23909        if (app == null) return;
23910        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23911            UserState userState = mUserController.getStartedUserState(app.userId);
23912            if (userState == null) return;
23913            final long now = SystemClock.elapsedRealtime();
23914            Long lastReported = userState.mProviderLastReportedFg.get(authority);
23915            if (lastReported == null || lastReported < now - 60 * 1000L) {
23916                if (mSystemReady) {
23917                    // Cannot touch the user stats if not system ready
23918                    mUsageStatsService.reportContentProviderUsage(
23919                            authority, providerPkgName, app.userId);
23920                }
23921                userState.mProviderLastReportedFg.put(authority, now);
23922            }
23923        }
23924    }
23925
23926    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
23927        if (DEBUG_USAGE_STATS) {
23928            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
23929                    + "] state changes: old = " + app.setProcState + ", new = "
23930                    + app.curProcState);
23931        }
23932        if (mUsageStatsService == null) {
23933            return;
23934        }
23935        boolean isInteraction;
23936        // To avoid some abuse patterns, we are going to be careful about what we consider
23937        // to be an app interaction.  Being the top activity doesn't count while the display
23938        // is sleeping, nor do short foreground services.
23939        if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
23940            isInteraction = true;
23941            app.fgInteractionTime = 0;
23942        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
23943            if (app.fgInteractionTime == 0) {
23944                app.fgInteractionTime = nowElapsed;
23945                isInteraction = false;
23946            } else {
23947                isInteraction = nowElapsed > app.fgInteractionTime
23948                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
23949            }
23950        } else {
23951            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23952            app.fgInteractionTime = 0;
23953        }
23954        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
23955                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
23956            app.interactionEventTime = nowElapsed;
23957            String[] packages = app.getPackageList();
23958            if (packages != null) {
23959                for (int i = 0; i < packages.length; i++) {
23960                    mUsageStatsService.reportEvent(packages[i], app.userId,
23961                            UsageEvents.Event.SYSTEM_INTERACTION);
23962                }
23963            }
23964        }
23965        app.reportedInteraction = isInteraction;
23966        if (!isInteraction) {
23967            app.interactionEventTime = 0;
23968        }
23969    }
23970
23971    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
23972        if (proc.thread != null) {
23973            if (proc.baseProcessTracker != null) {
23974                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
23975            }
23976        }
23977    }
23978
23979    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
23980            ProcessRecord TOP_APP, boolean doingAll, long now) {
23981        if (app.thread == null) {
23982            return false;
23983        }
23984
23985        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
23986
23987        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
23988    }
23989
23990    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
23991            boolean oomAdj) {
23992        if (isForeground != proc.foregroundServices) {
23993            proc.foregroundServices = isForeground;
23994            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
23995                    proc.info.uid);
23996            if (isForeground) {
23997                if (curProcs == null) {
23998                    curProcs = new ArrayList<ProcessRecord>();
23999                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
24000                }
24001                if (!curProcs.contains(proc)) {
24002                    curProcs.add(proc);
24003                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
24004                            proc.info.packageName, proc.info.uid);
24005                }
24006            } else {
24007                if (curProcs != null) {
24008                    if (curProcs.remove(proc)) {
24009                        mBatteryStatsService.noteEvent(
24010                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
24011                                proc.info.packageName, proc.info.uid);
24012                        if (curProcs.size() <= 0) {
24013                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
24014                        }
24015                    }
24016                }
24017            }
24018            if (oomAdj) {
24019                updateOomAdjLocked();
24020            }
24021        }
24022    }
24023
24024    private final ActivityRecord resumedAppLocked() {
24025        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
24026        String pkg;
24027        int uid;
24028        if (act != null) {
24029            pkg = act.packageName;
24030            uid = act.info.applicationInfo.uid;
24031        } else {
24032            pkg = null;
24033            uid = -1;
24034        }
24035        // Has the UID or resumed package name changed?
24036        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
24037                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
24038            if (mCurResumedPackage != null) {
24039                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
24040                        mCurResumedPackage, mCurResumedUid);
24041            }
24042            mCurResumedPackage = pkg;
24043            mCurResumedUid = uid;
24044            if (mCurResumedPackage != null) {
24045                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
24046                        mCurResumedPackage, mCurResumedUid);
24047            }
24048        }
24049        return act;
24050    }
24051
24052    /**
24053     * Update OomAdj for a specific process.
24054     * @param app The process to update
24055     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
24056     *                  if necessary, or skip.
24057     * @return whether updateOomAdjLocked(app) was successful.
24058     */
24059    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
24060        final ActivityRecord TOP_ACT = resumedAppLocked();
24061        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24062        final boolean wasCached = app.cached;
24063
24064        mAdjSeq++;
24065
24066        // This is the desired cached adjusment we want to tell it to use.
24067        // If our app is currently cached, we know it, and that is it.  Otherwise,
24068        // we don't know it yet, and it needs to now be cached we will then
24069        // need to do a complete oom adj.
24070        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
24071                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
24072        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
24073                SystemClock.uptimeMillis());
24074        if (oomAdjAll
24075                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
24076            // Changed to/from cached state, so apps after it in the LRU
24077            // list may also be changed.
24078            updateOomAdjLocked();
24079        }
24080        return success;
24081    }
24082
24083    final void updateOomAdjLocked() {
24084        final ActivityRecord TOP_ACT = resumedAppLocked();
24085        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24086        final long now = SystemClock.uptimeMillis();
24087        final long nowElapsed = SystemClock.elapsedRealtime();
24088        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
24089        final int N = mLruProcesses.size();
24090
24091        if (false) {
24092            RuntimeException e = new RuntimeException();
24093            e.fillInStackTrace();
24094            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
24095        }
24096
24097        // Reset state in all uid records.
24098        for (int i=mActiveUids.size()-1; i>=0; i--) {
24099            final UidRecord uidRec = mActiveUids.valueAt(i);
24100            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24101                    "Starting update of " + uidRec);
24102            uidRec.reset();
24103        }
24104
24105        mStackSupervisor.rankTaskLayersIfNeeded();
24106
24107        mAdjSeq++;
24108        mNewNumServiceProcs = 0;
24109        mNewNumAServiceProcs = 0;
24110
24111        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
24112        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
24113
24114        // Let's determine how many processes we have running vs.
24115        // how many slots we have for background processes; we may want
24116        // to put multiple processes in a slot of there are enough of
24117        // them.
24118        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
24119                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
24120        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
24121        if (numEmptyProcs > cachedProcessLimit) {
24122            // If there are more empty processes than our limit on cached
24123            // processes, then use the cached process limit for the factor.
24124            // This ensures that the really old empty processes get pushed
24125            // down to the bottom, so if we are running low on memory we will
24126            // have a better chance at keeping around more cached processes
24127            // instead of a gazillion empty processes.
24128            numEmptyProcs = cachedProcessLimit;
24129        }
24130        int emptyFactor = numEmptyProcs/numSlots;
24131        if (emptyFactor < 1) emptyFactor = 1;
24132        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
24133        if (cachedFactor < 1) cachedFactor = 1;
24134        int stepCached = 0;
24135        int stepEmpty = 0;
24136        int numCached = 0;
24137        int numEmpty = 0;
24138        int numTrimming = 0;
24139
24140        mNumNonCachedProcs = 0;
24141        mNumCachedHiddenProcs = 0;
24142
24143        // First update the OOM adjustment for each of the
24144        // application processes based on their current state.
24145        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
24146        int nextCachedAdj = curCachedAdj+1;
24147        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
24148        int nextEmptyAdj = curEmptyAdj+2;
24149        for (int i=N-1; i>=0; i--) {
24150            ProcessRecord app = mLruProcesses.get(i);
24151            if (!app.killedByAm && app.thread != null) {
24152                app.procStateChanged = false;
24153                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
24154
24155                // If we haven't yet assigned the final cached adj
24156                // to the process, do that now.
24157                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
24158                    switch (app.curProcState) {
24159                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24160                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24161                        case ActivityManager.PROCESS_STATE_CACHED_RECENT:
24162                            // This process is a cached process holding activities...
24163                            // assign it the next cached value for that type, and then
24164                            // step that cached level.
24165                            app.curRawAdj = curCachedAdj;
24166                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
24167                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
24168                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
24169                                    + ")");
24170                            if (curCachedAdj != nextCachedAdj) {
24171                                stepCached++;
24172                                if (stepCached >= cachedFactor) {
24173                                    stepCached = 0;
24174                                    curCachedAdj = nextCachedAdj;
24175                                    nextCachedAdj += 2;
24176                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24177                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
24178                                    }
24179                                }
24180                            }
24181                            break;
24182                        default:
24183                            // For everything else, assign next empty cached process
24184                            // level and bump that up.  Note that this means that
24185                            // long-running services that have dropped down to the
24186                            // cached level will be treated as empty (since their process
24187                            // state is still as a service), which is what we want.
24188                            app.curRawAdj = curEmptyAdj;
24189                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
24190                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
24191                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
24192                                    + ")");
24193                            if (curEmptyAdj != nextEmptyAdj) {
24194                                stepEmpty++;
24195                                if (stepEmpty >= emptyFactor) {
24196                                    stepEmpty = 0;
24197                                    curEmptyAdj = nextEmptyAdj;
24198                                    nextEmptyAdj += 2;
24199                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24200                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
24201                                    }
24202                                }
24203                            }
24204                            break;
24205                    }
24206                }
24207
24208                applyOomAdjLocked(app, true, now, nowElapsed);
24209
24210                // Count the number of process types.
24211                switch (app.curProcState) {
24212                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24213                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24214                        mNumCachedHiddenProcs++;
24215                        numCached++;
24216                        if (numCached > cachedProcessLimit) {
24217                            app.kill("cached #" + numCached, true);
24218                        }
24219                        break;
24220                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
24221                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
24222                                && app.lastActivityTime < oldTime) {
24223                            app.kill("empty for "
24224                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
24225                                    / 1000) + "s", true);
24226                        } else {
24227                            numEmpty++;
24228                            if (numEmpty > emptyProcessLimit) {
24229                                app.kill("empty #" + numEmpty, true);
24230                            }
24231                        }
24232                        break;
24233                    default:
24234                        mNumNonCachedProcs++;
24235                        break;
24236                }
24237
24238                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
24239                    // If this is an isolated process, there are no services
24240                    // running in it, and it's not a special process with a
24241                    // custom entry point, then the process is no longer
24242                    // needed.  We agressively kill these because we can by
24243                    // definition not re-use the same process again, and it is
24244                    // good to avoid having whatever code was running in them
24245                    // left sitting around after no longer needed.
24246                    app.kill("isolated not needed", true);
24247                } else {
24248                    // Keeping this process, update its uid.
24249                    final UidRecord uidRec = app.uidRecord;
24250                    if (uidRec != null) {
24251                        uidRec.ephemeral = app.info.isInstantApp();
24252                        if (uidRec.curProcState > app.curProcState) {
24253                            uidRec.curProcState = app.curProcState;
24254                        }
24255                        if (app.foregroundServices) {
24256                            uidRec.foregroundServices = true;
24257                        }
24258                    }
24259                }
24260
24261                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24262                        && !app.killedByAm) {
24263                    numTrimming++;
24264                }
24265            }
24266        }
24267
24268        incrementProcStateSeqAndNotifyAppsLocked();
24269
24270        mNumServiceProcs = mNewNumServiceProcs;
24271
24272        // Now determine the memory trimming level of background processes.
24273        // Unfortunately we need to start at the back of the list to do this
24274        // properly.  We only do this if the number of background apps we
24275        // are managing to keep around is less than half the maximum we desire;
24276        // if we are keeping a good number around, we'll let them use whatever
24277        // memory they want.
24278        final int numCachedAndEmpty = numCached + numEmpty;
24279        int memFactor;
24280        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
24281                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
24282            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
24283                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
24284            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
24285                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
24286            } else {
24287                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
24288            }
24289        } else {
24290            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
24291        }
24292        // We always allow the memory level to go up (better).  We only allow it to go
24293        // down if we are in a state where that is allowed, *and* the total number of processes
24294        // has gone down since last time.
24295        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
24296                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
24297                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
24298        if (memFactor > mLastMemoryLevel) {
24299            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
24300                memFactor = mLastMemoryLevel;
24301                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
24302            }
24303        }
24304        if (memFactor != mLastMemoryLevel) {
24305            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
24306        }
24307        mLastMemoryLevel = memFactor;
24308        mLastNumProcesses = mLruProcesses.size();
24309        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
24310        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
24311        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
24312            if (mLowRamStartTime == 0) {
24313                mLowRamStartTime = now;
24314            }
24315            int step = 0;
24316            int fgTrimLevel;
24317            switch (memFactor) {
24318                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
24319                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
24320                    break;
24321                case ProcessStats.ADJ_MEM_FACTOR_LOW:
24322                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
24323                    break;
24324                default:
24325                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
24326                    break;
24327            }
24328            int factor = numTrimming/3;
24329            int minFactor = 2;
24330            if (mHomeProcess != null) minFactor++;
24331            if (mPreviousProcess != null) minFactor++;
24332            if (factor < minFactor) factor = minFactor;
24333            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
24334            for (int i=N-1; i>=0; i--) {
24335                ProcessRecord app = mLruProcesses.get(i);
24336                if (allChanged || app.procStateChanged) {
24337                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24338                    app.procStateChanged = false;
24339                }
24340                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24341                        && !app.killedByAm) {
24342                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
24343                        try {
24344                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24345                                    "Trimming memory of " + app.processName + " to " + curLevel);
24346                            app.thread.scheduleTrimMemory(curLevel);
24347                        } catch (RemoteException e) {
24348                        }
24349                        if (false) {
24350                            // For now we won't do this; our memory trimming seems
24351                            // to be good enough at this point that destroying
24352                            // activities causes more harm than good.
24353                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
24354                                    && app != mHomeProcess && app != mPreviousProcess) {
24355                                // Need to do this on its own message because the stack may not
24356                                // be in a consistent state at this point.
24357                                // For these apps we will also finish their activities
24358                                // to help them free memory.
24359                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
24360                            }
24361                        }
24362                    }
24363                    app.trimMemoryLevel = curLevel;
24364                    step++;
24365                    if (step >= factor) {
24366                        step = 0;
24367                        switch (curLevel) {
24368                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
24369                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
24370                                break;
24371                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
24372                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24373                                break;
24374                        }
24375                    }
24376                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
24377                        && !app.killedByAm) {
24378                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
24379                            && app.thread != null) {
24380                        try {
24381                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24382                                    "Trimming memory of heavy-weight " + app.processName
24383                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24384                            app.thread.scheduleTrimMemory(
24385                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24386                        } catch (RemoteException e) {
24387                        }
24388                    }
24389                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24390                } else {
24391                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24392                            || app.systemNoUi) && app.pendingUiClean) {
24393                        // If this application is now in the background and it
24394                        // had done UI, then give it the special trim level to
24395                        // have it free UI resources.
24396                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
24397                        if (app.trimMemoryLevel < level && app.thread != null) {
24398                            try {
24399                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24400                                        "Trimming memory of bg-ui " + app.processName
24401                                        + " to " + level);
24402                                app.thread.scheduleTrimMemory(level);
24403                            } catch (RemoteException e) {
24404                            }
24405                        }
24406                        app.pendingUiClean = false;
24407                    }
24408                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
24409                        try {
24410                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24411                                    "Trimming memory of fg " + app.processName
24412                                    + " to " + fgTrimLevel);
24413                            app.thread.scheduleTrimMemory(fgTrimLevel);
24414                        } catch (RemoteException e) {
24415                        }
24416                    }
24417                    app.trimMemoryLevel = fgTrimLevel;
24418                }
24419            }
24420        } else {
24421            if (mLowRamStartTime != 0) {
24422                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
24423                mLowRamStartTime = 0;
24424            }
24425            for (int i=N-1; i>=0; i--) {
24426                ProcessRecord app = mLruProcesses.get(i);
24427                if (allChanged || app.procStateChanged) {
24428                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24429                    app.procStateChanged = false;
24430                }
24431                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24432                        || app.systemNoUi) && app.pendingUiClean) {
24433                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
24434                            && app.thread != null) {
24435                        try {
24436                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24437                                    "Trimming memory of ui hidden " + app.processName
24438                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24439                            app.thread.scheduleTrimMemory(
24440                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24441                        } catch (RemoteException e) {
24442                        }
24443                    }
24444                    app.pendingUiClean = false;
24445                }
24446                app.trimMemoryLevel = 0;
24447            }
24448        }
24449
24450        if (mAlwaysFinishActivities) {
24451            // Need to do this on its own message because the stack may not
24452            // be in a consistent state at this point.
24453            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
24454        }
24455
24456        if (allChanged) {
24457            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
24458        }
24459
24460        ArrayList<UidRecord> becameIdle = null;
24461
24462        // Update from any uid changes.
24463        if (mLocalPowerManager != null) {
24464            mLocalPowerManager.startUidChanges();
24465        }
24466        for (int i=mActiveUids.size()-1; i>=0; i--) {
24467            final UidRecord uidRec = mActiveUids.valueAt(i);
24468            int uidChange = UidRecord.CHANGE_PROCSTATE;
24469            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
24470                    && (uidRec.setProcState != uidRec.curProcState
24471                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
24472                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24473                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
24474                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
24475                        + " to " + uidRec.curWhitelist);
24476                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
24477                        && !uidRec.curWhitelist) {
24478                    // UID is now in the background (and not on the temp whitelist).  Was it
24479                    // previously in the foreground (or on the temp whitelist)?
24480                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
24481                            || uidRec.setWhitelist) {
24482                        uidRec.lastBackgroundTime = nowElapsed;
24483                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
24484                            // Note: the background settle time is in elapsed realtime, while
24485                            // the handler time base is uptime.  All this means is that we may
24486                            // stop background uids later than we had intended, but that only
24487                            // happens because the device was sleeping so we are okay anyway.
24488                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24489                                    mConstants.BACKGROUND_SETTLE_TIME);
24490                        }
24491                    }
24492                    if (uidRec.idle && !uidRec.setIdle) {
24493                        uidChange = UidRecord.CHANGE_IDLE;
24494                        if (becameIdle == null) {
24495                            becameIdle = new ArrayList<>();
24496                        }
24497                        becameIdle.add(uidRec);
24498                    }
24499                } else {
24500                    if (uidRec.idle) {
24501                        uidChange = UidRecord.CHANGE_ACTIVE;
24502                        EventLogTags.writeAmUidActive(uidRec.uid);
24503                        uidRec.idle = false;
24504                    }
24505                    uidRec.lastBackgroundTime = 0;
24506                }
24507                final boolean wasCached = uidRec.setProcState
24508                        > ActivityManager.PROCESS_STATE_RECEIVER;
24509                final boolean isCached = uidRec.curProcState
24510                        > ActivityManager.PROCESS_STATE_RECEIVER;
24511                if (wasCached != isCached ||
24512                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
24513                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
24514                }
24515                uidRec.setProcState = uidRec.curProcState;
24516                uidRec.setWhitelist = uidRec.curWhitelist;
24517                uidRec.setIdle = uidRec.idle;
24518                enqueueUidChangeLocked(uidRec, -1, uidChange);
24519                noteUidProcessState(uidRec.uid, uidRec.curProcState);
24520                if (uidRec.foregroundServices) {
24521                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
24522                }
24523            }
24524        }
24525        if (mLocalPowerManager != null) {
24526            mLocalPowerManager.finishUidChanges();
24527        }
24528
24529        if (becameIdle != null) {
24530            // If we have any new uids that became idle this time, we need to make sure
24531            // they aren't left with running services.
24532            for (int i = becameIdle.size() - 1; i >= 0; i--) {
24533                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
24534            }
24535        }
24536
24537        if (mProcessStats.shouldWriteNowLocked(now)) {
24538            mHandler.post(new Runnable() {
24539                @Override public void run() {
24540                    synchronized (ActivityManagerService.this) {
24541                        mProcessStats.writeStateAsyncLocked();
24542                    }
24543                }
24544            });
24545        }
24546
24547        if (DEBUG_OOM_ADJ) {
24548            final long duration = SystemClock.uptimeMillis() - now;
24549            if (false) {
24550                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
24551                        new RuntimeException("here").fillInStackTrace());
24552            } else {
24553                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
24554            }
24555        }
24556    }
24557
24558    @Override
24559    public void makePackageIdle(String packageName, int userId) {
24560        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
24561                != PackageManager.PERMISSION_GRANTED) {
24562            String msg = "Permission Denial: makePackageIdle() from pid="
24563                    + Binder.getCallingPid()
24564                    + ", uid=" + Binder.getCallingUid()
24565                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
24566            Slog.w(TAG, msg);
24567            throw new SecurityException(msg);
24568        }
24569        final int callingPid = Binder.getCallingPid();
24570        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
24571                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
24572        long callingId = Binder.clearCallingIdentity();
24573        synchronized(this) {
24574            try {
24575                IPackageManager pm = AppGlobals.getPackageManager();
24576                int pkgUid = -1;
24577                try {
24578                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
24579                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
24580                } catch (RemoteException e) {
24581                }
24582                if (pkgUid == -1) {
24583                    throw new IllegalArgumentException("Unknown package name " + packageName);
24584                }
24585
24586                if (mLocalPowerManager != null) {
24587                    mLocalPowerManager.startUidChanges();
24588                }
24589                final int appId = UserHandle.getAppId(pkgUid);
24590                final int N = mActiveUids.size();
24591                for (int i=N-1; i>=0; i--) {
24592                    final UidRecord uidRec = mActiveUids.valueAt(i);
24593                    final long bgTime = uidRec.lastBackgroundTime;
24594                    if (bgTime > 0 && !uidRec.idle) {
24595                        if (UserHandle.getAppId(uidRec.uid) == appId) {
24596                            if (userId == UserHandle.USER_ALL ||
24597                                    userId == UserHandle.getUserId(uidRec.uid)) {
24598                                EventLogTags.writeAmUidIdle(uidRec.uid);
24599                                uidRec.idle = true;
24600                                uidRec.setIdle = true;
24601                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
24602                                        + " from package " + packageName + " user " + userId);
24603                                doStopUidLocked(uidRec.uid, uidRec);
24604                            }
24605                        }
24606                    }
24607                }
24608            } finally {
24609                if (mLocalPowerManager != null) {
24610                    mLocalPowerManager.finishUidChanges();
24611                }
24612                Binder.restoreCallingIdentity(callingId);
24613            }
24614        }
24615    }
24616
24617    final void idleUids() {
24618        synchronized (this) {
24619            final int N = mActiveUids.size();
24620            if (N <= 0) {
24621                return;
24622            }
24623            final long nowElapsed = SystemClock.elapsedRealtime();
24624            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
24625            long nextTime = 0;
24626            if (mLocalPowerManager != null) {
24627                mLocalPowerManager.startUidChanges();
24628            }
24629            for (int i=N-1; i>=0; i--) {
24630                final UidRecord uidRec = mActiveUids.valueAt(i);
24631                final long bgTime = uidRec.lastBackgroundTime;
24632                if (bgTime > 0 && !uidRec.idle) {
24633                    if (bgTime <= maxBgTime) {
24634                        EventLogTags.writeAmUidIdle(uidRec.uid);
24635                        uidRec.idle = true;
24636                        uidRec.setIdle = true;
24637                        doStopUidLocked(uidRec.uid, uidRec);
24638                    } else {
24639                        if (nextTime == 0 || nextTime > bgTime) {
24640                            nextTime = bgTime;
24641                        }
24642                    }
24643                }
24644            }
24645            if (mLocalPowerManager != null) {
24646                mLocalPowerManager.finishUidChanges();
24647            }
24648            if (nextTime > 0) {
24649                mHandler.removeMessages(IDLE_UIDS_MSG);
24650                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24651                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
24652            }
24653        }
24654    }
24655
24656    /**
24657     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
24658     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
24659     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
24660     */
24661    @VisibleForTesting
24662    @GuardedBy("this")
24663    void incrementProcStateSeqAndNotifyAppsLocked() {
24664        if (mWaitForNetworkTimeoutMs <= 0) {
24665            return;
24666        }
24667        // Used for identifying which uids need to block for network.
24668        ArrayList<Integer> blockingUids = null;
24669        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
24670            final UidRecord uidRec = mActiveUids.valueAt(i);
24671            // If the network is not restricted for uid, then nothing to do here.
24672            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
24673                continue;
24674            }
24675            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
24676                continue;
24677            }
24678            // If process state is not changed, then there's nothing to do.
24679            if (uidRec.setProcState == uidRec.curProcState) {
24680                continue;
24681            }
24682            final int blockState = getBlockStateForUid(uidRec);
24683            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
24684            // there's nothing the app needs to do in this scenario.
24685            if (blockState == NETWORK_STATE_NO_CHANGE) {
24686                continue;
24687            }
24688            synchronized (uidRec.networkStateLock) {
24689                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
24690                if (blockState == NETWORK_STATE_BLOCK) {
24691                    if (blockingUids == null) {
24692                        blockingUids = new ArrayList<>();
24693                    }
24694                    blockingUids.add(uidRec.uid);
24695                } else {
24696                    if (DEBUG_NETWORK) {
24697                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
24698                                + " threads for uid: " + uidRec);
24699                    }
24700                    if (uidRec.waitingForNetwork) {
24701                        uidRec.networkStateLock.notifyAll();
24702                    }
24703                }
24704            }
24705        }
24706
24707        // There are no uids that need to block, so nothing more to do.
24708        if (blockingUids == null) {
24709            return;
24710        }
24711
24712        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
24713            final ProcessRecord app = mLruProcesses.get(i);
24714            if (!blockingUids.contains(app.uid)) {
24715                continue;
24716            }
24717            if (!app.killedByAm && app.thread != null) {
24718                final UidRecord uidRec = mActiveUids.get(app.uid);
24719                try {
24720                    if (DEBUG_NETWORK) {
24721                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
24722                                + uidRec);
24723                    }
24724                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
24725                } catch (RemoteException ignored) {
24726                }
24727            }
24728        }
24729    }
24730
24731    /**
24732     * Checks if the uid is coming from background to foreground or vice versa and returns
24733     * appropriate block state based on this.
24734     *
24735     * @return blockState based on whether the uid is coming from background to foreground or
24736     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
24737     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
24738     *         {@link #NETWORK_STATE_NO_CHANGE}.
24739     */
24740    @VisibleForTesting
24741    int getBlockStateForUid(UidRecord uidRec) {
24742        // Denotes whether uid's process state is currently allowed network access.
24743        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
24744                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
24745        // Denotes whether uid's process state was previously allowed network access.
24746        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
24747                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
24748
24749        // When the uid is coming to foreground, AMS should inform the app thread that it should
24750        // block for the network rules to get updated before launching an activity.
24751        if (!wasAllowed && isAllowed) {
24752            return NETWORK_STATE_BLOCK;
24753        }
24754        // When the uid is going to background, AMS should inform the app thread that if an
24755        // activity launch is blocked for the network rules to get updated, it should be unblocked.
24756        if (wasAllowed && !isAllowed) {
24757            return NETWORK_STATE_UNBLOCK;
24758        }
24759        return NETWORK_STATE_NO_CHANGE;
24760    }
24761
24762    final void runInBackgroundDisabled(int uid) {
24763        synchronized (this) {
24764            UidRecord uidRec = mActiveUids.get(uid);
24765            if (uidRec != null) {
24766                // This uid is actually running...  should it be considered background now?
24767                if (uidRec.idle) {
24768                    doStopUidLocked(uidRec.uid, uidRec);
24769                }
24770            } else {
24771                // This uid isn't actually running...  still send a report about it being "stopped".
24772                doStopUidLocked(uid, null);
24773            }
24774        }
24775    }
24776
24777    /**
24778     * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
24779     */
24780    void doStopUidForIdleUidsLocked() {
24781        final int size = mActiveUids.size();
24782        for (int i = 0; i < size; i++) {
24783            final int uid = mActiveUids.keyAt(i);
24784            if (UserHandle.isCore(uid)) {
24785                continue;
24786            }
24787            final UidRecord uidRec = mActiveUids.valueAt(i);
24788            if (!uidRec.idle) {
24789                continue;
24790            }
24791            doStopUidLocked(uidRec.uid, uidRec);
24792        }
24793    }
24794
24795    final void doStopUidLocked(int uid, final UidRecord uidRec) {
24796        mServices.stopInBackgroundLocked(uid);
24797        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
24798    }
24799
24800    /**
24801     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
24802     */
24803    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
24804            long duration, String tag) {
24805        if (DEBUG_WHITELISTS) {
24806            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
24807                    + targetUid + ", " + duration + ")");
24808        }
24809
24810        synchronized (mPidsSelfLocked) {
24811            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
24812            if (pr == null) {
24813                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
24814                        + callerPid);
24815                return;
24816            }
24817            if (!pr.whitelistManager) {
24818                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
24819                        != PackageManager.PERMISSION_GRANTED) {
24820                    if (DEBUG_WHITELISTS) {
24821                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
24822                                + ": pid " + callerPid + " is not allowed");
24823                    }
24824                    return;
24825                }
24826            }
24827        }
24828
24829        tempWhitelistUidLocked(targetUid, duration, tag);
24830    }
24831
24832    /**
24833     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
24834     */
24835    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
24836        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
24837        setUidTempWhitelistStateLocked(targetUid, true);
24838        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
24839    }
24840
24841    void pushTempWhitelist() {
24842        final int N;
24843        final PendingTempWhitelist[] list;
24844
24845        // First copy out the pending changes...  we need to leave them in the map for now,
24846        // in case someone needs to check what is coming up while we don't have the lock held.
24847        synchronized(this) {
24848            N = mPendingTempWhitelist.size();
24849            list = new PendingTempWhitelist[N];
24850            for (int i = 0; i < N; i++) {
24851                list[i] = mPendingTempWhitelist.valueAt(i);
24852            }
24853        }
24854
24855        // Now safely dispatch changes to device idle controller.
24856        for (int i = 0; i < N; i++) {
24857            PendingTempWhitelist ptw = list[i];
24858            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
24859                    ptw.duration, true, ptw.tag);
24860        }
24861
24862        // And now we can safely remove them from the map.
24863        synchronized(this) {
24864            for (int i = 0; i < N; i++) {
24865                PendingTempWhitelist ptw = list[i];
24866                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
24867                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
24868                    mPendingTempWhitelist.removeAt(index);
24869                }
24870            }
24871        }
24872    }
24873
24874    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
24875        boolean changed = false;
24876        for (int i=mActiveUids.size()-1; i>=0; i--) {
24877            final UidRecord uidRec = mActiveUids.valueAt(i);
24878            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
24879                uidRec.curWhitelist = onWhitelist;
24880                changed = true;
24881            }
24882        }
24883        if (changed) {
24884            updateOomAdjLocked();
24885        }
24886    }
24887
24888    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
24889        boolean changed = false;
24890        final UidRecord uidRec = mActiveUids.get(uid);
24891        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
24892            uidRec.curWhitelist = onWhitelist;
24893            updateOomAdjLocked();
24894        }
24895    }
24896
24897    final void trimApplications() {
24898        synchronized (this) {
24899            int i;
24900
24901            // First remove any unused application processes whose package
24902            // has been removed.
24903            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
24904                final ProcessRecord app = mRemovedProcesses.get(i);
24905                if (app.activities.size() == 0 && app.recentTasks.size() == 0
24906                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
24907                    Slog.i(
24908                        TAG, "Exiting empty application process "
24909                        + app.toShortString() + " ("
24910                        + (app.thread != null ? app.thread.asBinder() : null)
24911                        + ")\n");
24912                    if (app.pid > 0 && app.pid != MY_PID) {
24913                        app.kill("empty", false);
24914                    } else if (app.thread != null) {
24915                        try {
24916                            app.thread.scheduleExit();
24917                        } catch (Exception e) {
24918                            // Ignore exceptions.
24919                        }
24920                    }
24921                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
24922                    mRemovedProcesses.remove(i);
24923
24924                    if (app.persistent) {
24925                        addAppLocked(app.info, null, false, null /* ABI override */);
24926                    }
24927                }
24928            }
24929
24930            // Now update the oom adj for all processes.
24931            updateOomAdjLocked();
24932        }
24933    }
24934
24935    /** This method sends the specified signal to each of the persistent apps */
24936    public void signalPersistentProcesses(int sig) throws RemoteException {
24937        if (sig != SIGNAL_USR1) {
24938            throw new SecurityException("Only SIGNAL_USR1 is allowed");
24939        }
24940
24941        synchronized (this) {
24942            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
24943                    != PackageManager.PERMISSION_GRANTED) {
24944                throw new SecurityException("Requires permission "
24945                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
24946            }
24947
24948            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
24949                ProcessRecord r = mLruProcesses.get(i);
24950                if (r.thread != null && r.persistent) {
24951                    sendSignal(r.pid, sig);
24952                }
24953            }
24954        }
24955    }
24956
24957    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
24958        if (proc == null || proc == mProfileProc) {
24959            proc = mProfileProc;
24960            profileType = mProfileType;
24961            clearProfilerLocked();
24962        }
24963        if (proc == null) {
24964            return;
24965        }
24966        try {
24967            proc.thread.profilerControl(false, null, profileType);
24968        } catch (RemoteException e) {
24969            throw new IllegalStateException("Process disappeared");
24970        }
24971    }
24972
24973    private void clearProfilerLocked() {
24974        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
24975            try {
24976                mProfilerInfo.profileFd.close();
24977            } catch (IOException e) {
24978            }
24979        }
24980        mProfileApp = null;
24981        mProfileProc = null;
24982        mProfilerInfo = null;
24983    }
24984
24985    public boolean profileControl(String process, int userId, boolean start,
24986            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
24987
24988        try {
24989            synchronized (this) {
24990                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
24991                // its own permission.
24992                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
24993                        != PackageManager.PERMISSION_GRANTED) {
24994                    throw new SecurityException("Requires permission "
24995                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
24996                }
24997
24998                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
24999                    throw new IllegalArgumentException("null profile info or fd");
25000                }
25001
25002                ProcessRecord proc = null;
25003                if (process != null) {
25004                    proc = findProcessLocked(process, userId, "profileControl");
25005                }
25006
25007                if (start && (proc == null || proc.thread == null)) {
25008                    throw new IllegalArgumentException("Unknown process: " + process);
25009                }
25010
25011                if (start) {
25012                    stopProfilerLocked(null, 0);
25013                    setProfileApp(proc.info, proc.processName, profilerInfo);
25014                    mProfileProc = proc;
25015                    mProfileType = profileType;
25016                    ParcelFileDescriptor fd = profilerInfo.profileFd;
25017                    try {
25018                        fd = fd.dup();
25019                    } catch (IOException e) {
25020                        fd = null;
25021                    }
25022                    profilerInfo.profileFd = fd;
25023                    proc.thread.profilerControl(start, profilerInfo, profileType);
25024                    fd = null;
25025                    try {
25026                        mProfilerInfo.profileFd.close();
25027                    } catch (IOException e) {
25028                    }
25029                    mProfilerInfo.profileFd = null;
25030                } else {
25031                    stopProfilerLocked(proc, profileType);
25032                    if (profilerInfo != null && profilerInfo.profileFd != null) {
25033                        try {
25034                            profilerInfo.profileFd.close();
25035                        } catch (IOException e) {
25036                        }
25037                    }
25038                }
25039
25040                return true;
25041            }
25042        } catch (RemoteException e) {
25043            throw new IllegalStateException("Process disappeared");
25044        } finally {
25045            if (profilerInfo != null && profilerInfo.profileFd != null) {
25046                try {
25047                    profilerInfo.profileFd.close();
25048                } catch (IOException e) {
25049                }
25050            }
25051        }
25052    }
25053
25054    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
25055        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
25056                userId, true, ALLOW_FULL_ONLY, callName, null);
25057        ProcessRecord proc = null;
25058        try {
25059            int pid = Integer.parseInt(process);
25060            synchronized (mPidsSelfLocked) {
25061                proc = mPidsSelfLocked.get(pid);
25062            }
25063        } catch (NumberFormatException e) {
25064        }
25065
25066        if (proc == null) {
25067            ArrayMap<String, SparseArray<ProcessRecord>> all
25068                    = mProcessNames.getMap();
25069            SparseArray<ProcessRecord> procs = all.get(process);
25070            if (procs != null && procs.size() > 0) {
25071                proc = procs.valueAt(0);
25072                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
25073                    for (int i=1; i<procs.size(); i++) {
25074                        ProcessRecord thisProc = procs.valueAt(i);
25075                        if (thisProc.userId == userId) {
25076                            proc = thisProc;
25077                            break;
25078                        }
25079                    }
25080                }
25081            }
25082        }
25083
25084        return proc;
25085    }
25086
25087    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
25088            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
25089
25090        try {
25091            synchronized (this) {
25092                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25093                // its own permission (same as profileControl).
25094                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25095                        != PackageManager.PERMISSION_GRANTED) {
25096                    throw new SecurityException("Requires permission "
25097                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25098                }
25099
25100                if (fd == null) {
25101                    throw new IllegalArgumentException("null fd");
25102                }
25103
25104                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
25105                if (proc == null || proc.thread == null) {
25106                    throw new IllegalArgumentException("Unknown process: " + process);
25107                }
25108
25109                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25110                if (!isDebuggable) {
25111                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25112                        throw new SecurityException("Process not debuggable: " + proc);
25113                    }
25114                }
25115
25116                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
25117                fd = null;
25118                return true;
25119            }
25120        } catch (RemoteException e) {
25121            throw new IllegalStateException("Process disappeared");
25122        } finally {
25123            if (fd != null) {
25124                try {
25125                    fd.close();
25126                } catch (IOException e) {
25127                }
25128            }
25129        }
25130    }
25131
25132    @Override
25133    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
25134            String reportPackage) {
25135        if (processName != null) {
25136            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
25137                    "setDumpHeapDebugLimit()");
25138        } else {
25139            synchronized (mPidsSelfLocked) {
25140                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
25141                if (proc == null) {
25142                    throw new SecurityException("No process found for calling pid "
25143                            + Binder.getCallingPid());
25144                }
25145                if (!Build.IS_DEBUGGABLE
25146                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25147                    throw new SecurityException("Not running a debuggable build");
25148                }
25149                processName = proc.processName;
25150                uid = proc.uid;
25151                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
25152                    throw new SecurityException("Package " + reportPackage + " is not running in "
25153                            + proc);
25154                }
25155            }
25156        }
25157        synchronized (this) {
25158            if (maxMemSize > 0) {
25159                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
25160            } else {
25161                if (uid != 0) {
25162                    mMemWatchProcesses.remove(processName, uid);
25163                } else {
25164                    mMemWatchProcesses.getMap().remove(processName);
25165                }
25166            }
25167        }
25168    }
25169
25170    @Override
25171    public void dumpHeapFinished(String path) {
25172        synchronized (this) {
25173            if (Binder.getCallingPid() != mMemWatchDumpPid) {
25174                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
25175                        + " does not match last pid " + mMemWatchDumpPid);
25176                return;
25177            }
25178            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
25179                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
25180                        + " does not match last path " + mMemWatchDumpFile);
25181                return;
25182            }
25183            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
25184            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
25185
25186            // Forced gc to clean up the remnant hprof fd.
25187            Runtime.getRuntime().gc();
25188        }
25189    }
25190
25191    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
25192    public void monitor() {
25193        synchronized (this) { }
25194    }
25195
25196    void onCoreSettingsChange(Bundle settings) {
25197        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
25198            ProcessRecord processRecord = mLruProcesses.get(i);
25199            try {
25200                if (processRecord.thread != null) {
25201                    processRecord.thread.setCoreSettings(settings);
25202                }
25203            } catch (RemoteException re) {
25204                /* ignore */
25205            }
25206        }
25207    }
25208
25209    // Multi-user methods
25210
25211    /**
25212     * Start user, if its not already running, but don't bring it to foreground.
25213     */
25214    @Override
25215    public boolean startUserInBackground(final int userId) {
25216        return startUserInBackgroundWithListener(userId, null);
25217    }
25218
25219    @Override
25220    public boolean startUserInBackgroundWithListener(final int userId,
25221                @Nullable IProgressListener unlockListener) {
25222        return mUserController.startUser(userId, /* foreground */ false, unlockListener);
25223    }
25224
25225    @Override
25226    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
25227        return mUserController.unlockUser(userId, token, secret, listener);
25228    }
25229
25230    @Override
25231    public boolean switchUser(final int targetUserId) {
25232        return mUserController.switchUser(targetUserId);
25233    }
25234
25235    @Override
25236    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
25237        return mUserController.stopUser(userId, force, callback);
25238    }
25239
25240    @Override
25241    public UserInfo getCurrentUser() {
25242        return mUserController.getCurrentUser();
25243    }
25244
25245    String getStartedUserState(int userId) {
25246        final UserState userState = mUserController.getStartedUserState(userId);
25247        return UserState.stateToString(userState.state);
25248    }
25249
25250    @Override
25251    public boolean isUserRunning(int userId, int flags) {
25252        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
25253                && checkCallingPermission(INTERACT_ACROSS_USERS)
25254                    != PackageManager.PERMISSION_GRANTED) {
25255            String msg = "Permission Denial: isUserRunning() from pid="
25256                    + Binder.getCallingPid()
25257                    + ", uid=" + Binder.getCallingUid()
25258                    + " requires " + INTERACT_ACROSS_USERS;
25259            Slog.w(TAG, msg);
25260            throw new SecurityException(msg);
25261        }
25262        return mUserController.isUserRunning(userId, flags);
25263    }
25264
25265    @Override
25266    public int[] getRunningUserIds() {
25267        if (checkCallingPermission(INTERACT_ACROSS_USERS)
25268                != PackageManager.PERMISSION_GRANTED) {
25269            String msg = "Permission Denial: isUserRunning() from pid="
25270                    + Binder.getCallingPid()
25271                    + ", uid=" + Binder.getCallingUid()
25272                    + " requires " + INTERACT_ACROSS_USERS;
25273            Slog.w(TAG, msg);
25274            throw new SecurityException(msg);
25275        }
25276        return mUserController.getStartedUserArray();
25277    }
25278
25279    @Override
25280    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
25281        mUserController.registerUserSwitchObserver(observer, name);
25282    }
25283
25284    @Override
25285    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
25286        mUserController.unregisterUserSwitchObserver(observer);
25287    }
25288
25289    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
25290        if (info == null) return null;
25291        ApplicationInfo newInfo = new ApplicationInfo(info);
25292        newInfo.initForUser(userId);
25293        return newInfo;
25294    }
25295
25296    public boolean isUserStopped(int userId) {
25297        return mUserController.getStartedUserState(userId) == null;
25298    }
25299
25300    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
25301        if (aInfo == null
25302                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
25303            return aInfo;
25304        }
25305
25306        ActivityInfo info = new ActivityInfo(aInfo);
25307        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
25308        return info;
25309    }
25310
25311    private boolean processSanityChecksLocked(ProcessRecord process) {
25312        if (process == null || process.thread == null) {
25313            return false;
25314        }
25315
25316        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25317        if (!isDebuggable) {
25318            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25319                return false;
25320            }
25321        }
25322
25323        return true;
25324    }
25325
25326    public boolean startBinderTracking() throws RemoteException {
25327        synchronized (this) {
25328            mBinderTransactionTrackingEnabled = true;
25329            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25330            // permission (same as profileControl).
25331            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25332                    != PackageManager.PERMISSION_GRANTED) {
25333                throw new SecurityException("Requires permission "
25334                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25335            }
25336
25337            for (int i = 0; i < mLruProcesses.size(); i++) {
25338                ProcessRecord process = mLruProcesses.get(i);
25339                if (!processSanityChecksLocked(process)) {
25340                    continue;
25341                }
25342                try {
25343                    process.thread.startBinderTracking();
25344                } catch (RemoteException e) {
25345                    Log.v(TAG, "Process disappared");
25346                }
25347            }
25348            return true;
25349        }
25350    }
25351
25352    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
25353        try {
25354            synchronized (this) {
25355                mBinderTransactionTrackingEnabled = false;
25356                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25357                // permission (same as profileControl).
25358                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25359                        != PackageManager.PERMISSION_GRANTED) {
25360                    throw new SecurityException("Requires permission "
25361                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25362                }
25363
25364                if (fd == null) {
25365                    throw new IllegalArgumentException("null fd");
25366                }
25367
25368                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
25369                pw.println("Binder transaction traces for all processes.\n");
25370                for (ProcessRecord process : mLruProcesses) {
25371                    if (!processSanityChecksLocked(process)) {
25372                        continue;
25373                    }
25374
25375                    pw.println("Traces for process: " + process.processName);
25376                    pw.flush();
25377                    try {
25378                        TransferPipe tp = new TransferPipe();
25379                        try {
25380                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
25381                            tp.go(fd.getFileDescriptor());
25382                        } finally {
25383                            tp.kill();
25384                        }
25385                    } catch (IOException e) {
25386                        pw.println("Failure while dumping IPC traces from " + process +
25387                                ".  Exception: " + e);
25388                        pw.flush();
25389                    } catch (RemoteException e) {
25390                        pw.println("Got a RemoteException while dumping IPC traces from " +
25391                                process + ".  Exception: " + e);
25392                        pw.flush();
25393                    }
25394                }
25395                fd = null;
25396                return true;
25397            }
25398        } finally {
25399            if (fd != null) {
25400                try {
25401                    fd.close();
25402                } catch (IOException e) {
25403                }
25404            }
25405        }
25406    }
25407
25408    @VisibleForTesting
25409    final class LocalService extends ActivityManagerInternal {
25410        @Override
25411        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
25412                int targetUserId) {
25413            synchronized (ActivityManagerService.this) {
25414                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
25415                        targetPkg, intent, null, targetUserId);
25416            }
25417        }
25418
25419        @Override
25420        public String checkContentProviderAccess(String authority, int userId) {
25421            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
25422        }
25423
25424        @Override
25425        public void onWakefulnessChanged(int wakefulness) {
25426            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
25427        }
25428
25429        @Override
25430        public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
25431                String processName, String abiOverride, int uid, Runnable crashHandler) {
25432            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
25433                    processName, abiOverride, uid, crashHandler);
25434        }
25435
25436        @Override
25437        public SleepToken acquireSleepToken(String tag, int displayId) {
25438            Preconditions.checkNotNull(tag);
25439            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
25440        }
25441
25442        @Override
25443        public ComponentName getHomeActivityForUser(int userId) {
25444            synchronized (ActivityManagerService.this) {
25445                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
25446                return homeActivity == null ? null : homeActivity.realActivity;
25447            }
25448        }
25449
25450        @Override
25451        public void onUserRemoved(int userId) {
25452            synchronized (ActivityManagerService.this) {
25453                ActivityManagerService.this.onUserStoppedLocked(userId);
25454            }
25455            mBatteryStatsService.onUserRemoved(userId);
25456            mUserController.onUserRemoved(userId);
25457        }
25458
25459        @Override
25460        public void onLocalVoiceInteractionStarted(IBinder activity,
25461                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
25462            synchronized (ActivityManagerService.this) {
25463                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
25464                        voiceSession, voiceInteractor);
25465            }
25466        }
25467
25468        @Override
25469        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
25470            synchronized (ActivityManagerService.this) {
25471                mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
25472                        reasons, timestamp);
25473            }
25474        }
25475
25476        @Override
25477        public void notifyAppTransitionFinished() {
25478            synchronized (ActivityManagerService.this) {
25479                mStackSupervisor.notifyAppTransitionDone();
25480                mKeyguardController.notifyAppTransitionDone();
25481            }
25482        }
25483
25484        @Override
25485        public void notifyAppTransitionCancelled() {
25486            synchronized (ActivityManagerService.this) {
25487                mStackSupervisor.notifyAppTransitionDone();
25488            }
25489        }
25490
25491        @Override
25492        public List<IBinder> getTopVisibleActivities() {
25493            synchronized (ActivityManagerService.this) {
25494                return mStackSupervisor.getTopVisibleActivities();
25495            }
25496        }
25497
25498        @Override
25499        public void notifyDockedStackMinimizedChanged(boolean minimized) {
25500            synchronized (ActivityManagerService.this) {
25501                mStackSupervisor.setDockedStackMinimized(minimized);
25502            }
25503        }
25504
25505        @Override
25506        public void killForegroundAppsForUser(int userHandle) {
25507            synchronized (ActivityManagerService.this) {
25508                final ArrayList<ProcessRecord> procs = new ArrayList<>();
25509                final int NP = mProcessNames.getMap().size();
25510                for (int ip = 0; ip < NP; ip++) {
25511                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
25512                    final int NA = apps.size();
25513                    for (int ia = 0; ia < NA; ia++) {
25514                        final ProcessRecord app = apps.valueAt(ia);
25515                        if (app.persistent) {
25516                            // We don't kill persistent processes.
25517                            continue;
25518                        }
25519                        if (app.removed) {
25520                            procs.add(app);
25521                        } else if (app.userId == userHandle && app.foregroundActivities) {
25522                            app.removed = true;
25523                            procs.add(app);
25524                        }
25525                    }
25526                }
25527
25528                final int N = procs.size();
25529                for (int i = 0; i < N; i++) {
25530                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
25531                }
25532            }
25533        }
25534
25535        @Override
25536        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
25537                long duration) {
25538            if (!(target instanceof PendingIntentRecord)) {
25539                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
25540                return;
25541            }
25542            synchronized (ActivityManagerService.this) {
25543                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
25544            }
25545        }
25546
25547        @Override
25548        public void setDeviceIdleWhitelist(int[] appids) {
25549            synchronized (ActivityManagerService.this) {
25550                mDeviceIdleWhitelist = appids;
25551            }
25552        }
25553
25554        @Override
25555        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
25556            synchronized (ActivityManagerService.this) {
25557                mDeviceIdleTempWhitelist = appids;
25558                setAppIdTempWhitelistStateLocked(changingAppId, adding);
25559            }
25560        }
25561
25562        @Override
25563        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
25564                int userId) {
25565            Preconditions.checkNotNull(values, "Configuration must not be null");
25566            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
25567            synchronized (ActivityManagerService.this) {
25568                updateConfigurationLocked(values, null, false, true, userId,
25569                        false /* deferResume */);
25570            }
25571        }
25572
25573        @Override
25574        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
25575                Bundle bOptions) {
25576            Preconditions.checkNotNull(intents, "intents");
25577            final String[] resolvedTypes = new String[intents.length];
25578            for (int i = 0; i < intents.length; i++) {
25579                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
25580            }
25581
25582            // UID of the package on user userId.
25583            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
25584            // packageUid may not be initialized.
25585            int packageUid = 0;
25586            final long ident = Binder.clearCallingIdentity();
25587            try {
25588                packageUid = AppGlobals.getPackageManager().getPackageUid(
25589                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
25590            } catch (RemoteException e) {
25591                // Shouldn't happen.
25592            } finally {
25593                Binder.restoreCallingIdentity(ident);
25594            }
25595
25596            synchronized (ActivityManagerService.this) {
25597                return mActivityStartController.startActivitiesInPackage(packageUid, packageName,
25598                        intents, resolvedTypes, null /* resultTo */,
25599                        SafeActivityOptions.fromBundle(bOptions), userId);
25600            }
25601        }
25602
25603        @Override
25604        public int getUidProcessState(int uid) {
25605            return getUidState(uid);
25606        }
25607
25608        @Override
25609        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
25610            synchronized (ActivityManagerService.this) {
25611
25612                // We might change the visibilities here, so prepare an empty app transition which
25613                // might be overridden later if we actually change visibilities.
25614                final boolean wasTransitionSet =
25615                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
25616                if (!wasTransitionSet) {
25617                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
25618                            false /* alwaysKeepCurrent */);
25619                }
25620                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
25621
25622                // If there was a transition set already we don't want to interfere with it as we
25623                // might be starting it too early.
25624                if (!wasTransitionSet) {
25625                    mWindowManager.executeAppTransition();
25626                }
25627            }
25628            if (callback != null) {
25629                callback.run();
25630            }
25631        }
25632
25633        @Override
25634        public boolean isSystemReady() {
25635            // no need to synchronize(this) just to read & return the value
25636            return mSystemReady;
25637        }
25638
25639        @Override
25640        public void notifyKeyguardTrustedChanged() {
25641            synchronized (ActivityManagerService.this) {
25642                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
25643                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
25644                }
25645            }
25646        }
25647
25648        /**
25649         * Sets if the given pid has an overlay UI or not.
25650         *
25651         * @param pid The pid we are setting overlay UI for.
25652         * @param hasOverlayUi True if the process has overlay UI.
25653         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
25654         */
25655        @Override
25656        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
25657            synchronized (ActivityManagerService.this) {
25658                final ProcessRecord pr;
25659                synchronized (mPidsSelfLocked) {
25660                    pr = mPidsSelfLocked.get(pid);
25661                    if (pr == null) {
25662                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
25663                        return;
25664                    }
25665                }
25666                if (pr.hasOverlayUi == hasOverlayUi) {
25667                    return;
25668                }
25669                pr.hasOverlayUi = hasOverlayUi;
25670                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
25671                updateOomAdjLocked(pr, true);
25672            }
25673        }
25674
25675        /**
25676         * Called after the network policy rules are updated by
25677         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
25678         * and {@param procStateSeq}.
25679         */
25680        @Override
25681        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
25682            if (DEBUG_NETWORK) {
25683                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
25684                        + uid + " seq: " + procStateSeq);
25685            }
25686            UidRecord record;
25687            synchronized (ActivityManagerService.this) {
25688                record = mActiveUids.get(uid);
25689                if (record == null) {
25690                    if (DEBUG_NETWORK) {
25691                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
25692                                + " procStateSeq: " + procStateSeq);
25693                    }
25694                    return;
25695                }
25696            }
25697            synchronized (record.networkStateLock) {
25698                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
25699                    if (DEBUG_NETWORK) {
25700                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
25701                                + " been handled for uid: " + uid);
25702                    }
25703                    return;
25704                }
25705                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
25706                if (record.curProcStateSeq > procStateSeq) {
25707                    if (DEBUG_NETWORK) {
25708                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
25709                                + ", curProcstateSeq: " + record.curProcStateSeq
25710                                + ", procStateSeq: " + procStateSeq);
25711                    }
25712                    return;
25713                }
25714                if (record.waitingForNetwork) {
25715                    if (DEBUG_NETWORK) {
25716                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
25717                                + ", procStateSeq: " + procStateSeq);
25718                    }
25719                    record.networkStateLock.notifyAll();
25720                }
25721            }
25722        }
25723
25724        @Override
25725        public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
25726            synchronized (ActivityManagerService.this) {
25727                mActiveVoiceInteractionServiceComponent = component;
25728            }
25729        }
25730
25731        /**
25732         * Called after virtual display Id is updated by
25733         * {@link com.android.server.vr.Vr2dDisplay} with a specific
25734         * {@param vrVr2dDisplayId}.
25735         */
25736        @Override
25737        public void setVr2dDisplayId(int vr2dDisplayId) {
25738            if (DEBUG_STACK) {
25739                Slog.d(TAG, "setVr2dDisplayId called for: " +
25740                        vr2dDisplayId);
25741            }
25742            synchronized (ActivityManagerService.this) {
25743                mVr2dDisplayId = vr2dDisplayId;
25744            }
25745        }
25746
25747        @Override
25748        public void saveANRState(String reason) {
25749            synchronized (ActivityManagerService.this) {
25750                final StringWriter sw = new StringWriter();
25751                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
25752                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
25753                if (reason != null) {
25754                    pw.println("  Reason: " + reason);
25755                }
25756                pw.println();
25757                mActivityStartController.dump(pw, "  ", null);
25758                pw.println();
25759                pw.println("-------------------------------------------------------------------------------");
25760                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
25761                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
25762                        "" /* header */);
25763                pw.println();
25764                pw.close();
25765
25766                mLastANRState = sw.toString();
25767            }
25768        }
25769
25770        @Override
25771        public void clearSavedANRState() {
25772            synchronized (ActivityManagerService.this) {
25773                mLastANRState = null;
25774            }
25775        }
25776
25777        @Override
25778        public void setFocusedActivity(IBinder token) {
25779            synchronized (ActivityManagerService.this) {
25780                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
25781                if (r == null) {
25782                    throw new IllegalArgumentException(
25783                            "setFocusedActivity: No activity record matching token=" + token);
25784                }
25785                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
25786                        r, "setFocusedActivity")) {
25787                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
25788                }
25789            }
25790        }
25791
25792        @Override
25793        public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
25794            synchronized (ActivityManagerService.this) {
25795                if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
25796                    ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
25797                    if (types == null) {
25798                        if (uid < 0) {
25799                            return;
25800                        }
25801                        types = new ArrayMap<>();
25802                        mAllowAppSwitchUids.put(userId, types);
25803                    }
25804                    if (uid < 0) {
25805                        types.remove(type);
25806                    } else {
25807                        types.put(type, uid);
25808                    }
25809                }
25810            }
25811        }
25812
25813        @Override
25814        public boolean isRuntimeRestarted() {
25815            return mSystemServiceManager.isRuntimeRestarted();
25816        }
25817
25818        @Override
25819        public boolean hasRunningActivity(int uid, @Nullable String packageName) {
25820            if (packageName == null) return false;
25821
25822            synchronized (ActivityManagerService.this) {
25823                for (int i = 0; i < mLruProcesses.size(); i++) {
25824                    final ProcessRecord processRecord = mLruProcesses.get(i);
25825                    if (processRecord.uid == uid) {
25826                        for (int j = 0; j < processRecord.activities.size(); j++) {
25827                            final ActivityRecord activityRecord = processRecord.activities.get(j);
25828                            if (packageName.equals(activityRecord.packageName)) {
25829                                return true;
25830                            }
25831                        }
25832                    }
25833                }
25834            }
25835            return false;
25836        }
25837
25838        @Override
25839        public void registerScreenObserver(ScreenObserver observer) {
25840            mScreenObservers.add(observer);
25841        }
25842
25843        @Override
25844        public boolean canStartMoreUsers() {
25845            return mUserController.canStartMoreUsers();
25846        }
25847
25848        @Override
25849        public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
25850            mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
25851        }
25852
25853        @Override
25854        public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
25855            mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
25856        }
25857
25858        @Override
25859        public int getMaxRunningUsers() {
25860            return mUserController.mMaxRunningUsers;
25861        }
25862
25863        public boolean isCallerRecents(int callingUid) {
25864            return getRecentTasks().isCallerRecents(callingUid);
25865        }
25866
25867        @Override
25868        public boolean isUidActive(int uid) {
25869            synchronized (ActivityManagerService.this) {
25870                final UidRecord uidRec = mActiveUids.get(uid);
25871                return (uidRec != null) && !uidRec.idle;
25872            }
25873        }
25874    }
25875
25876    /**
25877     * Called by app main thread to wait for the network policy rules to get updated.
25878     *
25879     * @param procStateSeq The sequence number indicating the process state change that the main
25880     *                     thread is interested in.
25881     */
25882    @Override
25883    public void waitForNetworkStateUpdate(long procStateSeq) {
25884        final int callingUid = Binder.getCallingUid();
25885        if (DEBUG_NETWORK) {
25886            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
25887        }
25888        UidRecord record;
25889        synchronized (this) {
25890            record = mActiveUids.get(callingUid);
25891            if (record == null) {
25892                return;
25893            }
25894        }
25895        synchronized (record.networkStateLock) {
25896            if (record.lastDispatchedProcStateSeq < procStateSeq) {
25897                if (DEBUG_NETWORK) {
25898                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
25899                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
25900                            + " lastProcStateSeqDispatchedToObservers: "
25901                            + record.lastDispatchedProcStateSeq);
25902                }
25903                return;
25904            }
25905            if (record.curProcStateSeq > procStateSeq) {
25906                if (DEBUG_NETWORK) {
25907                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
25908                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
25909                            + ", procStateSeq: " + procStateSeq);
25910                }
25911                return;
25912            }
25913            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
25914                if (DEBUG_NETWORK) {
25915                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
25916                            + procStateSeq + ", so no need to wait. Uid: "
25917                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
25918                            + record.lastNetworkUpdatedProcStateSeq);
25919                }
25920                return;
25921            }
25922            try {
25923                if (DEBUG_NETWORK) {
25924                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
25925                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
25926                }
25927                final long startTime = SystemClock.uptimeMillis();
25928                record.waitingForNetwork = true;
25929                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
25930                record.waitingForNetwork = false;
25931                final long totalTime = SystemClock.uptimeMillis() - startTime;
25932                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
25933                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
25934                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
25935                            + procStateSeq + " UidRec: " + record
25936                            + " validateUidRec: " + mValidateUids.get(callingUid));
25937                }
25938            } catch (InterruptedException e) {
25939                Thread.currentThread().interrupt();
25940            }
25941        }
25942    }
25943
25944    public void waitForBroadcastIdle(PrintWriter pw) {
25945        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
25946        while (true) {
25947            boolean idle = true;
25948            synchronized (this) {
25949                for (BroadcastQueue queue : mBroadcastQueues) {
25950                    if (!queue.isIdle()) {
25951                        final String msg = "Waiting for queue " + queue + " to become idle...";
25952                        pw.println(msg);
25953                        pw.flush();
25954                        Slog.v(TAG, msg);
25955                        idle = false;
25956                    }
25957                }
25958            }
25959
25960            if (idle) {
25961                final String msg = "All broadcast queues are idle!";
25962                pw.println(msg);
25963                pw.flush();
25964                Slog.v(TAG, msg);
25965                return;
25966            } else {
25967                SystemClock.sleep(1000);
25968            }
25969        }
25970    }
25971
25972    /**
25973     * Return the user id of the last resumed activity.
25974     */
25975    @Override
25976    public @UserIdInt int getLastResumedActivityUserId() {
25977        enforceCallingPermission(
25978                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
25979        synchronized (this) {
25980            if (mLastResumedActivity == null) {
25981                return mUserController.getCurrentUserId();
25982            }
25983            return mLastResumedActivity.userId;
25984        }
25985    }
25986
25987    /**
25988     * Kill processes for the user with id userId and that depend on the package named packageName
25989     */
25990    @Override
25991    public void killPackageDependents(String packageName, int userId) {
25992        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
25993        if (packageName == null) {
25994            throw new NullPointerException(
25995                    "Cannot kill the dependents of a package without its name.");
25996        }
25997
25998        long callingId = Binder.clearCallingIdentity();
25999        IPackageManager pm = AppGlobals.getPackageManager();
26000        int pkgUid = -1;
26001        try {
26002            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
26003        } catch (RemoteException e) {
26004        }
26005        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
26006            throw new IllegalArgumentException(
26007                    "Cannot kill dependents of non-existing package " + packageName);
26008        }
26009        try {
26010            synchronized(this) {
26011                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
26012                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
26013                        "dep: " + packageName);
26014            }
26015        } finally {
26016            Binder.restoreCallingIdentity(callingId);
26017        }
26018    }
26019
26020    @Override
26021    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
26022            CharSequence message) throws RemoteException {
26023        if (message != null) {
26024            enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
26025                    "dismissKeyguard()");
26026        }
26027        final long callingId = Binder.clearCallingIdentity();
26028        try {
26029            mKeyguardController.dismissKeyguard(token, callback, message);
26030        } finally {
26031            Binder.restoreCallingIdentity(callingId);
26032        }
26033    }
26034
26035    @Override
26036    public int restartUserInBackground(final int userId) {
26037        return mUserController.restartUser(userId, /* foreground */ false);
26038    }
26039
26040    @Override
26041    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
26042        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
26043                "scheduleApplicationInfoChanged()");
26044
26045        synchronized (this) {
26046            final long origId = Binder.clearCallingIdentity();
26047            try {
26048                updateApplicationInfoLocked(packageNames, userId);
26049            } finally {
26050                Binder.restoreCallingIdentity(origId);
26051            }
26052        }
26053    }
26054
26055    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
26056        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
26057        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
26058            final ProcessRecord app = mLruProcesses.get(i);
26059            if (app.thread == null) {
26060                continue;
26061            }
26062
26063            if (userId != UserHandle.USER_ALL && app.userId != userId) {
26064                continue;
26065            }
26066
26067            final int packageCount = app.pkgList.size();
26068            for (int j = 0; j < packageCount; j++) {
26069                final String packageName = app.pkgList.keyAt(j);
26070                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
26071                    try {
26072                        final ApplicationInfo ai = AppGlobals.getPackageManager()
26073                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
26074                        if (ai != null) {
26075                            app.thread.scheduleApplicationInfoChanged(ai);
26076                        }
26077                    } catch (RemoteException e) {
26078                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
26079                                    packageName, app));
26080                    }
26081                }
26082            }
26083        }
26084        if (updateFrameworkRes) {
26085            // Update system server components that need to know about changed overlays. Because the
26086            // overlay is applied in ActivityThread, we need to serialize through its thread too.
26087            final Executor executor = ActivityThread.currentActivityThread().getExecutor();
26088            final DisplayManagerInternal display =
26089                    LocalServices.getService(DisplayManagerInternal.class);
26090            if (display != null) {
26091                executor.execute(display::onOverlayChanged);
26092            }
26093            if (mWindowManager != null) {
26094                executor.execute(mWindowManager::onOverlayChanged);
26095            }
26096        }
26097    }
26098
26099    /**
26100     * Attach an agent to the specified process (proces name or PID)
26101     */
26102    public void attachAgent(String process, String path) {
26103        try {
26104            synchronized (this) {
26105                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
26106                if (proc == null || proc.thread == null) {
26107                    throw new IllegalArgumentException("Unknown process: " + process);
26108                }
26109
26110                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26111                if (!isDebuggable) {
26112                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26113                        throw new SecurityException("Process not debuggable: " + proc);
26114                    }
26115                }
26116
26117                proc.thread.attachAgent(path);
26118            }
26119        } catch (RemoteException e) {
26120            throw new IllegalStateException("Process disappeared");
26121        }
26122    }
26123
26124    @VisibleForTesting
26125    public static class Injector {
26126        private NetworkManagementInternal mNmi;
26127
26128        public Context getContext() {
26129            return null;
26130        }
26131
26132        public AppOpsService getAppOpsService(File file, Handler handler) {
26133            return new AppOpsService(file, handler);
26134        }
26135
26136        public Handler getUiHandler(ActivityManagerService service) {
26137            return service.new UiHandler();
26138        }
26139
26140        public boolean isNetworkRestrictedForUid(int uid) {
26141            if (ensureHasNetworkManagementInternal()) {
26142                return mNmi.isNetworkRestrictedForUid(uid);
26143            }
26144            return false;
26145        }
26146
26147        private boolean ensureHasNetworkManagementInternal() {
26148            if (mNmi == null) {
26149                mNmi = LocalServices.getService(NetworkManagementInternal.class);
26150            }
26151            return mNmi != null;
26152        }
26153    }
26154
26155    @Override
26156    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
26157            throws RemoteException {
26158        synchronized (this) {
26159            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26160            if (r == null) {
26161                return;
26162            }
26163            final long origId = Binder.clearCallingIdentity();
26164            try {
26165                r.setShowWhenLocked(showWhenLocked);
26166            } finally {
26167                Binder.restoreCallingIdentity(origId);
26168            }
26169        }
26170    }
26171
26172    @Override
26173    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
26174        synchronized (this) {
26175            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26176            if (r == null) {
26177                return;
26178            }
26179            final long origId = Binder.clearCallingIdentity();
26180            try {
26181                r.setTurnScreenOn(turnScreenOn);
26182            } finally {
26183                Binder.restoreCallingIdentity(origId);
26184            }
26185        }
26186    }
26187
26188    @Override
26189    public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
26190            throws RemoteException {
26191        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
26192                "registerRemoteAnimations");
26193        synchronized (this) {
26194            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26195            if (r == null) {
26196                return;
26197            }
26198            final long origId = Binder.clearCallingIdentity();
26199            try {
26200                r.registerRemoteAnimations(definition);
26201            } finally {
26202                Binder.restoreCallingIdentity(origId);
26203            }
26204        }
26205    }
26206}
26207