ActivityManagerService.java revision 51c66ea459acdfe8d90ed49637271981b46d0e50
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 com.android.internal.R;
389import com.android.internal.annotations.GuardedBy;
390import com.android.internal.annotations.VisibleForTesting;
391import com.android.internal.app.AssistUtils;
392import com.android.internal.app.DumpHeapActivity;
393import com.android.internal.app.IAppOpsCallback;
394import com.android.internal.app.IAppOpsService;
395import com.android.internal.app.IVoiceInteractor;
396import com.android.internal.app.ProcessMap;
397import com.android.internal.app.SystemUserHomeActivity;
398import com.android.internal.app.procstats.ProcessStats;
399import com.android.internal.logging.MetricsLogger;
400import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
401import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
402import com.android.internal.notification.SystemNotificationChannels;
403import com.android.internal.os.BackgroundThread;
404import com.android.internal.os.BatteryStatsImpl;
405import com.android.internal.os.BinderInternal;
406import com.android.internal.os.logging.MetricsLoggerWrapper;
407import com.android.internal.os.ByteTransferPipe;
408import com.android.internal.os.IResultReceiver;
409import com.android.internal.os.ProcessCpuTracker;
410import com.android.internal.os.TransferPipe;
411import com.android.internal.os.Zygote;
412import com.android.internal.policy.IKeyguardDismissCallback;
413import com.android.internal.policy.KeyguardDismissCallback;
414import com.android.internal.telephony.TelephonyIntents;
415import com.android.internal.util.ArrayUtils;
416import com.android.internal.util.DumpUtils;
417import com.android.internal.util.FastPrintWriter;
418import com.android.internal.util.FastXmlSerializer;
419import com.android.internal.util.MemInfoReader;
420import com.android.internal.util.Preconditions;
421import com.android.server.AlarmManagerInternal;
422import com.android.server.AppOpsService;
423import com.android.server.AttributeCache;
424import com.android.server.DeviceIdleController;
425import com.android.server.IntentResolver;
426import com.android.server.IoThread;
427import com.android.server.LocalServices;
428import com.android.server.LockGuard;
429import com.android.server.NetworkManagementInternal;
430import com.android.server.RescueParty;
431import com.android.server.ServiceThread;
432import com.android.server.SystemConfig;
433import com.android.server.SystemService;
434import com.android.server.SystemServiceManager;
435import com.android.server.ThreadPriorityBooster;
436import com.android.server.Watchdog;
437import com.android.server.am.ActivityStack.ActivityState;
438import com.android.server.am.proto.ActivityManagerServiceProto;
439import com.android.server.am.proto.BroadcastProto;
440import com.android.server.am.proto.GrantUriProto;
441import com.android.server.am.proto.ImportanceTokenProto;
442import com.android.server.am.proto.MemInfoProto;
443import com.android.server.am.proto.NeededUriGrantsProto;
444import com.android.server.am.proto.ProcessOomProto;
445import com.android.server.am.proto.ProcessToGcProto;
446import com.android.server.am.proto.ProcessesProto;
447import com.android.server.am.proto.ProcessesProto.UidObserverRegistrationProto;
448import com.android.server.am.proto.StickyBroadcastProto;
449import com.android.server.firewall.IntentFirewall;
450import com.android.server.job.JobSchedulerInternal;
451import com.android.server.pm.Installer;
452import com.android.server.pm.Installer.InstallerException;
453import com.android.server.utils.PriorityDump;
454import com.android.server.vr.VrManagerInternal;
455import com.android.server.wm.PinnedStackWindowController;
456import com.android.server.wm.RecentsAnimationController;
457import com.android.server.wm.WindowManagerService;
458
459import dalvik.system.VMRuntime;
460
461import libcore.io.IoUtils;
462import libcore.util.EmptyArray;
463
464import com.google.android.collect.Lists;
465import com.google.android.collect.Maps;
466
467import org.xmlpull.v1.XmlPullParser;
468import org.xmlpull.v1.XmlPullParserException;
469import org.xmlpull.v1.XmlSerializer;
470
471import java.io.File;
472import java.io.FileDescriptor;
473import java.io.FileInputStream;
474import java.io.FileNotFoundException;
475import java.io.FileOutputStream;
476import java.io.IOException;
477import java.io.InputStreamReader;
478import java.io.PrintWriter;
479import java.io.StringWriter;
480import java.io.UnsupportedEncodingException;
481import java.lang.ref.WeakReference;
482import java.nio.charset.StandardCharsets;
483import java.text.DateFormat;
484import java.text.SimpleDateFormat;
485import java.util.ArrayList;
486import java.util.Arrays;
487import java.util.Collections;
488import java.util.Comparator;
489import java.util.Date;
490import java.util.HashMap;
491import java.util.HashSet;
492import java.util.Iterator;
493import java.util.List;
494import java.util.Locale;
495import java.util.Map;
496import java.util.Objects;
497import java.util.Set;
498import java.util.concurrent.CountDownLatch;
499import java.util.concurrent.Executor;
500import java.util.concurrent.atomic.AtomicBoolean;
501import java.util.concurrent.atomic.AtomicLong;
502
503public class ActivityManagerService extends IActivityManager.Stub
504        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
505
506    /**
507     * Priority we boost main thread and RT of top app to.
508     */
509    public static final int TOP_APP_PRIORITY_BOOST = -10;
510
511    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
512    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
513    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
514    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
515    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
516    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
517    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
518    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
519    private static final String TAG_LRU = TAG + POSTFIX_LRU;
520    private static final String TAG_MU = TAG + POSTFIX_MU;
521    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
522    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
523    private static final String TAG_POWER = TAG + POSTFIX_POWER;
524    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
525    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
526    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
527    private static final String TAG_PSS = TAG + POSTFIX_PSS;
528    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
529    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
530    private static final String TAG_STACK = TAG + POSTFIX_STACK;
531    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
532    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
533    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
534    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
535
536    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
537    // here so that while the job scheduler can depend on AMS, the other way around
538    // need not be the case.
539    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
540
541    /** Control over CPU and battery monitoring */
542    // write battery stats every 30 minutes.
543    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
544    static final boolean MONITOR_CPU_USAGE = true;
545    // don't sample cpu less than every 5 seconds.
546    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
547    // wait possibly forever for next cpu sample.
548    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
549    static final boolean MONITOR_THREAD_CPU_USAGE = false;
550
551    // The flags that are set for all calls we make to the package manager.
552    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
553
554    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
555
556    // Amount of time after a call to stopAppSwitches() during which we will
557    // prevent further untrusted switches from happening.
558    static final long APP_SWITCH_DELAY_TIME = 5*1000;
559
560    // How long we wait for a launched process to attach to the activity manager
561    // before we decide it's never going to come up for real.
562    static final int PROC_START_TIMEOUT = 10*1000;
563    // How long we wait for an attached process to publish its content providers
564    // before we decide it must be hung.
565    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
566
567    // How long we wait for a launched process to attach to the activity manager
568    // before we decide it's never going to come up for real, when the process was
569    // started with a wrapper for instrumentation (such as Valgrind) because it
570    // could take much longer than usual.
571    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
572
573    // How long we allow a receiver to run before giving up on it.
574    static final int BROADCAST_FG_TIMEOUT = 10*1000;
575    static final int BROADCAST_BG_TIMEOUT = 60*1000;
576
577    // How long we wait until we timeout on key dispatching.
578    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
579
580    // How long we wait until we timeout on key dispatching during instrumentation.
581    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
582
583    // How long to wait in getAssistContextExtras for the activity and foreground services
584    // to respond with the result.
585    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
586
587    // How long top wait when going through the modern assist (which doesn't need to block
588    // on getting this result before starting to launch its UI).
589    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
590
591    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
592    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
593
594    // Maximum number of persisted Uri grants a package is allowed
595    static final int MAX_PERSISTED_URI_GRANTS = 128;
596
597    static final int MY_PID = myPid();
598
599    static final String[] EMPTY_STRING_ARRAY = new String[0];
600
601    // How many bytes to write into the dropbox log before truncating
602    static final int DROPBOX_MAX_SIZE = 192 * 1024;
603    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
604    // as one line, but close enough for now.
605    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
606
607    // Access modes for handleIncomingUser.
608    static final int ALLOW_NON_FULL = 0;
609    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
610    static final int ALLOW_FULL_ONLY = 2;
611
612    // Necessary ApplicationInfo flags to mark an app as persistent
613    private static final int PERSISTENT_MASK =
614            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
615
616    // Intent sent when remote bugreport collection has been completed
617    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
618            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
619
620    // Used to indicate that an app transition should be animated.
621    static final boolean ANIMATE = true;
622
623    // Determines whether to take full screen screenshots
624    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
625
626    /**
627     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
628     */
629    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
630
631    /**
632     * State indicating that there is no need for any blocking for network.
633     */
634    @VisibleForTesting
635    static final int NETWORK_STATE_NO_CHANGE = 0;
636
637    /**
638     * State indicating that the main thread needs to be informed about the network wait.
639     */
640    @VisibleForTesting
641    static final int NETWORK_STATE_BLOCK = 1;
642
643    /**
644     * State indicating that any threads waiting for network state to get updated can be unblocked.
645     */
646    @VisibleForTesting
647    static final int NETWORK_STATE_UNBLOCK = 2;
648
649    // Max character limit for a notification title. If the notification title is larger than this
650    // the notification will not be legible to the user.
651    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
652
653    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
654
655    /** All system services */
656    SystemServiceManager mSystemServiceManager;
657
658    // Wrapper around VoiceInteractionServiceManager
659    private AssistUtils mAssistUtils;
660
661    // Keeps track of the active voice interaction service component, notified from
662    // VoiceInteractionManagerService
663    ComponentName mActiveVoiceInteractionServiceComponent;
664
665    private Installer mInstaller;
666
667    /** Run all ActivityStacks through this */
668    final ActivityStackSupervisor mStackSupervisor;
669    private final KeyguardController mKeyguardController;
670
671    private final ActivityStartController mActivityStartController;
672
673    final ClientLifecycleManager mLifecycleManager;
674
675    final TaskChangeNotificationController mTaskChangeNotificationController;
676
677    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
678
679    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
680
681    public final IntentFirewall mIntentFirewall;
682
683    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
684    // default action automatically.  Important for devices without direct input
685    // devices.
686    private boolean mShowDialogs = true;
687
688    private final VrController mVrController;
689
690    // VR Vr2d Display Id.
691    int mVr2dDisplayId = INVALID_DISPLAY;
692
693    // Whether we should use SCHED_FIFO for UI and RenderThreads.
694    private boolean mUseFifoUiScheduling = false;
695
696    BroadcastQueue mFgBroadcastQueue;
697    BroadcastQueue mBgBroadcastQueue;
698    // Convenient for easy iteration over the queues. Foreground is first
699    // so that dispatch of foreground broadcasts gets precedence.
700    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
701
702    BroadcastStats mLastBroadcastStats;
703    BroadcastStats mCurBroadcastStats;
704
705    BroadcastQueue broadcastQueueForIntent(Intent intent) {
706        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
707        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
708                "Broadcast intent " + intent + " on "
709                + (isFg ? "foreground" : "background") + " queue");
710        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
711    }
712
713    /**
714     * The last resumed activity. This is identical to the current resumed activity most
715     * of the time but could be different when we're pausing one activity before we resume
716     * another activity.
717     */
718    private ActivityRecord mLastResumedActivity;
719
720    /**
721     * If non-null, we are tracking the time the user spends in the currently focused app.
722     */
723    private AppTimeTracker mCurAppTimeTracker;
724
725    /**
726     * List of intents that were used to start the most recent tasks.
727     */
728    private final RecentTasks mRecentTasks;
729
730    /**
731     * For addAppTask: cached of the last activity component that was added.
732     */
733    ComponentName mLastAddedTaskComponent;
734
735    /**
736     * For addAppTask: cached of the last activity uid that was added.
737     */
738    int mLastAddedTaskUid;
739
740    /**
741     * For addAppTask: cached of the last ActivityInfo that was added.
742     */
743    ActivityInfo mLastAddedTaskActivity;
744
745    /**
746     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
747     */
748    String mDeviceOwnerName;
749
750    /**
751     * The controller for all operations related to locktask.
752     */
753    final LockTaskController mLockTaskController;
754
755    final UserController mUserController;
756
757    /**
758     * Packages that are being allowed to perform unrestricted app switches.  Mapping is
759     * User -> Type -> uid.
760     */
761    final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
762
763    final AppErrors mAppErrors;
764
765    final AppWarnings mAppWarnings;
766
767    /**
768     * Dump of the activity state at the time of the last ANR. Cleared after
769     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
770     */
771    String mLastANRState;
772
773    /**
774     * Indicates the maximum time spent waiting for the network rules to get updated.
775     */
776    @VisibleForTesting
777    long mWaitForNetworkTimeoutMs;
778
779    /**
780     * Helper class which parses out priority arguments and dumps sections according to their
781     * priority. If priority arguments are omitted, function calls the legacy dump command.
782     */
783    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
784        @Override
785        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
786                boolean asProto) {
787            if (asProto) return;
788            doDump(fd, pw, new String[]{"activities"}, asProto);
789        }
790
791        @Override
792        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
793            if (asProto) {
794                doDump(fd, pw, new String[0], asProto);
795            } else {
796                doDump(fd, pw, new String[]{"settings"}, asProto);
797                doDump(fd, pw, new String[]{"intents"}, asProto);
798                doDump(fd, pw, new String[]{"broadcasts"}, asProto);
799                doDump(fd, pw, new String[]{"providers"}, asProto);
800                doDump(fd, pw, new String[]{"permissions"}, asProto);
801                doDump(fd, pw, new String[]{"services"}, asProto);
802                doDump(fd, pw, new String[]{"recents"}, asProto);
803                doDump(fd, pw, new String[]{"lastanr"}, asProto);
804                doDump(fd, pw, new String[]{"starter"}, asProto);
805                if (mAssociations.size() > 0) {
806                    doDump(fd, pw, new String[]{"associations"}, asProto);
807                }
808                doDump(fd, pw, new String[]{"processes"}, asProto);
809            }
810        }
811
812        @Override
813        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
814            doDump(fd, pw, args, asProto);
815        }
816    };
817
818    public boolean canShowErrorDialogs() {
819        return mShowDialogs && !mSleeping && !mShuttingDown
820                && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
821                && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
822                        mUserController.getCurrentUserId())
823                && !(UserManager.isDeviceInDemoMode(mContext)
824                        && mUserController.getCurrentUser().isDemo());
825    }
826
827    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
828            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
829
830    static void boostPriorityForLockedSection() {
831        sThreadPriorityBooster.boost();
832    }
833
834    static void resetPriorityAfterLockedSection() {
835        sThreadPriorityBooster.reset();
836    }
837
838    public class PendingAssistExtras extends Binder implements Runnable {
839        public final ActivityRecord activity;
840        public boolean isHome;
841        public final Bundle extras;
842        public final Intent intent;
843        public final String hint;
844        public final IAssistDataReceiver receiver;
845        public final int userHandle;
846        public boolean haveResult = false;
847        public Bundle result = null;
848        public AssistStructure structure = null;
849        public AssistContent content = null;
850        public Bundle receiverExtras;
851
852        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
853                String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
854                int _userHandle) {
855            activity = _activity;
856            extras = _extras;
857            intent = _intent;
858            hint = _hint;
859            receiver = _receiver;
860            receiverExtras = _receiverExtras;
861            userHandle = _userHandle;
862        }
863
864        @Override
865        public void run() {
866            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
867            synchronized (this) {
868                haveResult = true;
869                notifyAll();
870            }
871            pendingAssistExtrasTimedOut(this);
872        }
873    }
874
875    final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
876
877    /**
878     * Process management.
879     */
880    final ProcessList mProcessList = new ProcessList();
881
882    /**
883     * All of the applications we currently have running organized by name.
884     * The keys are strings of the application package name (as
885     * returned by the package manager), and the keys are ApplicationRecord
886     * objects.
887     */
888    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
889
890    /**
891     * Tracking long-term execution of processes to look for abuse and other
892     * bad app behavior.
893     */
894    final ProcessStatsService mProcessStats;
895
896    /**
897     * The currently running isolated processes.
898     */
899    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
900
901    /**
902     * Counter for assigning isolated process uids, to avoid frequently reusing the
903     * same ones.
904     */
905    int mNextIsolatedProcessUid = 0;
906
907    /**
908     * The currently running heavy-weight process, if any.
909     */
910    ProcessRecord mHeavyWeightProcess = null;
911
912    /**
913     * Non-persistent appId whitelist for background restrictions
914     */
915    int[] mBackgroundAppIdWhitelist = new int[] {
916            BLUETOOTH_UID
917    };
918
919    /**
920     * Broadcast actions that will always be deliverable to unlaunched/background apps
921     */
922    ArraySet<String> mBackgroundLaunchBroadcasts;
923
924    /**
925     * All of the processes we currently have running organized by pid.
926     * The keys are the pid running the application.
927     *
928     * <p>NOTE: This object is protected by its own lock, NOT the global
929     * activity manager lock!
930     */
931    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
932
933    /**
934     * All of the processes that have been forced to be important.  The key
935     * is the pid of the caller who requested it (we hold a death
936     * link on it).
937     */
938    abstract class ImportanceToken implements IBinder.DeathRecipient {
939        final int pid;
940        final IBinder token;
941        final String reason;
942
943        ImportanceToken(int _pid, IBinder _token, String _reason) {
944            pid = _pid;
945            token = _token;
946            reason = _reason;
947        }
948
949        @Override
950        public String toString() {
951            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
952                    + " " + reason + " " + pid + " " + token + " }";
953        }
954
955        void writeToProto(ProtoOutputStream proto, long fieldId) {
956            final long pToken = proto.start(fieldId);
957            proto.write(ImportanceTokenProto.PID, pid);
958            if (token != null) {
959                proto.write(ImportanceTokenProto.TOKEN, token.toString());
960            }
961            proto.write(ImportanceTokenProto.REASON, reason);
962            proto.end(pToken);
963        }
964    }
965    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
966
967    /**
968     * List of records for processes that someone had tried to start before the
969     * system was ready.  We don't start them at that point, but ensure they
970     * are started by the time booting is complete.
971     */
972    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
973
974    /**
975     * List of persistent applications that are in the process
976     * of being started.
977     */
978    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
979
980    /**
981     * Processes that are being forcibly torn down.
982     */
983    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
984
985    /**
986     * List of running applications, sorted by recent usage.
987     * The first entry in the list is the least recently used.
988     */
989    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
990
991    /**
992     * Where in mLruProcesses that the processes hosting activities start.
993     */
994    int mLruProcessActivityStart = 0;
995
996    /**
997     * Where in mLruProcesses that the processes hosting services start.
998     * This is after (lower index) than mLruProcessesActivityStart.
999     */
1000    int mLruProcessServiceStart = 0;
1001
1002    /**
1003     * List of processes that should gc as soon as things are idle.
1004     */
1005    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
1006
1007    /**
1008     * Processes we want to collect PSS data from.
1009     */
1010    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
1011
1012    private boolean mBinderTransactionTrackingEnabled = false;
1013
1014    /**
1015     * Last time we requested PSS data of all processes.
1016     */
1017    long mLastFullPssTime = SystemClock.uptimeMillis();
1018
1019    /**
1020     * If set, the next time we collect PSS data we should do a full collection
1021     * with data from native processes and the kernel.
1022     */
1023    boolean mFullPssPending = false;
1024
1025    /**
1026     * This is the process holding what we currently consider to be
1027     * the "home" activity.
1028     */
1029    ProcessRecord mHomeProcess;
1030
1031    /**
1032     * This is the process holding the activity the user last visited that
1033     * is in a different process from the one they are currently in.
1034     */
1035    ProcessRecord mPreviousProcess;
1036
1037    /**
1038     * The time at which the previous process was last visible.
1039     */
1040    long mPreviousProcessVisibleTime;
1041
1042    /**
1043     * Track all uids that have actively running processes.
1044     */
1045    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1046
1047    /**
1048     * This is for verifying the UID report flow.
1049     */
1050    static final boolean VALIDATE_UID_STATES = true;
1051    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1052
1053    /**
1054     * Packages that the user has asked to have run in screen size
1055     * compatibility mode instead of filling the screen.
1056     */
1057    final CompatModePackages mCompatModePackages;
1058
1059    /**
1060     * Set of IntentSenderRecord objects that are currently active.
1061     */
1062    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1063            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1064
1065    /**
1066     * Fingerprints (hashCode()) of stack traces that we've
1067     * already logged DropBox entries for.  Guarded by itself.  If
1068     * something (rogue user app) forces this over
1069     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1070     */
1071    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1072    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1073
1074    /**
1075     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1076     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1077     */
1078    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1079
1080    /**
1081     * Resolver for broadcast intents to registered receivers.
1082     * Holds BroadcastFilter (subclass of IntentFilter).
1083     */
1084    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1085            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1086        @Override
1087        protected boolean allowFilterResult(
1088                BroadcastFilter filter, List<BroadcastFilter> dest) {
1089            IBinder target = filter.receiverList.receiver.asBinder();
1090            for (int i = dest.size() - 1; i >= 0; i--) {
1091                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1092                    return false;
1093                }
1094            }
1095            return true;
1096        }
1097
1098        @Override
1099        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1100            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1101                    || userId == filter.owningUserId) {
1102                return super.newResult(filter, match, userId);
1103            }
1104            return null;
1105        }
1106
1107        @Override
1108        protected BroadcastFilter[] newArray(int size) {
1109            return new BroadcastFilter[size];
1110        }
1111
1112        @Override
1113        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1114            return packageName.equals(filter.packageName);
1115        }
1116    };
1117
1118    /**
1119     * State of all active sticky broadcasts per user.  Keys are the action of the
1120     * sticky Intent, values are an ArrayList of all broadcasted intents with
1121     * that action (which should usually be one).  The SparseArray is keyed
1122     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1123     * for stickies that are sent to all users.
1124     */
1125    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1126            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1127
1128    final ActiveServices mServices;
1129
1130    final static class Association {
1131        final int mSourceUid;
1132        final String mSourceProcess;
1133        final int mTargetUid;
1134        final ComponentName mTargetComponent;
1135        final String mTargetProcess;
1136
1137        int mCount;
1138        long mTime;
1139
1140        int mNesting;
1141        long mStartTime;
1142
1143        // states of the source process when the bind occurred.
1144        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1145        long mLastStateUptime;
1146        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1147                - ActivityManager.MIN_PROCESS_STATE+1];
1148
1149        Association(int sourceUid, String sourceProcess, int targetUid,
1150                ComponentName targetComponent, String targetProcess) {
1151            mSourceUid = sourceUid;
1152            mSourceProcess = sourceProcess;
1153            mTargetUid = targetUid;
1154            mTargetComponent = targetComponent;
1155            mTargetProcess = targetProcess;
1156        }
1157    }
1158
1159    /**
1160     * When service association tracking is enabled, this is all of the associations we
1161     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1162     * -> association data.
1163     */
1164    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1165            mAssociations = new SparseArray<>();
1166    boolean mTrackingAssociations;
1167
1168    /**
1169     * Backup/restore process management
1170     */
1171    String mBackupAppName = null;
1172    BackupRecord mBackupTarget = null;
1173
1174    final ProviderMap mProviderMap;
1175
1176    /**
1177     * List of content providers who have clients waiting for them.  The
1178     * application is currently being launched and the provider will be
1179     * removed from this list once it is published.
1180     */
1181    final ArrayList<ContentProviderRecord> mLaunchingProviders
1182            = new ArrayList<ContentProviderRecord>();
1183
1184    /**
1185     * File storing persisted {@link #mGrantedUriPermissions}.
1186     */
1187    private final AtomicFile mGrantFile;
1188
1189    /** XML constants used in {@link #mGrantFile} */
1190    private static final String TAG_URI_GRANTS = "uri-grants";
1191    private static final String TAG_URI_GRANT = "uri-grant";
1192    private static final String ATTR_USER_HANDLE = "userHandle";
1193    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1194    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1195    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1196    private static final String ATTR_TARGET_PKG = "targetPkg";
1197    private static final String ATTR_URI = "uri";
1198    private static final String ATTR_MODE_FLAGS = "modeFlags";
1199    private static final String ATTR_CREATED_TIME = "createdTime";
1200    private static final String ATTR_PREFIX = "prefix";
1201
1202    /**
1203     * Global set of specific {@link Uri} permissions that have been granted.
1204     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1205     * to {@link UriPermission#uri} to {@link UriPermission}.
1206     */
1207    @GuardedBy("this")
1208    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1209            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1210
1211    public static class GrantUri {
1212        public final int sourceUserId;
1213        public final Uri uri;
1214        public boolean prefix;
1215
1216        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1217            this.sourceUserId = sourceUserId;
1218            this.uri = uri;
1219            this.prefix = prefix;
1220        }
1221
1222        @Override
1223        public int hashCode() {
1224            int hashCode = 1;
1225            hashCode = 31 * hashCode + sourceUserId;
1226            hashCode = 31 * hashCode + uri.hashCode();
1227            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1228            return hashCode;
1229        }
1230
1231        @Override
1232        public boolean equals(Object o) {
1233            if (o instanceof GrantUri) {
1234                GrantUri other = (GrantUri) o;
1235                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1236                        && prefix == other.prefix;
1237            }
1238            return false;
1239        }
1240
1241        @Override
1242        public String toString() {
1243            String result = uri.toString() + " [user " + sourceUserId + "]";
1244            if (prefix) result += " [prefix]";
1245            return result;
1246        }
1247
1248        public String toSafeString() {
1249            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1250            if (prefix) result += " [prefix]";
1251            return result;
1252        }
1253
1254        public void writeToProto(ProtoOutputStream proto, long fieldId) {
1255            long token = proto.start(fieldId);
1256            proto.write(GrantUriProto.URI, uri.toString());
1257            proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
1258            proto.end(token);
1259        }
1260
1261        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1262            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1263                    ContentProvider.getUriWithoutUserId(uri), false);
1264        }
1265    }
1266
1267    CoreSettingsObserver mCoreSettingsObserver;
1268
1269    FontScaleSettingObserver mFontScaleSettingObserver;
1270
1271    private final class FontScaleSettingObserver extends ContentObserver {
1272        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1273
1274        public FontScaleSettingObserver() {
1275            super(mHandler);
1276            ContentResolver resolver = mContext.getContentResolver();
1277            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1278        }
1279
1280        @Override
1281        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1282            if (mFontScaleUri.equals(uri)) {
1283                updateFontScaleIfNeeded(userId);
1284            }
1285        }
1286    }
1287
1288    /**
1289     * Thread-local storage used to carry caller permissions over through
1290     * indirect content-provider access.
1291     */
1292    private class Identity {
1293        public final IBinder token;
1294        public final int pid;
1295        public final int uid;
1296
1297        Identity(IBinder _token, int _pid, int _uid) {
1298            token = _token;
1299            pid = _pid;
1300            uid = _uid;
1301        }
1302    }
1303
1304    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1305
1306    /**
1307     * All information we have collected about the runtime performance of
1308     * any user id that can impact battery performance.
1309     */
1310    final BatteryStatsService mBatteryStatsService;
1311
1312    /**
1313     * Information about component usage
1314     */
1315    UsageStatsManagerInternal mUsageStatsService;
1316
1317    /**
1318     * Access to DeviceIdleController service.
1319     */
1320    DeviceIdleController.LocalService mLocalDeviceIdleController;
1321
1322    /**
1323     * Set of app ids that are whitelisted for device idle and thus background check.
1324     */
1325    int[] mDeviceIdleWhitelist = new int[0];
1326
1327    /**
1328     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1329     */
1330    int[] mDeviceIdleTempWhitelist = new int[0];
1331
1332    static final class PendingTempWhitelist {
1333        final int targetUid;
1334        final long duration;
1335        final String tag;
1336
1337        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1338            targetUid = _targetUid;
1339            duration = _duration;
1340            tag = _tag;
1341        }
1342
1343        void writeToProto(ProtoOutputStream proto, long fieldId) {
1344            final long token = proto.start(fieldId);
1345            proto.write(ProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
1346            proto.write(ProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
1347            proto.write(ProcessesProto.PendingTempWhitelist.TAG, tag);
1348            proto.end(token);
1349        }
1350    }
1351
1352    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1353
1354    /**
1355     * Information about and control over application operations
1356     */
1357    final AppOpsService mAppOpsService;
1358
1359    /** Current sequencing integer of the configuration, for skipping old configurations. */
1360    private int mConfigurationSeq;
1361
1362    /**
1363     * Temp object used when global and/or display override configuration is updated. It is also
1364     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1365     * anyone...
1366     */
1367    private Configuration mTempConfig = new Configuration();
1368
1369    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1370            new UpdateConfigurationResult();
1371    private static final class UpdateConfigurationResult {
1372        // Configuration changes that were updated.
1373        int changes;
1374        // If the activity was relaunched to match the new configuration.
1375        boolean activityRelaunched;
1376
1377        void reset() {
1378            changes = 0;
1379            activityRelaunched = false;
1380        }
1381    }
1382
1383    boolean mSuppressResizeConfigChanges;
1384
1385    /**
1386     * Hardware-reported OpenGLES version.
1387     */
1388    final int GL_ES_VERSION;
1389
1390    /**
1391     * List of initialization arguments to pass to all processes when binding applications to them.
1392     * For example, references to the commonly used services.
1393     */
1394    HashMap<String, IBinder> mAppBindArgs;
1395    HashMap<String, IBinder> mIsolatedAppBindArgs;
1396
1397    /**
1398     * Temporary to avoid allocations.  Protected by main lock.
1399     */
1400    final StringBuilder mStringBuilder = new StringBuilder(256);
1401
1402    /**
1403     * Used to control how we initialize the service.
1404     */
1405    ComponentName mTopComponent;
1406    String mTopAction = Intent.ACTION_MAIN;
1407    String mTopData;
1408
1409    volatile boolean mProcessesReady = false;
1410    volatile boolean mSystemReady = false;
1411    volatile boolean mOnBattery = false;
1412    volatile int mFactoryTest;
1413
1414    @GuardedBy("this") boolean mBooting = false;
1415    @GuardedBy("this") boolean mCallFinishBooting = false;
1416    @GuardedBy("this") boolean mBootAnimationComplete = false;
1417    @GuardedBy("this") boolean mLaunchWarningShown = false;
1418    private @GuardedBy("this") boolean mCheckedForSetup = false;
1419
1420    final Context mContext;
1421
1422    /**
1423     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1424     * change at runtime. Use mContext for non-UI purposes.
1425     */
1426    final Context mUiContext;
1427
1428    /**
1429     * The time at which we will allow normal application switches again,
1430     * after a call to {@link #stopAppSwitches()}.
1431     */
1432    long mAppSwitchesAllowedTime;
1433
1434    /**
1435     * This is set to true after the first switch after mAppSwitchesAllowedTime
1436     * is set; any switches after that will clear the time.
1437     */
1438    boolean mDidAppSwitch;
1439
1440    /**
1441     * Last time (in uptime) at which we checked for power usage.
1442     */
1443    long mLastPowerCheckUptime;
1444
1445    /**
1446     * Set while we are wanting to sleep, to prevent any
1447     * activities from being started/resumed.
1448     *
1449     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1450     *
1451     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1452     * while in the sleep state until there is a pending transition out of sleep, in which case
1453     * mSleeping is set to false, and remains false while awake.
1454     *
1455     * Whether mSleeping can quickly toggled between true/false without the device actually
1456     * display changing states is undefined.
1457     */
1458    private boolean mSleeping = false;
1459
1460    /**
1461     * The process state used for processes that are running the top activities.
1462     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1463     */
1464    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1465
1466    /**
1467     * Set while we are running a voice interaction.  This overrides
1468     * sleeping while it is active.
1469     */
1470    IVoiceInteractionSession mRunningVoice;
1471
1472    /**
1473     * For some direct access we need to power manager.
1474     */
1475    PowerManagerInternal mLocalPowerManager;
1476
1477    /**
1478     * We want to hold a wake lock while running a voice interaction session, since
1479     * this may happen with the screen off and we need to keep the CPU running to
1480     * be able to continue to interact with the user.
1481     */
1482    PowerManager.WakeLock mVoiceWakeLock;
1483
1484    /**
1485     * State of external calls telling us if the device is awake or asleep.
1486     */
1487    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1488
1489    /**
1490     * Set if we are shutting down the system, similar to sleeping.
1491     */
1492    boolean mShuttingDown = false;
1493
1494    /**
1495     * Current sequence id for oom_adj computation traversal.
1496     */
1497    int mAdjSeq = 0;
1498
1499    /**
1500     * Current sequence id for process LRU updating.
1501     */
1502    int mLruSeq = 0;
1503
1504    /**
1505     * Keep track of the non-cached/empty process we last found, to help
1506     * determine how to distribute cached/empty processes next time.
1507     */
1508    int mNumNonCachedProcs = 0;
1509
1510    /**
1511     * Keep track of the number of cached hidden procs, to balance oom adj
1512     * distribution between those and empty procs.
1513     */
1514    int mNumCachedHiddenProcs = 0;
1515
1516    /**
1517     * Keep track of the number of service processes we last found, to
1518     * determine on the next iteration which should be B services.
1519     */
1520    int mNumServiceProcs = 0;
1521    int mNewNumAServiceProcs = 0;
1522    int mNewNumServiceProcs = 0;
1523
1524    /**
1525     * Allow the current computed overall memory level of the system to go down?
1526     * This is set to false when we are killing processes for reasons other than
1527     * memory management, so that the now smaller process list will not be taken as
1528     * an indication that memory is tighter.
1529     */
1530    boolean mAllowLowerMemLevel = false;
1531
1532    /**
1533     * The last computed memory level, for holding when we are in a state that
1534     * processes are going away for other reasons.
1535     */
1536    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1537
1538    /**
1539     * The last total number of process we have, to determine if changes actually look
1540     * like a shrinking number of process due to lower RAM.
1541     */
1542    int mLastNumProcesses;
1543
1544    /**
1545     * The uptime of the last time we performed idle maintenance.
1546     */
1547    long mLastIdleTime = SystemClock.uptimeMillis();
1548
1549    /**
1550     * Total time spent with RAM that has been added in the past since the last idle time.
1551     */
1552    long mLowRamTimeSinceLastIdle = 0;
1553
1554    /**
1555     * If RAM is currently low, when that horrible situation started.
1556     */
1557    long mLowRamStartTime = 0;
1558
1559    /**
1560     * For reporting to battery stats the current top application.
1561     */
1562    private String mCurResumedPackage = null;
1563    private int mCurResumedUid = -1;
1564
1565    /**
1566     * For reporting to battery stats the apps currently running foreground
1567     * service.  The ProcessMap is package/uid tuples; each of these contain
1568     * an array of the currently foreground processes.
1569     */
1570    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1571            = new ProcessMap<ArrayList<ProcessRecord>>();
1572
1573    /**
1574     * Set if the systemServer made a call to enterSafeMode.
1575     */
1576    boolean mSafeMode;
1577
1578    /**
1579     * If true, we are running under a test environment so will sample PSS from processes
1580     * much more rapidly to try to collect better data when the tests are rapidly
1581     * running through apps.
1582     */
1583    boolean mTestPssMode = false;
1584
1585    String mDebugApp = null;
1586    boolean mWaitForDebugger = false;
1587    boolean mDebugTransient = false;
1588    String mOrigDebugApp = null;
1589    boolean mOrigWaitForDebugger = false;
1590    boolean mAlwaysFinishActivities = false;
1591    boolean mForceResizableActivities;
1592    /**
1593     * Flag that indicates if multi-window is enabled.
1594     *
1595     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1596     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1597     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1598     * At least one of the forms of multi-window must be enabled in order for this flag to be
1599     * initialized to 'true'.
1600     *
1601     * @see #mSupportsSplitScreenMultiWindow
1602     * @see #mSupportsFreeformWindowManagement
1603     * @see #mSupportsPictureInPicture
1604     * @see #mSupportsMultiDisplay
1605     */
1606    boolean mSupportsMultiWindow;
1607    boolean mSupportsSplitScreenMultiWindow;
1608    boolean mSupportsFreeformWindowManagement;
1609    boolean mSupportsPictureInPicture;
1610    boolean mSupportsMultiDisplay;
1611    boolean mSupportsLeanbackOnly;
1612    IActivityController mController = null;
1613    boolean mControllerIsAMonkey = false;
1614    String mProfileApp = null;
1615    ProcessRecord mProfileProc = null;
1616    ProfilerInfo mProfilerInfo = null;
1617
1618    /**
1619     * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
1620     * is not null, this map is checked and the mapped agent installed during bind-time. Note:
1621     * A non-null agent in mProfileInfo overrides this.
1622     */
1623    private @Nullable Map<String, String> mAppAgentMap = null;
1624
1625    int mProfileType = 0;
1626    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1627    String mMemWatchDumpProcName;
1628    String mMemWatchDumpFile;
1629    int mMemWatchDumpPid;
1630    int mMemWatchDumpUid;
1631    String mTrackAllocationApp = null;
1632    String mNativeDebuggingApp = null;
1633
1634    final long[] mTmpLong = new long[3];
1635
1636    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1637
1638    /**
1639     * A global counter for generating sequence numbers.
1640     * This value will be used when incrementing sequence numbers in individual uidRecords.
1641     *
1642     * Having a global counter ensures that seq numbers are monotonically increasing for a
1643     * particular uid even when the uidRecord is re-created.
1644     */
1645    @GuardedBy("this")
1646    @VisibleForTesting
1647    long mProcStateSeqCounter = 0;
1648
1649    /**
1650     * A global counter for generating sequence numbers to uniquely identify pending process starts.
1651     */
1652    @GuardedBy("this")
1653    private long mProcStartSeqCounter = 0;
1654
1655    /**
1656     * Contains {@link ProcessRecord} objects for pending process starts.
1657     *
1658     * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1659     */
1660    @GuardedBy("this")
1661    private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1662
1663    private final Injector mInjector;
1664
1665    static final class ProcessChangeItem {
1666        static final int CHANGE_ACTIVITIES = 1<<0;
1667        int changes;
1668        int uid;
1669        int pid;
1670        int processState;
1671        boolean foregroundActivities;
1672    }
1673
1674    static final class UidObserverRegistration {
1675        final int uid;
1676        final String pkg;
1677        final int which;
1678        final int cutpoint;
1679
1680        final SparseIntArray lastProcStates;
1681
1682        // Please keep the enum lists in sync
1683        private static int[] ORIG_ENUMS = new int[]{
1684                ActivityManager.UID_OBSERVER_IDLE,
1685                ActivityManager.UID_OBSERVER_ACTIVE,
1686                ActivityManager.UID_OBSERVER_GONE,
1687                ActivityManager.UID_OBSERVER_PROCSTATE,
1688        };
1689        private static int[] PROTO_ENUMS = new int[]{
1690                ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
1691                ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
1692                ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
1693                ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
1694        };
1695
1696        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1697            uid = _uid;
1698            pkg = _pkg;
1699            which = _which;
1700            cutpoint = _cutpoint;
1701            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1702                lastProcStates = new SparseIntArray();
1703            } else {
1704                lastProcStates = null;
1705            }
1706        }
1707
1708        void writeToProto(ProtoOutputStream proto, long fieldId) {
1709            final long token = proto.start(fieldId);
1710            proto.write(UidObserverRegistrationProto.UID, uid);
1711            proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
1712            ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
1713                    which, ORIG_ENUMS, PROTO_ENUMS);
1714            proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
1715            if (lastProcStates != null) {
1716                final int NI = lastProcStates.size();
1717                for (int i=0; i<NI; i++) {
1718                    final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
1719                    proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
1720                    proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
1721                    proto.end(pToken);
1722                }
1723            }
1724            proto.end(token);
1725        }
1726    }
1727
1728    final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1729
1730    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1731    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1732
1733    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1734    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1735
1736    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1737    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1738
1739    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1740    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1741
1742    OomAdjObserver mCurOomAdjObserver;
1743    int mCurOomAdjUid;
1744
1745    interface OomAdjObserver {
1746        void onOomAdjMessage(String msg);
1747    }
1748
1749    /**
1750     * Runtime CPU use collection thread.  This object's lock is used to
1751     * perform synchronization with the thread (notifying it to run).
1752     */
1753    final Thread mProcessCpuThread;
1754
1755    /**
1756     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1757     * Must acquire this object's lock when accessing it.
1758     * NOTE: this lock will be held while doing long operations (trawling
1759     * through all processes in /proc), so it should never be acquired by
1760     * any critical paths such as when holding the main activity manager lock.
1761     */
1762    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1763            MONITOR_THREAD_CPU_USAGE);
1764    final AtomicLong mLastCpuTime = new AtomicLong(0);
1765    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1766    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1767
1768    long mLastWriteTime = 0;
1769
1770    /**
1771     * Used to retain an update lock when the foreground activity is in
1772     * immersive mode.
1773     */
1774    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1775
1776    /**
1777     * Set to true after the system has finished booting.
1778     */
1779    boolean mBooted = false;
1780
1781    WindowManagerService mWindowManager;
1782    final ActivityThread mSystemThread;
1783
1784    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1785        final ProcessRecord mApp;
1786        final int mPid;
1787        final IApplicationThread mAppThread;
1788
1789        AppDeathRecipient(ProcessRecord app, int pid,
1790                IApplicationThread thread) {
1791            if (DEBUG_ALL) Slog.v(
1792                TAG, "New death recipient " + this
1793                + " for thread " + thread.asBinder());
1794            mApp = app;
1795            mPid = pid;
1796            mAppThread = thread;
1797        }
1798
1799        @Override
1800        public void binderDied() {
1801            if (DEBUG_ALL) Slog.v(
1802                TAG, "Death received in " + this
1803                + " for thread " + mAppThread.asBinder());
1804            synchronized(ActivityManagerService.this) {
1805                appDiedLocked(mApp, mPid, mAppThread, true);
1806            }
1807        }
1808    }
1809
1810    static final int SHOW_ERROR_UI_MSG = 1;
1811    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1812    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1813    static final int UPDATE_CONFIGURATION_MSG = 4;
1814    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1815    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1816    static final int SERVICE_TIMEOUT_MSG = 12;
1817    static final int UPDATE_TIME_ZONE = 13;
1818    static final int SHOW_UID_ERROR_UI_MSG = 14;
1819    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1820    static final int PROC_START_TIMEOUT_MSG = 20;
1821    static final int KILL_APPLICATION_MSG = 22;
1822    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1823    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1824    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1825    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1826    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1827    static final int CLEAR_DNS_CACHE_MSG = 28;
1828    static final int UPDATE_HTTP_PROXY_MSG = 29;
1829    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1830    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1831    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1832    static final int REPORT_MEM_USAGE_MSG = 33;
1833    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1834    static final int PERSIST_URI_GRANTS_MSG = 38;
1835    static final int REQUEST_ALL_PSS_MSG = 39;
1836    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1837    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1838    static final int FINISH_BOOTING_MSG = 45;
1839    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1840    static final int DISMISS_DIALOG_UI_MSG = 48;
1841    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1842    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1843    static final int DELETE_DUMPHEAP_MSG = 51;
1844    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1845    static final int REPORT_TIME_TRACKER_MSG = 54;
1846    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1847    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1848    static final int IDLE_UIDS_MSG = 58;
1849    static final int LOG_STACK_STATE = 60;
1850    static final int VR_MODE_CHANGE_MSG = 61;
1851    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1852    static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
1853    static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
1854    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1855    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1856    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1857    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1858    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1859
1860    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1861    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1862    static final int FIRST_COMPAT_MODE_MSG = 300;
1863    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1864
1865    static ServiceThread sKillThread = null;
1866    static KillHandler sKillHandler = null;
1867
1868    CompatModeDialog mCompatModeDialog;
1869    long mLastMemUsageReportTime = 0;
1870
1871    /**
1872     * Flag whether the current user is a "monkey", i.e. whether
1873     * the UI is driven by a UI automation tool.
1874     */
1875    private boolean mUserIsMonkey;
1876
1877    /** The dimensions of the thumbnails in the Recents UI. */
1878    int mThumbnailWidth;
1879    int mThumbnailHeight;
1880    float mFullscreenThumbnailScale;
1881
1882    final ServiceThread mHandlerThread;
1883    final MainHandler mHandler;
1884    final Handler mUiHandler;
1885    final ServiceThread mProcStartHandlerThread;
1886    final Handler mProcStartHandler;
1887
1888    final ActivityManagerConstants mConstants;
1889
1890    PackageManagerInternal mPackageManagerInt;
1891
1892    // VoiceInteraction session ID that changes for each new request except when
1893    // being called for multiwindow assist in a single session.
1894    private int mViSessionId = 1000;
1895
1896    final boolean mPermissionReviewRequired;
1897
1898    /**
1899     * Whether to force background check on all apps (for battery saver) or not.
1900     */
1901    boolean mForceBackgroundCheck;
1902
1903    private static String sTheRealBuildSerial = Build.UNKNOWN;
1904
1905    /**
1906     * Current global configuration information. Contains general settings for the entire system,
1907     * also corresponds to the merged configuration of the default display.
1908     */
1909    Configuration getGlobalConfiguration() {
1910        return mStackSupervisor.getConfiguration();
1911    }
1912
1913    final class KillHandler extends Handler {
1914        static final int KILL_PROCESS_GROUP_MSG = 4000;
1915
1916        public KillHandler(Looper looper) {
1917            super(looper, null, true);
1918        }
1919
1920        @Override
1921        public void handleMessage(Message msg) {
1922            switch (msg.what) {
1923                case KILL_PROCESS_GROUP_MSG:
1924                {
1925                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1926                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1927                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1928                }
1929                break;
1930
1931                default:
1932                    super.handleMessage(msg);
1933            }
1934        }
1935    }
1936
1937    final class UiHandler extends Handler {
1938        public UiHandler() {
1939            super(com.android.server.UiThread.get().getLooper(), null, true);
1940        }
1941
1942        @Override
1943        public void handleMessage(Message msg) {
1944            switch (msg.what) {
1945            case SHOW_ERROR_UI_MSG: {
1946                mAppErrors.handleShowAppErrorUi(msg);
1947                ensureBootCompleted();
1948            } break;
1949            case SHOW_NOT_RESPONDING_UI_MSG: {
1950                mAppErrors.handleShowAnrUi(msg);
1951                ensureBootCompleted();
1952            } break;
1953            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1954                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1955                synchronized (ActivityManagerService.this) {
1956                    ProcessRecord proc = (ProcessRecord) data.get("app");
1957                    if (proc == null) {
1958                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1959                        break;
1960                    }
1961                    if (proc.crashDialog != null) {
1962                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1963                        return;
1964                    }
1965                    AppErrorResult res = (AppErrorResult) data.get("result");
1966                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1967                        Dialog d = new StrictModeViolationDialog(mUiContext,
1968                                ActivityManagerService.this, res, proc);
1969                        d.show();
1970                        proc.crashDialog = d;
1971                    } else {
1972                        // The device is asleep, so just pretend that the user
1973                        // saw a crash dialog and hit "force quit".
1974                        res.set(0);
1975                    }
1976                }
1977                ensureBootCompleted();
1978            } break;
1979            case SHOW_FACTORY_ERROR_UI_MSG: {
1980                Dialog d = new FactoryErrorDialog(
1981                        mUiContext, msg.getData().getCharSequence("msg"));
1982                d.show();
1983                ensureBootCompleted();
1984            } break;
1985            case WAIT_FOR_DEBUGGER_UI_MSG: {
1986                synchronized (ActivityManagerService.this) {
1987                    ProcessRecord app = (ProcessRecord)msg.obj;
1988                    if (msg.arg1 != 0) {
1989                        if (!app.waitedForDebugger) {
1990                            Dialog d = new AppWaitingForDebuggerDialog(
1991                                    ActivityManagerService.this,
1992                                    mUiContext, app);
1993                            app.waitDialog = d;
1994                            app.waitedForDebugger = true;
1995                            d.show();
1996                        }
1997                    } else {
1998                        if (app.waitDialog != null) {
1999                            app.waitDialog.dismiss();
2000                            app.waitDialog = null;
2001                        }
2002                    }
2003                }
2004            } break;
2005            case SHOW_UID_ERROR_UI_MSG: {
2006                if (mShowDialogs) {
2007                    AlertDialog d = new BaseErrorDialog(mUiContext);
2008                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2009                    d.setCancelable(false);
2010                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2011                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
2012                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2013                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2014                    d.show();
2015                }
2016            } break;
2017            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
2018                if (mShowDialogs) {
2019                    AlertDialog d = new BaseErrorDialog(mUiContext);
2020                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2021                    d.setCancelable(false);
2022                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2023                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
2024                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2025                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2026                    d.show();
2027                }
2028            } break;
2029            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
2030                synchronized (ActivityManagerService.this) {
2031                    ActivityRecord ar = (ActivityRecord) msg.obj;
2032                    if (mCompatModeDialog != null) {
2033                        if (mCompatModeDialog.mAppInfo.packageName.equals(
2034                                ar.info.applicationInfo.packageName)) {
2035                            return;
2036                        }
2037                        mCompatModeDialog.dismiss();
2038                        mCompatModeDialog = null;
2039                    }
2040                    if (ar != null && false) {
2041                        if (mCompatModePackages.getPackageAskCompatModeLocked(
2042                                ar.packageName)) {
2043                            int mode = mCompatModePackages.computeCompatModeLocked(
2044                                    ar.info.applicationInfo);
2045                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
2046                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
2047                                mCompatModeDialog = new CompatModeDialog(
2048                                        ActivityManagerService.this, mUiContext,
2049                                        ar.info.applicationInfo);
2050                                mCompatModeDialog.show();
2051                            }
2052                        }
2053                    }
2054                }
2055                break;
2056            }
2057            case DISMISS_DIALOG_UI_MSG: {
2058                final Dialog d = (Dialog) msg.obj;
2059                d.dismiss();
2060                break;
2061            }
2062            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
2063                dispatchProcessesChanged();
2064                break;
2065            }
2066            case DISPATCH_PROCESS_DIED_UI_MSG: {
2067                final int pid = msg.arg1;
2068                final int uid = msg.arg2;
2069                dispatchProcessDied(pid, uid);
2070                break;
2071            }
2072            case DISPATCH_UIDS_CHANGED_UI_MSG: {
2073                dispatchUidsChanged();
2074            } break;
2075            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
2076                dispatchOomAdjObserver((String)msg.obj);
2077            } break;
2078            case PUSH_TEMP_WHITELIST_UI_MSG: {
2079                pushTempWhitelist();
2080            } break;
2081            }
2082        }
2083    }
2084
2085    final class MainHandler extends Handler {
2086        public MainHandler(Looper looper) {
2087            super(looper, null, true);
2088        }
2089
2090        @Override
2091        public void handleMessage(Message msg) {
2092            switch (msg.what) {
2093            case UPDATE_CONFIGURATION_MSG: {
2094                final ContentResolver resolver = mContext.getContentResolver();
2095                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
2096                        msg.arg1);
2097            } break;
2098            case GC_BACKGROUND_PROCESSES_MSG: {
2099                synchronized (ActivityManagerService.this) {
2100                    performAppGcsIfAppropriateLocked();
2101                }
2102            } break;
2103            case SERVICE_TIMEOUT_MSG: {
2104                mServices.serviceTimeout((ProcessRecord)msg.obj);
2105            } break;
2106            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
2107                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
2108            } break;
2109            case SERVICE_FOREGROUND_CRASH_MSG: {
2110                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
2111            } break;
2112            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
2113                RemoteCallbackList<IResultReceiver> callbacks
2114                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
2115                int N = callbacks.beginBroadcast();
2116                for (int i = 0; i < N; i++) {
2117                    try {
2118                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2119                    } catch (RemoteException e) {
2120                    }
2121                }
2122                callbacks.finishBroadcast();
2123            } break;
2124            case UPDATE_TIME_ZONE: {
2125                synchronized (ActivityManagerService.this) {
2126                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2127                        ProcessRecord r = mLruProcesses.get(i);
2128                        if (r.thread != null) {
2129                            try {
2130                                r.thread.updateTimeZone();
2131                            } catch (RemoteException ex) {
2132                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2133                            }
2134                        }
2135                    }
2136                }
2137            } break;
2138            case CLEAR_DNS_CACHE_MSG: {
2139                synchronized (ActivityManagerService.this) {
2140                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2141                        ProcessRecord r = mLruProcesses.get(i);
2142                        if (r.thread != null) {
2143                            try {
2144                                r.thread.clearDnsCache();
2145                            } catch (RemoteException ex) {
2146                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2147                            }
2148                        }
2149                    }
2150                }
2151            } break;
2152            case UPDATE_HTTP_PROXY_MSG: {
2153                ProxyInfo proxy = (ProxyInfo)msg.obj;
2154                String host = "";
2155                String port = "";
2156                String exclList = "";
2157                Uri pacFileUrl = Uri.EMPTY;
2158                if (proxy != null) {
2159                    host = proxy.getHost();
2160                    port = Integer.toString(proxy.getPort());
2161                    exclList = proxy.getExclusionListAsString();
2162                    pacFileUrl = proxy.getPacFileUrl();
2163                }
2164                synchronized (ActivityManagerService.this) {
2165                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2166                        ProcessRecord r = mLruProcesses.get(i);
2167                        // Don't dispatch to isolated processes as they can't access
2168                        // ConnectivityManager and don't have network privileges anyway.
2169                        if (r.thread != null && !r.isolated) {
2170                            try {
2171                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2172                            } catch (RemoteException ex) {
2173                                Slog.w(TAG, "Failed to update http proxy for: " +
2174                                        r.info.processName);
2175                            }
2176                        }
2177                    }
2178                }
2179            } break;
2180            case PROC_START_TIMEOUT_MSG: {
2181                ProcessRecord app = (ProcessRecord)msg.obj;
2182                synchronized (ActivityManagerService.this) {
2183                    processStartTimedOutLocked(app);
2184                }
2185            } break;
2186            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2187                ProcessRecord app = (ProcessRecord)msg.obj;
2188                synchronized (ActivityManagerService.this) {
2189                    processContentProviderPublishTimedOutLocked(app);
2190                }
2191            } break;
2192            case KILL_APPLICATION_MSG: {
2193                synchronized (ActivityManagerService.this) {
2194                    final int appId = msg.arg1;
2195                    final int userId = msg.arg2;
2196                    Bundle bundle = (Bundle)msg.obj;
2197                    String pkg = bundle.getString("pkg");
2198                    String reason = bundle.getString("reason");
2199                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2200                            false, userId, reason);
2201                }
2202            } break;
2203            case FINALIZE_PENDING_INTENT_MSG: {
2204                ((PendingIntentRecord)msg.obj).completeFinalize();
2205            } break;
2206            case POST_HEAVY_NOTIFICATION_MSG: {
2207                INotificationManager inm = NotificationManager.getService();
2208                if (inm == null) {
2209                    return;
2210                }
2211
2212                ActivityRecord root = (ActivityRecord)msg.obj;
2213                ProcessRecord process = root.app;
2214                if (process == null) {
2215                    return;
2216                }
2217
2218                try {
2219                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2220                    String text = mContext.getString(R.string.heavy_weight_notification,
2221                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2222                    Notification notification =
2223                            new Notification.Builder(context,
2224                                    SystemNotificationChannels.HEAVY_WEIGHT_APP)
2225                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2226                            .setWhen(0)
2227                            .setOngoing(true)
2228                            .setTicker(text)
2229                            .setColor(mContext.getColor(
2230                                    com.android.internal.R.color.system_notification_accent_color))
2231                            .setContentTitle(text)
2232                            .setContentText(
2233                                    mContext.getText(R.string.heavy_weight_notification_detail))
2234                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2235                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2236                                    new UserHandle(root.userId)))
2237                            .build();
2238                    try {
2239                        inm.enqueueNotificationWithTag("android", "android", null,
2240                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2241                                notification, root.userId);
2242                    } catch (RuntimeException e) {
2243                        Slog.w(ActivityManagerService.TAG,
2244                                "Error showing notification for heavy-weight app", e);
2245                    } catch (RemoteException e) {
2246                    }
2247                } catch (NameNotFoundException e) {
2248                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2249                }
2250            } break;
2251            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2252                INotificationManager inm = NotificationManager.getService();
2253                if (inm == null) {
2254                    return;
2255                }
2256                try {
2257                    inm.cancelNotificationWithTag("android", null,
2258                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2259                } catch (RuntimeException e) {
2260                    Slog.w(ActivityManagerService.TAG,
2261                            "Error canceling notification for service", e);
2262                } catch (RemoteException e) {
2263                }
2264            } break;
2265            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2266                synchronized (ActivityManagerService.this) {
2267                    checkExcessivePowerUsageLocked();
2268                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2269                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2270                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2271                }
2272            } break;
2273            case REPORT_MEM_USAGE_MSG: {
2274                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2275                Thread thread = new Thread() {
2276                    @Override public void run() {
2277                        reportMemUsage(memInfos);
2278                    }
2279                };
2280                thread.start();
2281                break;
2282            }
2283            case IMMERSIVE_MODE_LOCK_MSG: {
2284                final boolean nextState = (msg.arg1 != 0);
2285                if (mUpdateLock.isHeld() != nextState) {
2286                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2287                            "Applying new update lock state '" + nextState
2288                            + "' for " + (ActivityRecord)msg.obj);
2289                    if (nextState) {
2290                        mUpdateLock.acquire();
2291                    } else {
2292                        mUpdateLock.release();
2293                    }
2294                }
2295                break;
2296            }
2297            case PERSIST_URI_GRANTS_MSG: {
2298                writeGrantedUriPermissions();
2299                break;
2300            }
2301            case REQUEST_ALL_PSS_MSG: {
2302                synchronized (ActivityManagerService.this) {
2303                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2304                }
2305                break;
2306            }
2307            case UPDATE_TIME_PREFERENCE_MSG: {
2308                // The user's time format preference might have changed.
2309                // For convenience we re-use the Intent extra values.
2310                synchronized (ActivityManagerService.this) {
2311                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2312                        ProcessRecord r = mLruProcesses.get(i);
2313                        if (r.thread != null) {
2314                            try {
2315                                r.thread.updateTimePrefs(msg.arg1);
2316                            } catch (RemoteException ex) {
2317                                Slog.w(TAG, "Failed to update preferences for: "
2318                                        + r.info.processName);
2319                            }
2320                        }
2321                    }
2322                }
2323                break;
2324            }
2325            case ENTER_ANIMATION_COMPLETE_MSG: {
2326                synchronized (ActivityManagerService.this) {
2327                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2328                    if (r != null && r.app != null && r.app.thread != null) {
2329                        try {
2330                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2331                        } catch (RemoteException e) {
2332                        }
2333                    }
2334                }
2335                break;
2336            }
2337            case FINISH_BOOTING_MSG: {
2338                if (msg.arg1 != 0) {
2339                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2340                    finishBooting();
2341                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2342                }
2343                if (msg.arg2 != 0) {
2344                    enableScreenAfterBoot();
2345                }
2346                break;
2347            }
2348            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2349                try {
2350                    Locale l = (Locale) msg.obj;
2351                    IBinder service = ServiceManager.getService("mount");
2352                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2353                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2354                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2355                } catch (RemoteException e) {
2356                    Log.e(TAG, "Error storing locale for decryption UI", e);
2357                }
2358                break;
2359            }
2360            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2361                final int uid = msg.arg1;
2362                final byte[] firstPacket = (byte[]) msg.obj;
2363
2364                synchronized (mPidsSelfLocked) {
2365                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2366                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2367                        if (p.uid == uid) {
2368                            try {
2369                                p.thread.notifyCleartextNetwork(firstPacket);
2370                            } catch (RemoteException ignored) {
2371                            }
2372                        }
2373                    }
2374                }
2375                break;
2376            }
2377            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2378                final String procName;
2379                final int uid;
2380                final long memLimit;
2381                final String reportPackage;
2382                synchronized (ActivityManagerService.this) {
2383                    procName = mMemWatchDumpProcName;
2384                    uid = mMemWatchDumpUid;
2385                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2386                    if (val == null) {
2387                        val = mMemWatchProcesses.get(procName, 0);
2388                    }
2389                    if (val != null) {
2390                        memLimit = val.first;
2391                        reportPackage = val.second;
2392                    } else {
2393                        memLimit = 0;
2394                        reportPackage = null;
2395                    }
2396                }
2397                if (procName == null) {
2398                    return;
2399                }
2400
2401                if (DEBUG_PSS) Slog.d(TAG_PSS,
2402                        "Showing dump heap notification from " + procName + "/" + uid);
2403
2404                INotificationManager inm = NotificationManager.getService();
2405                if (inm == null) {
2406                    return;
2407                }
2408
2409                String text = mContext.getString(R.string.dump_heap_notification, procName);
2410
2411
2412                Intent deleteIntent = new Intent();
2413                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2414                Intent intent = new Intent();
2415                intent.setClassName("android", DumpHeapActivity.class.getName());
2416                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2417                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2418                if (reportPackage != null) {
2419                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2420                }
2421                int userId = UserHandle.getUserId(uid);
2422                Notification notification =
2423                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2424                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2425                        .setWhen(0)
2426                        .setOngoing(true)
2427                        .setAutoCancel(true)
2428                        .setTicker(text)
2429                        .setColor(mContext.getColor(
2430                                com.android.internal.R.color.system_notification_accent_color))
2431                        .setContentTitle(text)
2432                        .setContentText(
2433                                mContext.getText(R.string.dump_heap_notification_detail))
2434                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2435                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2436                                new UserHandle(userId)))
2437                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2438                                deleteIntent, 0, UserHandle.SYSTEM))
2439                        .build();
2440
2441                try {
2442                    inm.enqueueNotificationWithTag("android", "android", null,
2443                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2444                            notification, userId);
2445                } catch (RuntimeException e) {
2446                    Slog.w(ActivityManagerService.TAG,
2447                            "Error showing notification for dump heap", e);
2448                } catch (RemoteException e) {
2449                }
2450            } break;
2451            case DELETE_DUMPHEAP_MSG: {
2452                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2453                        null, DumpHeapActivity.JAVA_URI,
2454                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2455                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2456                        UserHandle.myUserId());
2457                synchronized (ActivityManagerService.this) {
2458                    mMemWatchDumpFile = null;
2459                    mMemWatchDumpProcName = null;
2460                    mMemWatchDumpPid = -1;
2461                    mMemWatchDumpUid = -1;
2462                }
2463            } break;
2464            case REPORT_TIME_TRACKER_MSG: {
2465                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2466                tracker.deliverResult(mContext);
2467            } break;
2468            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2469                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2470                try {
2471                    connection.shutdown();
2472                } catch (RemoteException e) {
2473                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2474                }
2475                // Only a UiAutomation can set this flag and now that
2476                // it is finished we make sure it is reset to its default.
2477                mUserIsMonkey = false;
2478            } break;
2479            case IDLE_UIDS_MSG: {
2480                idleUids();
2481            } break;
2482            case VR_MODE_CHANGE_MSG: {
2483                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2484                    return;
2485                }
2486                synchronized (ActivityManagerService.this) {
2487                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2488                    mWindowManager.disableNonVrUi(disableNonVrUi);
2489                    if (disableNonVrUi) {
2490                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2491                        // then remove the pinned stack.
2492                        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2493                    }
2494                }
2495            } break;
2496            case DISPATCH_SCREEN_AWAKE_MSG: {
2497                final boolean isAwake = msg.arg1 != 0;
2498                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2499                    mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2500                }
2501            } break;
2502            case DISPATCH_SCREEN_KEYGUARD_MSG: {
2503                final boolean isShowing = msg.arg1 != 0;
2504                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2505                    mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2506                }
2507            } break;
2508            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2509                synchronized (ActivityManagerService.this) {
2510                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2511                        ProcessRecord r = mLruProcesses.get(i);
2512                        if (r.thread != null) {
2513                            try {
2514                                r.thread.handleTrustStorageUpdate();
2515                            } catch (RemoteException ex) {
2516                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2517                                        r.info.processName);
2518                            }
2519                        }
2520                    }
2521                }
2522            } break;
2523            }
2524        }
2525    };
2526
2527    static final int COLLECT_PSS_BG_MSG = 1;
2528
2529    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2530        @Override
2531        public void handleMessage(Message msg) {
2532            switch (msg.what) {
2533            case COLLECT_PSS_BG_MSG: {
2534                long start = SystemClock.uptimeMillis();
2535                MemInfoReader memInfo = null;
2536                synchronized (ActivityManagerService.this) {
2537                    if (mFullPssPending) {
2538                        mFullPssPending = false;
2539                        memInfo = new MemInfoReader();
2540                    }
2541                }
2542                if (memInfo != null) {
2543                    updateCpuStatsNow();
2544                    long nativeTotalPss = 0;
2545                    final List<ProcessCpuTracker.Stats> stats;
2546                    synchronized (mProcessCpuTracker) {
2547                        stats = mProcessCpuTracker.getStats( (st)-> {
2548                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2549                        });
2550                    }
2551                    final int N = stats.size();
2552                    for (int j = 0; j < N; j++) {
2553                        synchronized (mPidsSelfLocked) {
2554                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2555                                // This is one of our own processes; skip it.
2556                                continue;
2557                            }
2558                        }
2559                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2560                    }
2561                    memInfo.readMemInfo();
2562                    synchronized (ActivityManagerService.this) {
2563                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2564                                + (SystemClock.uptimeMillis()-start) + "ms");
2565                        final long cachedKb = memInfo.getCachedSizeKb();
2566                        final long freeKb = memInfo.getFreeSizeKb();
2567                        final long zramKb = memInfo.getZramTotalSizeKb();
2568                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2569                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2570                                kernelKb*1024, nativeTotalPss*1024);
2571                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2572                                nativeTotalPss);
2573                    }
2574                }
2575
2576                int num = 0;
2577                long[] tmp = new long[3];
2578                do {
2579                    ProcessRecord proc;
2580                    int procState;
2581                    int statType;
2582                    int pid;
2583                    long lastPssTime;
2584                    synchronized (ActivityManagerService.this) {
2585                        if (mPendingPssProcesses.size() <= 0) {
2586                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2587                                    "Collected pss of " + num + " processes in "
2588                                    + (SystemClock.uptimeMillis() - start) + "ms");
2589                            mPendingPssProcesses.clear();
2590                            return;
2591                        }
2592                        proc = mPendingPssProcesses.remove(0);
2593                        procState = proc.pssProcState;
2594                        statType = proc.pssStatType;
2595                        lastPssTime = proc.lastPssTime;
2596                        if (proc.thread != null && procState == proc.setProcState
2597                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2598                                        < SystemClock.uptimeMillis()) {
2599                            pid = proc.pid;
2600                        } else {
2601                            proc = null;
2602                            pid = 0;
2603                        }
2604                    }
2605                    if (proc != null) {
2606                        long startTime = SystemClock.currentThreadTimeMillis();
2607                        long pss = Debug.getPss(pid, tmp, null);
2608                        long endTime = SystemClock.currentThreadTimeMillis();
2609                        synchronized (ActivityManagerService.this) {
2610                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2611                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2612                                num++;
2613                                ProcessList.commitNextPssTime(proc.procStateMemTracker);
2614                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2],
2615                                        statType, endTime-startTime, SystemClock.uptimeMillis());
2616                            } else {
2617                                ProcessList.abortNextPssTime(proc.procStateMemTracker);
2618                                if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2619                                        ": " + (proc.thread == null ? "NO_THREAD " : "") +
2620                                        (proc.pid != pid ? "PID_CHANGED " : "") +
2621                                        " initState=" + procState + " curState=" +
2622                                        proc.setProcState + " " +
2623                                        (proc.lastPssTime != lastPssTime ? "TIME_CHANGED" : ""));
2624                            }
2625                        }
2626                    }
2627                } while (true);
2628            }
2629            }
2630        }
2631    };
2632
2633    public void setSystemProcess() {
2634        try {
2635            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
2636                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
2637            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2638            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
2639                    DUMP_FLAG_PRIORITY_HIGH);
2640            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2641            ServiceManager.addService("dbinfo", new DbBinder(this));
2642            if (MONITOR_CPU_USAGE) {
2643                ServiceManager.addService("cpuinfo", new CpuBinder(this),
2644                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
2645            }
2646            ServiceManager.addService("permission", new PermissionController(this));
2647            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2648
2649            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2650                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2651            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2652
2653            synchronized (this) {
2654                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2655                app.persistent = true;
2656                app.pid = MY_PID;
2657                app.maxAdj = ProcessList.SYSTEM_ADJ;
2658                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2659                synchronized (mPidsSelfLocked) {
2660                    mPidsSelfLocked.put(app.pid, app);
2661                }
2662                updateLruProcessLocked(app, false, null);
2663                updateOomAdjLocked();
2664            }
2665        } catch (PackageManager.NameNotFoundException e) {
2666            throw new RuntimeException(
2667                    "Unable to find android system package", e);
2668        }
2669    }
2670
2671    public void setWindowManager(WindowManagerService wm) {
2672        synchronized (this) {
2673            mWindowManager = wm;
2674            mStackSupervisor.setWindowManager(wm);
2675            mLockTaskController.setWindowManager(wm);
2676        }
2677    }
2678
2679    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2680        mUsageStatsService = usageStatsManager;
2681    }
2682
2683    public void startObservingNativeCrashes() {
2684        final NativeCrashListener ncl = new NativeCrashListener(this);
2685        ncl.start();
2686    }
2687
2688    public IAppOpsService getAppOpsService() {
2689        return mAppOpsService;
2690    }
2691
2692    static class MemBinder extends Binder {
2693        ActivityManagerService mActivityManagerService;
2694        private final PriorityDump.PriorityDumper mPriorityDumper =
2695                new PriorityDump.PriorityDumper() {
2696            @Override
2697            public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
2698                    boolean asProto) {
2699                dump(fd, pw, new String[] {"-a"}, asProto);
2700            }
2701
2702            @Override
2703            public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
2704                mActivityManagerService.dumpApplicationMemoryUsage(
2705                        fd, pw, "  ", args, false, null, asProto);
2706            }
2707        };
2708
2709        MemBinder(ActivityManagerService activityManagerService) {
2710            mActivityManagerService = activityManagerService;
2711        }
2712
2713        @Override
2714        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2715            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2716                    "meminfo", pw)) return;
2717            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2718        }
2719    }
2720
2721    static class GraphicsBinder extends Binder {
2722        ActivityManagerService mActivityManagerService;
2723        GraphicsBinder(ActivityManagerService activityManagerService) {
2724            mActivityManagerService = activityManagerService;
2725        }
2726
2727        @Override
2728        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2729            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2730                    "gfxinfo", pw)) return;
2731            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2732        }
2733    }
2734
2735    static class DbBinder extends Binder {
2736        ActivityManagerService mActivityManagerService;
2737        DbBinder(ActivityManagerService activityManagerService) {
2738            mActivityManagerService = activityManagerService;
2739        }
2740
2741        @Override
2742        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2743            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2744                    "dbinfo", pw)) return;
2745            mActivityManagerService.dumpDbInfo(fd, pw, args);
2746        }
2747    }
2748
2749    static class CpuBinder extends Binder {
2750        ActivityManagerService mActivityManagerService;
2751        private final PriorityDump.PriorityDumper mPriorityDumper =
2752                new PriorityDump.PriorityDumper() {
2753            @Override
2754            public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
2755                    boolean asProto) {
2756                if (asProto) return;
2757                if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2758                        "cpuinfo", pw)) return;
2759                synchronized (mActivityManagerService.mProcessCpuTracker) {
2760                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2761                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2762                            SystemClock.uptimeMillis()));
2763                }
2764            }
2765        };
2766
2767        CpuBinder(ActivityManagerService activityManagerService) {
2768            mActivityManagerService = activityManagerService;
2769        }
2770
2771        @Override
2772        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2773            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2774        }
2775    }
2776
2777    public static final class Lifecycle extends SystemService {
2778        private final ActivityManagerService mService;
2779
2780        public Lifecycle(Context context) {
2781            super(context);
2782            mService = new ActivityManagerService(context);
2783        }
2784
2785        @Override
2786        public void onStart() {
2787            mService.start();
2788        }
2789
2790        @Override
2791        public void onBootPhase(int phase) {
2792            if (phase == PHASE_SYSTEM_SERVICES_READY) {
2793                mService.mBatteryStatsService.systemServicesReady();
2794            }
2795        }
2796
2797        @Override
2798        public void onCleanupUser(int userId) {
2799            mService.mBatteryStatsService.onCleanupUser(userId);
2800        }
2801
2802        public ActivityManagerService getService() {
2803            return mService;
2804        }
2805    }
2806
2807    @VisibleForTesting
2808    public ActivityManagerService(Injector injector) {
2809        mInjector = injector;
2810        mContext = mInjector.getContext();
2811        mUiContext = null;
2812        GL_ES_VERSION = 0;
2813        mActivityStartController = null;
2814        mAppErrors = null;
2815        mAppWarnings = null;
2816        mAppOpsService = mInjector.getAppOpsService(null, null);
2817        mBatteryStatsService = null;
2818        mCompatModePackages = null;
2819        mConstants = null;
2820        mGrantFile = null;
2821        mHandler = null;
2822        mHandlerThread = null;
2823        mIntentFirewall = null;
2824        mKeyguardController = null;
2825        mPermissionReviewRequired = false;
2826        mProcessCpuThread = null;
2827        mProcessStats = null;
2828        mProviderMap = null;
2829        mRecentTasks = null;
2830        mServices = null;
2831        mStackSupervisor = null;
2832        mSystemThread = null;
2833        mTaskChangeNotificationController = null;
2834        mUiHandler = injector.getUiHandler(null);
2835        mUserController = null;
2836        mVrController = null;
2837        mLockTaskController = null;
2838        mLifecycleManager = null;
2839        mProcStartHandlerThread = null;
2840        mProcStartHandler = null;
2841    }
2842
2843    // Note: This method is invoked on the main thread but may need to attach various
2844    // handlers to other threads.  So take care to be explicit about the looper.
2845    public ActivityManagerService(Context systemContext) {
2846        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2847        mInjector = new Injector();
2848        mContext = systemContext;
2849
2850        mFactoryTest = FactoryTest.getMode();
2851        mSystemThread = ActivityThread.currentActivityThread();
2852        mUiContext = mSystemThread.getSystemUiContext();
2853
2854        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2855
2856        mPermissionReviewRequired = mContext.getResources().getBoolean(
2857                com.android.internal.R.bool.config_permissionReviewRequired);
2858
2859        mHandlerThread = new ServiceThread(TAG,
2860                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2861        mHandlerThread.start();
2862        mHandler = new MainHandler(mHandlerThread.getLooper());
2863        mUiHandler = mInjector.getUiHandler(this);
2864
2865        mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
2866                THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
2867        mProcStartHandlerThread.start();
2868        mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
2869
2870        mConstants = new ActivityManagerConstants(this, mHandler);
2871
2872        /* static; one-time init here */
2873        if (sKillHandler == null) {
2874            sKillThread = new ServiceThread(TAG + ":kill",
2875                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2876            sKillThread.start();
2877            sKillHandler = new KillHandler(sKillThread.getLooper());
2878        }
2879
2880        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2881                "foreground", BROADCAST_FG_TIMEOUT, false);
2882        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2883                "background", BROADCAST_BG_TIMEOUT, true);
2884        mBroadcastQueues[0] = mFgBroadcastQueue;
2885        mBroadcastQueues[1] = mBgBroadcastQueue;
2886
2887        mServices = new ActiveServices(this);
2888        mProviderMap = new ProviderMap(this);
2889        mAppErrors = new AppErrors(mUiContext, this);
2890
2891        File dataDir = Environment.getDataDirectory();
2892        File systemDir = new File(dataDir, "system");
2893        systemDir.mkdirs();
2894
2895        mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
2896
2897        // TODO: Move creation of battery stats service outside of activity manager service.
2898        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2899        mBatteryStatsService.getActiveStatistics().readLocked();
2900        mBatteryStatsService.scheduleWriteToDisk();
2901        mOnBattery = DEBUG_POWER ? true
2902                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2903        mBatteryStatsService.getActiveStatistics().setCallback(this);
2904
2905        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2906
2907        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2908        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2909                new IAppOpsCallback.Stub() {
2910                    @Override public void opChanged(int op, int uid, String packageName) {
2911                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2912                            if (mAppOpsService.checkOperation(op, uid, packageName)
2913                                    != AppOpsManager.MODE_ALLOWED) {
2914                                runInBackgroundDisabled(uid);
2915                            }
2916                        }
2917                    }
2918                });
2919
2920        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
2921
2922        mUserController = new UserController(this);
2923
2924        mVrController = new VrController(this);
2925
2926        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2927            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2928
2929        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2930            mUseFifoUiScheduling = true;
2931        }
2932
2933        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2934        mTempConfig.setToDefaults();
2935        mTempConfig.setLocales(LocaleList.getDefault());
2936        mConfigurationSeq = mTempConfig.seq = 1;
2937        mStackSupervisor = createStackSupervisor();
2938        mStackSupervisor.onConfigurationChanged(mTempConfig);
2939        mKeyguardController = mStackSupervisor.getKeyguardController();
2940        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2941        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2942        mTaskChangeNotificationController =
2943                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2944        mActivityStartController = new ActivityStartController(this);
2945        mRecentTasks = createRecentTasks();
2946        mStackSupervisor.setRecentTasks(mRecentTasks);
2947        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
2948        mLifecycleManager = new ClientLifecycleManager();
2949
2950        mProcessCpuThread = new Thread("CpuTracker") {
2951            @Override
2952            public void run() {
2953                synchronized (mProcessCpuTracker) {
2954                    mProcessCpuInitLatch.countDown();
2955                    mProcessCpuTracker.init();
2956                }
2957                while (true) {
2958                    try {
2959                        try {
2960                            synchronized(this) {
2961                                final long now = SystemClock.uptimeMillis();
2962                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2963                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2964                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2965                                //        + ", write delay=" + nextWriteDelay);
2966                                if (nextWriteDelay < nextCpuDelay) {
2967                                    nextCpuDelay = nextWriteDelay;
2968                                }
2969                                if (nextCpuDelay > 0) {
2970                                    mProcessCpuMutexFree.set(true);
2971                                    this.wait(nextCpuDelay);
2972                                }
2973                            }
2974                        } catch (InterruptedException e) {
2975                        }
2976                        updateCpuStatsNow();
2977                    } catch (Exception e) {
2978                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2979                    }
2980                }
2981            }
2982        };
2983
2984        Watchdog.getInstance().addMonitor(this);
2985        Watchdog.getInstance().addThread(mHandler);
2986    }
2987
2988    protected ActivityStackSupervisor createStackSupervisor() {
2989        final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
2990        supervisor.initialize();
2991        return supervisor;
2992    }
2993
2994    protected RecentTasks createRecentTasks() {
2995        return new RecentTasks(this, mStackSupervisor);
2996    }
2997
2998    RecentTasks getRecentTasks() {
2999        return mRecentTasks;
3000    }
3001
3002    public void setSystemServiceManager(SystemServiceManager mgr) {
3003        mSystemServiceManager = mgr;
3004    }
3005
3006    public void setInstaller(Installer installer) {
3007        mInstaller = installer;
3008    }
3009
3010    private void start() {
3011        removeAllProcessGroups();
3012        mProcessCpuThread.start();
3013
3014        mBatteryStatsService.publish();
3015        mAppOpsService.publish(mContext);
3016        Slog.d("AppOps", "AppOpsService published");
3017        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
3018        // Wait for the synchronized block started in mProcessCpuThread,
3019        // so that any other acccess to mProcessCpuTracker from main thread
3020        // will be blocked during mProcessCpuTracker initialization.
3021        try {
3022            mProcessCpuInitLatch.await();
3023        } catch (InterruptedException e) {
3024            Slog.wtf(TAG, "Interrupted wait during start", e);
3025            Thread.currentThread().interrupt();
3026            throw new IllegalStateException("Interrupted wait during start");
3027        }
3028    }
3029
3030    void onUserStoppedLocked(int userId) {
3031        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
3032        mAllowAppSwitchUids.remove(userId);
3033    }
3034
3035    public void initPowerManagement() {
3036        mStackSupervisor.initPowerManagement();
3037        mBatteryStatsService.initPowerManagement();
3038        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
3039        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
3040        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
3041        mVoiceWakeLock.setReferenceCounted(false);
3042    }
3043
3044    private ArraySet<String> getBackgroundLaunchBroadcasts() {
3045        if (mBackgroundLaunchBroadcasts == null) {
3046            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
3047        }
3048        return mBackgroundLaunchBroadcasts;
3049    }
3050
3051    @Override
3052    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3053            throws RemoteException {
3054        if (code == SYSPROPS_TRANSACTION) {
3055            // We need to tell all apps about the system property change.
3056            ArrayList<IBinder> procs = new ArrayList<IBinder>();
3057            synchronized(this) {
3058                final int NP = mProcessNames.getMap().size();
3059                for (int ip=0; ip<NP; ip++) {
3060                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3061                    final int NA = apps.size();
3062                    for (int ia=0; ia<NA; ia++) {
3063                        ProcessRecord app = apps.valueAt(ia);
3064                        if (app.thread != null) {
3065                            procs.add(app.thread.asBinder());
3066                        }
3067                    }
3068                }
3069            }
3070
3071            int N = procs.size();
3072            for (int i=0; i<N; i++) {
3073                Parcel data2 = Parcel.obtain();
3074                try {
3075                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
3076                            Binder.FLAG_ONEWAY);
3077                } catch (RemoteException e) {
3078                }
3079                data2.recycle();
3080            }
3081        }
3082        try {
3083            return super.onTransact(code, data, reply, flags);
3084        } catch (RuntimeException e) {
3085            // The activity manager only throws certain exceptions intentionally, so let's
3086            // log all others.
3087            if (!(e instanceof SecurityException
3088                    || e instanceof IllegalArgumentException
3089                    || e instanceof IllegalStateException)) {
3090                Slog.wtf(TAG, "Activity Manager Crash."
3091                        + " UID:" + Binder.getCallingUid()
3092                        + " PID:" + Binder.getCallingPid()
3093                        + " TRANS:" + code, e);
3094            }
3095            throw e;
3096        }
3097    }
3098
3099    void updateCpuStats() {
3100        final long now = SystemClock.uptimeMillis();
3101        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3102            return;
3103        }
3104        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3105            synchronized (mProcessCpuThread) {
3106                mProcessCpuThread.notify();
3107            }
3108        }
3109    }
3110
3111    void updateCpuStatsNow() {
3112        synchronized (mProcessCpuTracker) {
3113            mProcessCpuMutexFree.set(false);
3114            final long now = SystemClock.uptimeMillis();
3115            boolean haveNewCpuStats = false;
3116
3117            if (MONITOR_CPU_USAGE &&
3118                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3119                mLastCpuTime.set(now);
3120                mProcessCpuTracker.update();
3121                if (mProcessCpuTracker.hasGoodLastStats()) {
3122                    haveNewCpuStats = true;
3123                    //Slog.i(TAG, mProcessCpu.printCurrentState());
3124                    //Slog.i(TAG, "Total CPU usage: "
3125                    //        + mProcessCpu.getTotalCpuPercent() + "%");
3126
3127                    // Slog the cpu usage if the property is set.
3128                    if ("true".equals(SystemProperties.get("events.cpu"))) {
3129                        int user = mProcessCpuTracker.getLastUserTime();
3130                        int system = mProcessCpuTracker.getLastSystemTime();
3131                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
3132                        int irq = mProcessCpuTracker.getLastIrqTime();
3133                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3134                        int idle = mProcessCpuTracker.getLastIdleTime();
3135
3136                        int total = user + system + iowait + irq + softIrq + idle;
3137                        if (total == 0) total = 1;
3138
3139                        EventLog.writeEvent(EventLogTags.CPU,
3140                                ((user+system+iowait+irq+softIrq) * 100) / total,
3141                                (user * 100) / total,
3142                                (system * 100) / total,
3143                                (iowait * 100) / total,
3144                                (irq * 100) / total,
3145                                (softIrq * 100) / total);
3146                    }
3147                }
3148            }
3149
3150            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3151            synchronized(bstats) {
3152                synchronized(mPidsSelfLocked) {
3153                    if (haveNewCpuStats) {
3154                        if (bstats.startAddingCpuLocked()) {
3155                            int totalUTime = 0;
3156                            int totalSTime = 0;
3157                            final int N = mProcessCpuTracker.countStats();
3158                            for (int i=0; i<N; i++) {
3159                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3160                                if (!st.working) {
3161                                    continue;
3162                                }
3163                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3164                                totalUTime += st.rel_utime;
3165                                totalSTime += st.rel_stime;
3166                                if (pr != null) {
3167                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3168                                    if (ps == null || !ps.isActive()) {
3169                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3170                                                pr.info.uid, pr.processName);
3171                                    }
3172                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3173                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3174                                    if (pr.lastCpuTime == 0) {
3175                                        pr.lastCpuTime = pr.curCpuTime;
3176                                    }
3177                                } else {
3178                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3179                                    if (ps == null || !ps.isActive()) {
3180                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3181                                                bstats.mapUid(st.uid), st.name);
3182                                    }
3183                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3184                                }
3185                            }
3186                            final int userTime = mProcessCpuTracker.getLastUserTime();
3187                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3188                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3189                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3190                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3191                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3192                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3193                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3194                        }
3195                    }
3196                }
3197
3198                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3199                    mLastWriteTime = now;
3200                    mBatteryStatsService.scheduleWriteToDisk();
3201                }
3202            }
3203        }
3204    }
3205
3206    @Override
3207    public void batteryNeedsCpuUpdate() {
3208        updateCpuStatsNow();
3209    }
3210
3211    @Override
3212    public void batteryPowerChanged(boolean onBattery) {
3213        // When plugging in, update the CPU stats first before changing
3214        // the plug state.
3215        updateCpuStatsNow();
3216        synchronized (this) {
3217            synchronized(mPidsSelfLocked) {
3218                mOnBattery = DEBUG_POWER ? true : onBattery;
3219            }
3220        }
3221    }
3222
3223    @Override
3224    public void batterySendBroadcast(Intent intent) {
3225        synchronized (this) {
3226            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3227                    OP_NONE, null, false, false,
3228                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3229        }
3230    }
3231
3232    /**
3233     * Initialize the application bind args. These are passed to each
3234     * process when the bindApplication() IPC is sent to the process. They're
3235     * lazily setup to make sure the services are running when they're asked for.
3236     */
3237    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3238        // Isolated processes won't get this optimization, so that we don't
3239        // violate the rules about which services they have access to.
3240        if (isolated) {
3241            if (mIsolatedAppBindArgs == null) {
3242                mIsolatedAppBindArgs = new HashMap<>();
3243                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3244            }
3245            return mIsolatedAppBindArgs;
3246        }
3247
3248        if (mAppBindArgs == null) {
3249            mAppBindArgs = new HashMap<>();
3250
3251            // Setup the application init args
3252            mAppBindArgs.put("package", ServiceManager.getService("package"));
3253            mAppBindArgs.put("window", ServiceManager.getService("window"));
3254            mAppBindArgs.put(Context.ALARM_SERVICE,
3255                    ServiceManager.getService(Context.ALARM_SERVICE));
3256        }
3257        return mAppBindArgs;
3258    }
3259
3260    /**
3261     * Update AMS states when an activity is resumed. This should only be called by
3262     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3263     */
3264    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3265        final TaskRecord task = r.getTask();
3266        if (task.isActivityTypeStandard()) {
3267            if (mCurAppTimeTracker != r.appTimeTracker) {
3268                // We are switching app tracking.  Complete the current one.
3269                if (mCurAppTimeTracker != null) {
3270                    mCurAppTimeTracker.stop();
3271                    mHandler.obtainMessage(
3272                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3273                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3274                    mCurAppTimeTracker = null;
3275                }
3276                if (r.appTimeTracker != null) {
3277                    mCurAppTimeTracker = r.appTimeTracker;
3278                    startTimeTrackingFocusedActivityLocked();
3279                }
3280            } else {
3281                startTimeTrackingFocusedActivityLocked();
3282            }
3283        } else {
3284            r.appTimeTracker = null;
3285        }
3286        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3287        // TODO: Probably not, because we don't want to resume voice on switching
3288        // back to this activity
3289        if (task.voiceInteractor != null) {
3290            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3291        } else {
3292            finishRunningVoiceLocked();
3293
3294            if (mLastResumedActivity != null) {
3295                final IVoiceInteractionSession session;
3296
3297                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3298                if (lastResumedActivityTask != null
3299                        && lastResumedActivityTask.voiceSession != null) {
3300                    session = lastResumedActivityTask.voiceSession;
3301                } else {
3302                    session = mLastResumedActivity.voiceSession;
3303                }
3304
3305                if (session != null) {
3306                    // We had been in a voice interaction session, but now focused has
3307                    // move to something different.  Just finish the session, we can't
3308                    // return to it and retain the proper state and synchronization with
3309                    // the voice interaction service.
3310                    finishVoiceTask(session);
3311                }
3312            }
3313        }
3314
3315        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3316            mUserController.sendForegroundProfileChanged(r.userId);
3317        }
3318        mLastResumedActivity = r;
3319
3320        mWindowManager.setFocusedApp(r.appToken, true);
3321
3322        applyUpdateLockStateLocked(r);
3323        applyUpdateVrModeLocked(r);
3324
3325        EventLogTags.writeAmSetResumedActivity(
3326                r == null ? -1 : r.userId,
3327                r == null ? "NULL" : r.shortComponentName,
3328                reason);
3329    }
3330
3331    @Override
3332    public void setFocusedStack(int stackId) {
3333        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3334        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3335        final long callingId = Binder.clearCallingIdentity();
3336        try {
3337            synchronized (this) {
3338                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3339                if (stack == null) {
3340                    Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3341                    return;
3342                }
3343                final ActivityRecord r = stack.topRunningActivityLocked();
3344                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3345                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3346                }
3347            }
3348        } finally {
3349            Binder.restoreCallingIdentity(callingId);
3350        }
3351    }
3352
3353    @Override
3354    public void setFocusedTask(int taskId) {
3355        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3356        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3357        final long callingId = Binder.clearCallingIdentity();
3358        try {
3359            synchronized (this) {
3360                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3361                if (task == null) {
3362                    return;
3363                }
3364                final ActivityRecord r = task.topRunningActivityLocked();
3365                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3366                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3367                }
3368            }
3369        } finally {
3370            Binder.restoreCallingIdentity(callingId);
3371        }
3372    }
3373
3374    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3375    @Override
3376    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3377        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3378                "registerTaskStackListener()");
3379        mTaskChangeNotificationController.registerTaskStackListener(listener);
3380    }
3381
3382    /**
3383     * Unregister a task stack listener so that it stops receiving callbacks.
3384     */
3385    @Override
3386    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3387        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3388                "unregisterTaskStackListener()");
3389         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3390     }
3391
3392    @Override
3393    public void notifyActivityDrawn(IBinder token) {
3394        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3395        synchronized (this) {
3396            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3397            if (r != null) {
3398                r.getStack().notifyActivityDrawnLocked(r);
3399            }
3400        }
3401    }
3402
3403    final void applyUpdateLockStateLocked(ActivityRecord r) {
3404        // Modifications to the UpdateLock state are done on our handler, outside
3405        // the activity manager's locks.  The new state is determined based on the
3406        // state *now* of the relevant activity record.  The object is passed to
3407        // the handler solely for logging detail, not to be consulted/modified.
3408        final boolean nextState = r != null && r.immersive;
3409        mHandler.sendMessage(
3410                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3411    }
3412
3413    final void applyUpdateVrModeLocked(ActivityRecord r) {
3414        // VR apps are expected to run in a main display. If an app is turning on VR for
3415        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3416        // fullscreen stack before enabling VR Mode.
3417        // TODO: The goal of this code is to keep the VR app on the main display. When the
3418        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3419        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3420        // option would be a better choice here.
3421        if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3422            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3423                    + " to main stack for VR");
3424            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3425                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3426            moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3427        }
3428        mHandler.sendMessage(
3429                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3430    }
3431
3432    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3433        Message msg = Message.obtain();
3434        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3435        msg.obj = r.getTask().askedCompatMode ? null : r;
3436        mUiHandler.sendMessage(msg);
3437    }
3438
3439    final AppWarnings getAppWarningsLocked() {
3440        return mAppWarnings;
3441    }
3442
3443    /**
3444     * Shows app warning dialogs, if necessary.
3445     *
3446     * @param r activity record for which the warnings may be displayed
3447     */
3448    final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3449        mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3450        mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3451        mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
3452    }
3453
3454    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3455            String what, Object obj, ProcessRecord srcApp) {
3456        app.lastActivityTime = now;
3457
3458        if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3459            // Don't want to touch dependent processes that are hosting activities.
3460            return index;
3461        }
3462
3463        int lrui = mLruProcesses.lastIndexOf(app);
3464        if (lrui < 0) {
3465            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3466                    + what + " " + obj + " from " + srcApp);
3467            return index;
3468        }
3469
3470        if (lrui >= index) {
3471            // Don't want to cause this to move dependent processes *back* in the
3472            // list as if they were less frequently used.
3473            return index;
3474        }
3475
3476        if (lrui >= mLruProcessActivityStart) {
3477            // Don't want to touch dependent processes that are hosting activities.
3478            return index;
3479        }
3480
3481        mLruProcesses.remove(lrui);
3482        if (index > 0) {
3483            index--;
3484        }
3485        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3486                + " in LRU list: " + app);
3487        mLruProcesses.add(index, app);
3488        return index;
3489    }
3490
3491    static void killProcessGroup(int uid, int pid) {
3492        if (sKillHandler != null) {
3493            sKillHandler.sendMessage(
3494                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3495        } else {
3496            Slog.w(TAG, "Asked to kill process group before system bringup!");
3497            Process.killProcessGroup(uid, pid);
3498        }
3499    }
3500
3501    final void removeLruProcessLocked(ProcessRecord app) {
3502        int lrui = mLruProcesses.lastIndexOf(app);
3503        if (lrui >= 0) {
3504            if (!app.killed) {
3505                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3506                if (app.pid > 0) {
3507                    killProcessQuiet(app.pid);
3508                    killProcessGroup(app.uid, app.pid);
3509                } else {
3510                    app.pendingStart = false;
3511                }
3512            }
3513            if (lrui <= mLruProcessActivityStart) {
3514                mLruProcessActivityStart--;
3515            }
3516            if (lrui <= mLruProcessServiceStart) {
3517                mLruProcessServiceStart--;
3518            }
3519            mLruProcesses.remove(lrui);
3520        }
3521    }
3522
3523    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3524            ProcessRecord client) {
3525        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3526                || app.treatLikeActivity || app.recentTasks.size() > 0;
3527        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3528        if (!activityChange && hasActivity) {
3529            // The process has activities, so we are only allowing activity-based adjustments
3530            // to move it.  It should be kept in the front of the list with other
3531            // processes that have activities, and we don't want those to change their
3532            // order except due to activity operations.
3533            return;
3534        }
3535
3536        mLruSeq++;
3537        final long now = SystemClock.uptimeMillis();
3538        app.lastActivityTime = now;
3539
3540        // First a quick reject: if the app is already at the position we will
3541        // put it, then there is nothing to do.
3542        if (hasActivity) {
3543            final int N = mLruProcesses.size();
3544            if (N > 0 && mLruProcesses.get(N-1) == app) {
3545                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3546                return;
3547            }
3548        } else {
3549            if (mLruProcessServiceStart > 0
3550                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3551                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3552                return;
3553            }
3554        }
3555
3556        int lrui = mLruProcesses.lastIndexOf(app);
3557
3558        if (app.persistent && lrui >= 0) {
3559            // We don't care about the position of persistent processes, as long as
3560            // they are in the list.
3561            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3562            return;
3563        }
3564
3565        /* In progress: compute new position first, so we can avoid doing work
3566           if the process is not actually going to move.  Not yet working.
3567        int addIndex;
3568        int nextIndex;
3569        boolean inActivity = false, inService = false;
3570        if (hasActivity) {
3571            // Process has activities, put it at the very tipsy-top.
3572            addIndex = mLruProcesses.size();
3573            nextIndex = mLruProcessServiceStart;
3574            inActivity = true;
3575        } else if (hasService) {
3576            // Process has services, put it at the top of the service list.
3577            addIndex = mLruProcessActivityStart;
3578            nextIndex = mLruProcessServiceStart;
3579            inActivity = true;
3580            inService = true;
3581        } else  {
3582            // Process not otherwise of interest, it goes to the top of the non-service area.
3583            addIndex = mLruProcessServiceStart;
3584            if (client != null) {
3585                int clientIndex = mLruProcesses.lastIndexOf(client);
3586                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3587                        + app);
3588                if (clientIndex >= 0 && addIndex > clientIndex) {
3589                    addIndex = clientIndex;
3590                }
3591            }
3592            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3593        }
3594
3595        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3596                + mLruProcessActivityStart + "): " + app);
3597        */
3598
3599        if (lrui >= 0) {
3600            if (lrui < mLruProcessActivityStart) {
3601                mLruProcessActivityStart--;
3602            }
3603            if (lrui < mLruProcessServiceStart) {
3604                mLruProcessServiceStart--;
3605            }
3606            /*
3607            if (addIndex > lrui) {
3608                addIndex--;
3609            }
3610            if (nextIndex > lrui) {
3611                nextIndex--;
3612            }
3613            */
3614            mLruProcesses.remove(lrui);
3615        }
3616
3617        /*
3618        mLruProcesses.add(addIndex, app);
3619        if (inActivity) {
3620            mLruProcessActivityStart++;
3621        }
3622        if (inService) {
3623            mLruProcessActivityStart++;
3624        }
3625        */
3626
3627        int nextIndex;
3628        if (hasActivity) {
3629            final int N = mLruProcesses.size();
3630            if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
3631                    && mLruProcessActivityStart < (N - 1)) {
3632                // Process doesn't have activities, but has clients with
3633                // activities...  move it up, but one below the top (the top
3634                // should always have a real activity).
3635                if (DEBUG_LRU) Slog.d(TAG_LRU,
3636                        "Adding to second-top of LRU activity list: " + app);
3637                mLruProcesses.add(N - 1, app);
3638                // To keep it from spamming the LRU list (by making a bunch of clients),
3639                // we will push down any other entries owned by the app.
3640                final int uid = app.info.uid;
3641                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3642                    ProcessRecord subProc = mLruProcesses.get(i);
3643                    if (subProc.info.uid == uid) {
3644                        // We want to push this one down the list.  If the process after
3645                        // it is for the same uid, however, don't do so, because we don't
3646                        // want them internally to be re-ordered.
3647                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3648                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3649                                    "Pushing uid " + uid + " swapping at " + i + ": "
3650                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3651                            ProcessRecord tmp = mLruProcesses.get(i);
3652                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3653                            mLruProcesses.set(i - 1, tmp);
3654                            i--;
3655                        }
3656                    } else {
3657                        // A gap, we can stop here.
3658                        break;
3659                    }
3660                }
3661            } else {
3662                // Process has activities, put it at the very tipsy-top.
3663                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3664                mLruProcesses.add(app);
3665            }
3666            nextIndex = mLruProcessServiceStart;
3667        } else if (hasService) {
3668            // Process has services, put it at the top of the service list.
3669            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3670            mLruProcesses.add(mLruProcessActivityStart, app);
3671            nextIndex = mLruProcessServiceStart;
3672            mLruProcessActivityStart++;
3673        } else  {
3674            // Process not otherwise of interest, it goes to the top of the non-service area.
3675            int index = mLruProcessServiceStart;
3676            if (client != null) {
3677                // If there is a client, don't allow the process to be moved up higher
3678                // in the list than that client.
3679                int clientIndex = mLruProcesses.lastIndexOf(client);
3680                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3681                        + " when updating " + app);
3682                if (clientIndex <= lrui) {
3683                    // Don't allow the client index restriction to push it down farther in the
3684                    // list than it already is.
3685                    clientIndex = lrui;
3686                }
3687                if (clientIndex >= 0 && index > clientIndex) {
3688                    index = clientIndex;
3689                }
3690            }
3691            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3692            mLruProcesses.add(index, app);
3693            nextIndex = index-1;
3694            mLruProcessActivityStart++;
3695            mLruProcessServiceStart++;
3696        }
3697
3698        // If the app is currently using a content provider or service,
3699        // bump those processes as well.
3700        for (int j=app.connections.size()-1; j>=0; j--) {
3701            ConnectionRecord cr = app.connections.valueAt(j);
3702            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3703                    && cr.binding.service.app != null
3704                    && cr.binding.service.app.lruSeq != mLruSeq
3705                    && !cr.binding.service.app.persistent) {
3706                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3707                        "service connection", cr, app);
3708            }
3709        }
3710        for (int j=app.conProviders.size()-1; j>=0; j--) {
3711            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3712            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3713                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3714                        "provider reference", cpr, app);
3715            }
3716        }
3717    }
3718
3719    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3720        if (uid == SYSTEM_UID) {
3721            // The system gets to run in any process.  If there are multiple
3722            // processes with the same uid, just pick the first (this
3723            // should never happen).
3724            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3725            if (procs == null) return null;
3726            final int procCount = procs.size();
3727            for (int i = 0; i < procCount; i++) {
3728                final int procUid = procs.keyAt(i);
3729                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3730                    // Don't use an app process or different user process for system component.
3731                    continue;
3732                }
3733                return procs.valueAt(i);
3734            }
3735        }
3736        ProcessRecord proc = mProcessNames.get(processName, uid);
3737        if (false && proc != null && !keepIfLarge
3738                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3739                && proc.lastCachedPss >= 4000) {
3740            // Turn this condition on to cause killing to happen regularly, for testing.
3741            if (proc.baseProcessTracker != null) {
3742                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3743            }
3744            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3745        } else if (proc != null && !keepIfLarge
3746                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3747                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3748            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3749            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3750                if (proc.baseProcessTracker != null) {
3751                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3752                }
3753                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3754            }
3755        }
3756        return proc;
3757    }
3758
3759    void notifyPackageUse(String packageName, int reason) {
3760        synchronized(this) {
3761            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3762        }
3763    }
3764
3765    boolean isNextTransitionForward() {
3766        int transit = mWindowManager.getPendingAppTransition();
3767        return transit == TRANSIT_ACTIVITY_OPEN
3768                || transit == TRANSIT_TASK_OPEN
3769                || transit == TRANSIT_TASK_TO_FRONT;
3770    }
3771
3772    boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3773            String processName, String abiOverride, int uid, Runnable crashHandler) {
3774        synchronized(this) {
3775            ApplicationInfo info = new ApplicationInfo();
3776            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3777            // For isolated processes, the former contains the parent's uid and the latter the
3778            // actual uid of the isolated process.
3779            // In the special case introduced by this method (which is, starting an isolated
3780            // process directly from the SystemServer without an actual parent app process) the
3781            // closest thing to a parent's uid is SYSTEM_UID.
3782            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3783            // the |isolated| logic in the ProcessRecord constructor.
3784            info.uid = SYSTEM_UID;
3785            info.processName = processName;
3786            info.className = entryPoint;
3787            info.packageName = "android";
3788            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3789            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3790                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3791                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3792                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3793                    crashHandler);
3794            return proc != null;
3795        }
3796    }
3797
3798    final ProcessRecord startProcessLocked(String processName,
3799            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3800            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3801            boolean isolated, boolean keepIfLarge) {
3802        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3803                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3804                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3805                null /* crashHandler */);
3806    }
3807
3808    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3809            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3810            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3811            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3812        long startTime = SystemClock.elapsedRealtime();
3813        ProcessRecord app;
3814        if (!isolated) {
3815            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3816            checkTime(startTime, "startProcess: after getProcessRecord");
3817
3818            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3819                // If we are in the background, then check to see if this process
3820                // is bad.  If so, we will just silently fail.
3821                if (mAppErrors.isBadProcessLocked(info)) {
3822                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3823                            + "/" + info.processName);
3824                    return null;
3825                }
3826            } else {
3827                // When the user is explicitly starting a process, then clear its
3828                // crash count so that we won't make it bad until they see at
3829                // least one crash dialog again, and make the process good again
3830                // if it had been bad.
3831                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3832                        + "/" + info.processName);
3833                mAppErrors.resetProcessCrashTimeLocked(info);
3834                if (mAppErrors.isBadProcessLocked(info)) {
3835                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3836                            UserHandle.getUserId(info.uid), info.uid,
3837                            info.processName);
3838                    mAppErrors.clearBadProcessLocked(info);
3839                    if (app != null) {
3840                        app.bad = false;
3841                    }
3842                }
3843            }
3844        } else {
3845            // If this is an isolated process, it can't re-use an existing process.
3846            app = null;
3847        }
3848
3849        // We don't have to do anything more if:
3850        // (1) There is an existing application record; and
3851        // (2) The caller doesn't think it is dead, OR there is no thread
3852        //     object attached to it so we know it couldn't have crashed; and
3853        // (3) There is a pid assigned to it, so it is either starting or
3854        //     already running.
3855        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3856                + " app=" + app + " knownToBeDead=" + knownToBeDead
3857                + " thread=" + (app != null ? app.thread : null)
3858                + " pid=" + (app != null ? app.pid : -1));
3859        if (app != null && app.pid > 0) {
3860            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3861                // We already have the app running, or are waiting for it to
3862                // come up (we have a pid but not yet its thread), so keep it.
3863                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3864                // If this is a new package in the process, add the package to the list
3865                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3866                checkTime(startTime, "startProcess: done, added package to proc");
3867                return app;
3868            }
3869
3870            // An application record is attached to a previous process,
3871            // clean it up now.
3872            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3873            checkTime(startTime, "startProcess: bad proc running, killing");
3874            killProcessGroup(app.uid, app.pid);
3875            handleAppDiedLocked(app, true, true);
3876            checkTime(startTime, "startProcess: done killing old proc");
3877        }
3878
3879        String hostingNameStr = hostingName != null
3880                ? hostingName.flattenToShortString() : null;
3881
3882        if (app == null) {
3883            checkTime(startTime, "startProcess: creating new process record");
3884            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3885            if (app == null) {
3886                Slog.w(TAG, "Failed making new process record for "
3887                        + processName + "/" + info.uid + " isolated=" + isolated);
3888                return null;
3889            }
3890            app.crashHandler = crashHandler;
3891            app.isolatedEntryPoint = entryPoint;
3892            app.isolatedEntryPointArgs = entryPointArgs;
3893            checkTime(startTime, "startProcess: done creating new process record");
3894        } else {
3895            // If this is a new package in the process, add the package to the list
3896            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3897            checkTime(startTime, "startProcess: added package to existing proc");
3898        }
3899
3900        // If the system is not ready yet, then hold off on starting this
3901        // process until it is.
3902        if (!mProcessesReady
3903                && !isAllowedWhileBooting(info)
3904                && !allowWhileBooting) {
3905            if (!mProcessesOnHold.contains(app)) {
3906                mProcessesOnHold.add(app);
3907            }
3908            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3909                    "System not ready, putting on hold: " + app);
3910            checkTime(startTime, "startProcess: returning with proc on hold");
3911            return app;
3912        }
3913
3914        checkTime(startTime, "startProcess: stepping in to startProcess");
3915        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
3916        checkTime(startTime, "startProcess: done starting proc!");
3917        return success ? app : null;
3918    }
3919
3920    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3921        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3922    }
3923
3924    private final void startProcessLocked(ProcessRecord app,
3925            String hostingType, String hostingNameStr) {
3926        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
3927    }
3928
3929    /**
3930     * @return {@code true} if process start is successful, false otherwise.
3931     */
3932    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
3933            String hostingNameStr, String abiOverride) {
3934        if (app.pendingStart) {
3935            return true;
3936        }
3937        long startTime = SystemClock.elapsedRealtime();
3938        if (app.pid > 0 && app.pid != MY_PID) {
3939            checkTime(startTime, "startProcess: removing from pids map");
3940            synchronized (mPidsSelfLocked) {
3941                mPidsSelfLocked.remove(app.pid);
3942                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3943            }
3944            checkTime(startTime, "startProcess: done removing from pids map");
3945            app.setPid(0);
3946        }
3947
3948        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3949                "startProcessLocked removing on hold: " + app);
3950        mProcessesOnHold.remove(app);
3951
3952        checkTime(startTime, "startProcess: starting to update cpu stats");
3953        updateCpuStats();
3954        checkTime(startTime, "startProcess: done updating cpu stats");
3955
3956        try {
3957            try {
3958                final int userId = UserHandle.getUserId(app.uid);
3959                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3960            } catch (RemoteException e) {
3961                throw e.rethrowAsRuntimeException();
3962            }
3963
3964            int uid = app.uid;
3965            int[] gids = null;
3966            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3967            if (!app.isolated) {
3968                int[] permGids = null;
3969                try {
3970                    checkTime(startTime, "startProcess: getting gids from package manager");
3971                    final IPackageManager pm = AppGlobals.getPackageManager();
3972                    permGids = pm.getPackageGids(app.info.packageName,
3973                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3974                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3975                            StorageManagerInternal.class);
3976                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3977                            app.info.packageName);
3978                } catch (RemoteException e) {
3979                    throw e.rethrowAsRuntimeException();
3980                }
3981
3982                /*
3983                 * Add shared application and profile GIDs so applications can share some
3984                 * resources like shared libraries and access user-wide resources
3985                 */
3986                if (ArrayUtils.isEmpty(permGids)) {
3987                    gids = new int[3];
3988                } else {
3989                    gids = new int[permGids.length + 3];
3990                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3991                }
3992                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3993                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3994                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3995
3996                // Replace any invalid GIDs
3997                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
3998                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
3999            }
4000            checkTime(startTime, "startProcess: building args");
4001            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
4002                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4003                        && mTopComponent != null
4004                        && app.processName.equals(mTopComponent.getPackageName())) {
4005                    uid = 0;
4006                }
4007                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
4008                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
4009                    uid = 0;
4010                }
4011            }
4012            int runtimeFlags = 0;
4013            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4014                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
4015                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
4016                // Also turn on CheckJNI for debuggable apps. It's quite
4017                // awkward to turn on otherwise.
4018                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4019            }
4020            // Run the app in safe mode if its manifest requests so or the
4021            // system is booted in safe mode.
4022            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
4023                mSafeMode == true) {
4024                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
4025            }
4026            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4027                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4028            }
4029            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4030            if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
4031                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4032            }
4033            String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
4034            if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
4035                runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
4036            }
4037            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4038                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4039            }
4040            if ("1".equals(SystemProperties.get("debug.assert"))) {
4041                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
4042            }
4043            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
4044                // Enable all debug flags required by the native debugger.
4045                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
4046                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
4047                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
4048                mNativeDebuggingApp = null;
4049            }
4050
4051            if (app.info.isPrivilegedApp() &&
4052                    SystemProperties.getBoolean("pm.dexopt.priv-apps-oob", false)) {
4053                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
4054            }
4055
4056            if (app.info.isAllowedToUseHiddenApi()) {
4057                // This app is allowed to use undocumented and private APIs. Set
4058                // up its runtime with the appropriate flag.
4059                runtimeFlags |= Zygote.DISABLE_HIDDEN_API_CHECKS;
4060            }
4061
4062            String invokeWith = null;
4063            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4064                // Debuggable apps may include a wrapper script with their library directory.
4065                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
4066                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4067                try {
4068                    if (new File(wrapperFileName).exists()) {
4069                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4070                    }
4071                } finally {
4072                    StrictMode.setThreadPolicy(oldPolicy);
4073                }
4074            }
4075
4076            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4077            if (requiredAbi == null) {
4078                requiredAbi = Build.SUPPORTED_ABIS[0];
4079            }
4080
4081            String instructionSet = null;
4082            if (app.info.primaryCpuAbi != null) {
4083                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4084            }
4085
4086            app.gids = gids;
4087            app.requiredAbi = requiredAbi;
4088            app.instructionSet = instructionSet;
4089
4090            // the per-user SELinux context must be set
4091            if (TextUtils.isEmpty(app.info.seInfoUser)) {
4092                Slog.wtf(TAG, "SELinux tag not defined",
4093                        new IllegalStateException("SELinux tag not defined for "
4094                        + app.info.packageName + " (uid " + app.uid + ")"));
4095            }
4096            final String seInfo = app.info.seInfo
4097                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
4098            // Start the process.  It will either succeed and return a result containing
4099            // the PID of the new process, or else throw a RuntimeException.
4100            final String entryPoint = "android.app.ActivityThread";
4101
4102            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4103                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4104                    startTime);
4105        } catch (RuntimeException e) {
4106            Slog.e(TAG, "Failure starting process " + app.processName, e);
4107
4108            // Something went very wrong while trying to start this process; one
4109            // common case is when the package is frozen due to an active
4110            // upgrade. To recover, clean up any active bookkeeping related to
4111            // starting this process. (We already invoked this method once when
4112            // the package was initially frozen through KILL_APPLICATION_MSG, so
4113            // it doesn't hurt to use it again.)
4114            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4115                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4116            return false;
4117        }
4118    }
4119
4120    @GuardedBy("this")
4121    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4122            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4123            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4124            long startTime) {
4125        app.pendingStart = true;
4126        app.killedByAm = false;
4127        app.removed = false;
4128        app.killed = false;
4129        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4130        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4131        if (mConstants.FLAG_PROCESS_START_ASYNC) {
4132            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4133                    "Posting procStart msg for " + app.toShortString());
4134            mProcStartHandler.post(() -> {
4135                try {
4136                    synchronized (ActivityManagerService.this) {
4137                        final String reason = isProcStartValidLocked(app, startSeq);
4138                        if (reason != null) {
4139                            Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4140                                    + " don't start process, " + reason);
4141                            app.pendingStart = false;
4142                            return;
4143                        }
4144                        app.usingWrapper = invokeWith != null
4145                                || SystemProperties.get("wrap." + app.processName) != null;
4146                        mPendingStarts.put(startSeq, app);
4147                    }
4148                    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4149                            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4150                            requiredAbi, instructionSet, invokeWith, app.startTime);
4151                    synchronized (ActivityManagerService.this) {
4152                        handleProcessStartedLocked(app, startResult, startSeq);
4153                    }
4154                } catch (RuntimeException e) {
4155                    synchronized (ActivityManagerService.this) {
4156                        Slog.e(TAG, "Failure starting process " + app.processName, e);
4157                        mPendingStarts.remove(startSeq);
4158                        app.pendingStart = false;
4159                        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4160                                false, false, true, false, false,
4161                                UserHandle.getUserId(app.userId), "start failure");
4162                    }
4163                }
4164            });
4165            return true;
4166        } else {
4167            try {
4168                final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4169                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4170                        invokeWith, startTime);
4171                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4172                        startSeq, false);
4173            } catch (RuntimeException e) {
4174                Slog.e(TAG, "Failure starting process " + app.processName, e);
4175                app.pendingStart = false;
4176                forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4177                        false, false, true, false, false,
4178                        UserHandle.getUserId(app.userId), "start failure");
4179            }
4180            return app.pid > 0;
4181        }
4182    }
4183
4184    private ProcessStartResult startProcess(String hostingType, String entryPoint,
4185            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4186            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4187            long startTime) {
4188        try {
4189            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4190                    app.processName);
4191            checkTime(startTime, "startProcess: asking zygote to start proc");
4192            final ProcessStartResult startResult;
4193            if (hostingType.equals("webview_service")) {
4194                startResult = startWebView(entryPoint,
4195                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4196                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4197                        app.info.dataDir, null,
4198                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4199            } else {
4200                startResult = Process.start(entryPoint,
4201                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4202                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4203                        app.info.dataDir, invokeWith,
4204                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4205            }
4206            checkTime(startTime, "startProcess: returned from zygote!");
4207            return startResult;
4208        } finally {
4209            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4210        }
4211    }
4212
4213    @GuardedBy("this")
4214    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4215        StringBuilder sb = null;
4216        if (app.killedByAm) {
4217            if (sb == null) sb = new StringBuilder();
4218            sb.append("killedByAm=true;");
4219        }
4220        if (mProcessNames.get(app.processName, app.uid) != app) {
4221            if (sb == null) sb = new StringBuilder();
4222            sb.append("No entry in mProcessNames;");
4223        }
4224        if (!app.pendingStart) {
4225            if (sb == null) sb = new StringBuilder();
4226            sb.append("pendingStart=false;");
4227        }
4228        if (app.startSeq > expectedStartSeq) {
4229            if (sb == null) sb = new StringBuilder();
4230            sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4231        }
4232        return sb == null ? null : sb.toString();
4233    }
4234
4235    @GuardedBy("this")
4236    private boolean handleProcessStartedLocked(ProcessRecord pending,
4237            ProcessStartResult startResult, long expectedStartSeq) {
4238        // Indicates that this process start has been taken care of.
4239        if (mPendingStarts.get(expectedStartSeq) == null) {
4240            if (pending.pid == startResult.pid) {
4241                pending.usingWrapper = startResult.usingWrapper;
4242                // TODO: Update already existing clients of usingWrapper
4243            }
4244            return false;
4245        }
4246        return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4247                expectedStartSeq, false);
4248    }
4249
4250    @GuardedBy("this")
4251    private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4252            long expectedStartSeq, boolean procAttached) {
4253        mPendingStarts.remove(expectedStartSeq);
4254        final String reason = isProcStartValidLocked(app, expectedStartSeq);
4255        if (reason != null) {
4256            Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4257                    + ", " + reason);
4258            app.pendingStart = false;
4259            Process.killProcessQuiet(pid);
4260            Process.killProcessGroup(app.uid, app.pid);
4261            return false;
4262        }
4263        mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4264        checkTime(app.startTime, "startProcess: done updating battery stats");
4265
4266        EventLog.writeEvent(EventLogTags.AM_PROC_START,
4267                UserHandle.getUserId(app.startUid), pid, app.startUid,
4268                app.processName, app.hostingType,
4269                app.hostingNameStr != null ? app.hostingNameStr : "");
4270
4271        try {
4272            AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4273                    app.seInfo, app.info.sourceDir, pid);
4274        } catch (RemoteException ex) {
4275            // Ignore
4276        }
4277
4278        if (app.persistent) {
4279            Watchdog.getInstance().processStarted(app.processName, pid);
4280        }
4281
4282        checkTime(app.startTime, "startProcess: building log message");
4283        StringBuilder buf = mStringBuilder;
4284        buf.setLength(0);
4285        buf.append("Start proc ");
4286        buf.append(pid);
4287        buf.append(':');
4288        buf.append(app.processName);
4289        buf.append('/');
4290        UserHandle.formatUid(buf, app.startUid);
4291        if (app.isolatedEntryPoint != null) {
4292            buf.append(" [");
4293            buf.append(app.isolatedEntryPoint);
4294            buf.append("]");
4295        }
4296        buf.append(" for ");
4297        buf.append(app.hostingType);
4298        if (app.hostingNameStr != null) {
4299            buf.append(" ");
4300            buf.append(app.hostingNameStr);
4301        }
4302        Slog.i(TAG, buf.toString());
4303        app.setPid(pid);
4304        app.usingWrapper = usingWrapper;
4305        app.pendingStart = false;
4306        checkTime(app.startTime, "startProcess: starting to update pids map");
4307        ProcessRecord oldApp;
4308        synchronized (mPidsSelfLocked) {
4309            oldApp = mPidsSelfLocked.get(pid);
4310        }
4311        // If there is already an app occupying that pid that hasn't been cleaned up
4312        if (oldApp != null && !app.isolated) {
4313            // Clean up anything relating to this pid first
4314            Slog.w(TAG, "Reusing pid " + pid
4315                    + " while app is still mapped to it");
4316            cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4317                    true /*replacingPid*/);
4318        }
4319        synchronized (mPidsSelfLocked) {
4320            this.mPidsSelfLocked.put(pid, app);
4321            if (!procAttached) {
4322                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4323                msg.obj = app;
4324                mHandler.sendMessageDelayed(msg, usingWrapper
4325                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4326            }
4327        }
4328        checkTime(app.startTime, "startProcess: done updating pids map");
4329        return true;
4330    }
4331
4332    void updateUsageStats(ActivityRecord component, boolean resumed) {
4333        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4334                "updateUsageStats: comp=" + component + "res=" + resumed);
4335        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4336        StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4337            component.userId, component.realActivity.getPackageName(),
4338            component.realActivity.getShortClassName(), resumed ?
4339                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_FOREGROUND :
4340                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_BACKGROUND);
4341        if (resumed) {
4342            if (mUsageStatsService != null) {
4343                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4344                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4345
4346            }
4347            synchronized (stats) {
4348                stats.noteActivityResumedLocked(component.app.uid);
4349            }
4350        } else {
4351            if (mUsageStatsService != null) {
4352                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4353                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4354            }
4355            synchronized (stats) {
4356                stats.noteActivityPausedLocked(component.app.uid);
4357            }
4358        }
4359    }
4360
4361    Intent getHomeIntent() {
4362        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4363        intent.setComponent(mTopComponent);
4364        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4365        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4366            intent.addCategory(Intent.CATEGORY_HOME);
4367        }
4368        return intent;
4369    }
4370
4371    boolean startHomeActivityLocked(int userId, String reason) {
4372        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4373                && mTopAction == null) {
4374            // We are running in factory test mode, but unable to find
4375            // the factory test app, so just sit around displaying the
4376            // error message and don't try to start anything.
4377            return false;
4378        }
4379        Intent intent = getHomeIntent();
4380        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4381        if (aInfo != null) {
4382            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4383            // Don't do this if the home app is currently being
4384            // instrumented.
4385            aInfo = new ActivityInfo(aInfo);
4386            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4387            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4388                    aInfo.applicationInfo.uid, true);
4389            if (app == null || app.instr == null) {
4390                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4391                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4392                // For ANR debugging to verify if the user activity is the one that actually
4393                // launched.
4394                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4395                mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4396            }
4397        } else {
4398            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4399        }
4400
4401        return true;
4402    }
4403
4404    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4405        ActivityInfo ai = null;
4406        ComponentName comp = intent.getComponent();
4407        try {
4408            if (comp != null) {
4409                // Factory test.
4410                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4411            } else {
4412                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4413                        intent,
4414                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4415                        flags, userId);
4416
4417                if (info != null) {
4418                    ai = info.activityInfo;
4419                }
4420            }
4421        } catch (RemoteException e) {
4422            // ignore
4423        }
4424
4425        return ai;
4426    }
4427
4428    boolean getCheckedForSetup() {
4429        return mCheckedForSetup;
4430    }
4431
4432    void setCheckedForSetup(boolean checked) {
4433        mCheckedForSetup = checked;
4434    }
4435
4436    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4437        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4438    }
4439
4440    void enforceNotIsolatedCaller(String caller) {
4441        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4442            throw new SecurityException("Isolated process not allowed to call " + caller);
4443        }
4444    }
4445
4446    @Override
4447    public int getFrontActivityScreenCompatMode() {
4448        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4449        synchronized (this) {
4450            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4451        }
4452    }
4453
4454    @Override
4455    public void setFrontActivityScreenCompatMode(int mode) {
4456        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4457                "setFrontActivityScreenCompatMode");
4458        synchronized (this) {
4459            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4460        }
4461    }
4462
4463    @Override
4464    public int getPackageScreenCompatMode(String packageName) {
4465        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4466        synchronized (this) {
4467            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4468        }
4469    }
4470
4471    @Override
4472    public void setPackageScreenCompatMode(String packageName, int mode) {
4473        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4474                "setPackageScreenCompatMode");
4475        synchronized (this) {
4476            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4477        }
4478    }
4479
4480    @Override
4481    public boolean getPackageAskScreenCompat(String packageName) {
4482        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4483        synchronized (this) {
4484            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4485        }
4486    }
4487
4488    @Override
4489    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4490        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4491                "setPackageAskScreenCompat");
4492        synchronized (this) {
4493            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4494        }
4495    }
4496
4497    private boolean hasUsageStatsPermission(String callingPackage) {
4498        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4499                Binder.getCallingUid(), callingPackage);
4500        if (mode == AppOpsManager.MODE_DEFAULT) {
4501            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4502                    == PackageManager.PERMISSION_GRANTED;
4503        }
4504        return mode == AppOpsManager.MODE_ALLOWED;
4505    }
4506
4507    @Override
4508    public int getPackageProcessState(String packageName, String callingPackage) {
4509        if (!hasUsageStatsPermission(callingPackage)) {
4510            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4511                    "getPackageProcessState");
4512        }
4513
4514        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4515        synchronized (this) {
4516            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4517                final ProcessRecord proc = mLruProcesses.get(i);
4518                if (procState > proc.setProcState) {
4519                    if (proc.pkgList.containsKey(packageName) ||
4520                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4521                        procState = proc.setProcState;
4522                    }
4523                }
4524            }
4525        }
4526        return procState;
4527    }
4528
4529    @Override
4530    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4531            throws RemoteException {
4532        synchronized (this) {
4533            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4534            if (app == null) {
4535                throw new IllegalArgumentException("Unknown process: " + process);
4536            }
4537            if (app.thread == null) {
4538                throw new IllegalArgumentException("Process has no app thread");
4539            }
4540            if (app.trimMemoryLevel >= level) {
4541                throw new IllegalArgumentException(
4542                        "Unable to set a higher trim level than current level");
4543            }
4544            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4545                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4546                throw new IllegalArgumentException("Unable to set a background trim level "
4547                    + "on a foreground process");
4548            }
4549            app.thread.scheduleTrimMemory(level);
4550            app.trimMemoryLevel = level;
4551            return true;
4552        }
4553    }
4554
4555    private void dispatchProcessesChanged() {
4556        int N;
4557        synchronized (this) {
4558            N = mPendingProcessChanges.size();
4559            if (mActiveProcessChanges.length < N) {
4560                mActiveProcessChanges = new ProcessChangeItem[N];
4561            }
4562            mPendingProcessChanges.toArray(mActiveProcessChanges);
4563            mPendingProcessChanges.clear();
4564            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4565                    "*** Delivering " + N + " process changes");
4566        }
4567
4568        int i = mProcessObservers.beginBroadcast();
4569        while (i > 0) {
4570            i--;
4571            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4572            if (observer != null) {
4573                try {
4574                    for (int j=0; j<N; j++) {
4575                        ProcessChangeItem item = mActiveProcessChanges[j];
4576                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4577                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4578                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4579                                    + item.uid + ": " + item.foregroundActivities);
4580                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4581                                    item.foregroundActivities);
4582                        }
4583                    }
4584                } catch (RemoteException e) {
4585                }
4586            }
4587        }
4588        mProcessObservers.finishBroadcast();
4589
4590        synchronized (this) {
4591            for (int j=0; j<N; j++) {
4592                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4593            }
4594        }
4595    }
4596
4597    private void dispatchProcessDied(int pid, int uid) {
4598        int i = mProcessObservers.beginBroadcast();
4599        while (i > 0) {
4600            i--;
4601            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4602            if (observer != null) {
4603                try {
4604                    observer.onProcessDied(pid, uid);
4605                } catch (RemoteException e) {
4606                }
4607            }
4608        }
4609        mProcessObservers.finishBroadcast();
4610    }
4611
4612    @VisibleForTesting
4613    void dispatchUidsChanged() {
4614        int N;
4615        synchronized (this) {
4616            N = mPendingUidChanges.size();
4617            if (mActiveUidChanges.length < N) {
4618                mActiveUidChanges = new UidRecord.ChangeItem[N];
4619            }
4620            for (int i=0; i<N; i++) {
4621                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4622                mActiveUidChanges[i] = change;
4623                if (change.uidRecord != null) {
4624                    change.uidRecord.pendingChange = null;
4625                    change.uidRecord = null;
4626                }
4627            }
4628            mPendingUidChanges.clear();
4629            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4630                    "*** Delivering " + N + " uid changes");
4631        }
4632
4633        int i = mUidObservers.beginBroadcast();
4634        while (i > 0) {
4635            i--;
4636            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4637                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4638        }
4639        mUidObservers.finishBroadcast();
4640
4641        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4642            for (int j = 0; j < N; ++j) {
4643                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4644                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4645                    mValidateUids.remove(item.uid);
4646                } else {
4647                    UidRecord validateUid = mValidateUids.get(item.uid);
4648                    if (validateUid == null) {
4649                        validateUid = new UidRecord(item.uid);
4650                        mValidateUids.put(item.uid, validateUid);
4651                    }
4652                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4653                        validateUid.idle = true;
4654                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4655                        validateUid.idle = false;
4656                    }
4657                    validateUid.curProcState = validateUid.setProcState = item.processState;
4658                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4659                }
4660            }
4661        }
4662
4663        synchronized (this) {
4664            for (int j = 0; j < N; j++) {
4665                mAvailUidChanges.add(mActiveUidChanges[j]);
4666            }
4667        }
4668    }
4669
4670    private void dispatchUidsChangedForObserver(IUidObserver observer,
4671            UidObserverRegistration reg, int changesSize) {
4672        if (observer == null) {
4673            return;
4674        }
4675        try {
4676            for (int j = 0; j < changesSize; j++) {
4677                UidRecord.ChangeItem item = mActiveUidChanges[j];
4678                final int change = item.change;
4679                if (change == UidRecord.CHANGE_PROCSTATE &&
4680                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4681                    // No-op common case: no significant change, the observer is not
4682                    // interested in all proc state changes.
4683                    continue;
4684                }
4685                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4686                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4687                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4688                                "UID idle uid=" + item.uid);
4689                        observer.onUidIdle(item.uid, item.ephemeral);
4690                    }
4691                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4692                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4693                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4694                                "UID active uid=" + item.uid);
4695                        observer.onUidActive(item.uid);
4696                    }
4697                }
4698                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4699                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4700                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4701                                "UID cached uid=" + item.uid);
4702                        observer.onUidCachedChanged(item.uid, true);
4703                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4704                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4705                                "UID active uid=" + item.uid);
4706                        observer.onUidCachedChanged(item.uid, false);
4707                    }
4708                }
4709                if ((change & UidRecord.CHANGE_GONE) != 0) {
4710                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4711                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4712                                "UID gone uid=" + item.uid);
4713                        observer.onUidGone(item.uid, item.ephemeral);
4714                    }
4715                    if (reg.lastProcStates != null) {
4716                        reg.lastProcStates.delete(item.uid);
4717                    }
4718                } else {
4719                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4720                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4721                                "UID CHANGED uid=" + item.uid
4722                                        + ": " + item.processState);
4723                        boolean doReport = true;
4724                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4725                            final int lastState = reg.lastProcStates.get(item.uid,
4726                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4727                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4728                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4729                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4730                                doReport = lastAboveCut != newAboveCut;
4731                            } else {
4732                                doReport = item.processState
4733                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4734                            }
4735                        }
4736                        if (doReport) {
4737                            if (reg.lastProcStates != null) {
4738                                reg.lastProcStates.put(item.uid, item.processState);
4739                            }
4740                            observer.onUidStateChanged(item.uid, item.processState,
4741                                    item.procStateSeq);
4742                        }
4743                    }
4744                }
4745            }
4746        } catch (RemoteException e) {
4747        }
4748    }
4749
4750    void dispatchOomAdjObserver(String msg) {
4751        OomAdjObserver observer;
4752        synchronized (this) {
4753            observer = mCurOomAdjObserver;
4754        }
4755
4756        if (observer != null) {
4757            observer.onOomAdjMessage(msg);
4758        }
4759    }
4760
4761    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4762        synchronized (this) {
4763            mCurOomAdjUid = uid;
4764            mCurOomAdjObserver = observer;
4765        }
4766    }
4767
4768    void clearOomAdjObserver() {
4769        synchronized (this) {
4770            mCurOomAdjUid = -1;
4771            mCurOomAdjObserver = null;
4772        }
4773    }
4774
4775    void reportOomAdjMessageLocked(String tag, String msg) {
4776        Slog.d(tag, msg);
4777        if (mCurOomAdjObserver != null) {
4778            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4779        }
4780    }
4781
4782    @Override
4783    public final int startActivity(IApplicationThread caller, String callingPackage,
4784            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4785            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4786        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4787                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4788                UserHandle.getCallingUserId());
4789    }
4790
4791    @Override
4792    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4793            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4794            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4795        enforceNotIsolatedCaller("startActivity");
4796        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4797                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4798        // TODO: Switch to user app stacks here.
4799        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
4800                .setCaller(caller)
4801                .setCallingPackage(callingPackage)
4802                .setResolvedType(resolvedType)
4803                .setResultTo(resultTo)
4804                .setResultWho(resultWho)
4805                .setRequestCode(requestCode)
4806                .setStartFlags(startFlags)
4807                .setProfilerInfo(profilerInfo)
4808                .setActivityOptions(bOptions)
4809                .setMayWait(userId)
4810                .execute();
4811
4812    }
4813
4814    @Override
4815    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4816            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4817            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4818            int userId) {
4819
4820        // This is very dangerous -- it allows you to perform a start activity (including
4821        // permission grants) as any app that may launch one of your own activities.  So
4822        // we will only allow this to be done from activities that are part of the core framework,
4823        // and then only when they are running as the system.
4824        final ActivityRecord sourceRecord;
4825        final int targetUid;
4826        final String targetPackage;
4827        synchronized (this) {
4828            if (resultTo == null) {
4829                throw new SecurityException("Must be called from an activity");
4830            }
4831            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4832            if (sourceRecord == null) {
4833                throw new SecurityException("Called with bad activity token: " + resultTo);
4834            }
4835            if (!sourceRecord.info.packageName.equals("android")) {
4836                throw new SecurityException(
4837                        "Must be called from an activity that is declared in the android package");
4838            }
4839            if (sourceRecord.app == null) {
4840                throw new SecurityException("Called without a process attached to activity");
4841            }
4842            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4843                // This is still okay, as long as this activity is running under the
4844                // uid of the original calling activity.
4845                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4846                    throw new SecurityException(
4847                            "Calling activity in uid " + sourceRecord.app.uid
4848                                    + " must be system uid or original calling uid "
4849                                    + sourceRecord.launchedFromUid);
4850                }
4851            }
4852            if (ignoreTargetSecurity) {
4853                if (intent.getComponent() == null) {
4854                    throw new SecurityException(
4855                            "Component must be specified with ignoreTargetSecurity");
4856                }
4857                if (intent.getSelector() != null) {
4858                    throw new SecurityException(
4859                            "Selector not allowed with ignoreTargetSecurity");
4860                }
4861            }
4862            targetUid = sourceRecord.launchedFromUid;
4863            targetPackage = sourceRecord.launchedFromPackage;
4864        }
4865
4866        if (userId == UserHandle.USER_NULL) {
4867            userId = UserHandle.getUserId(sourceRecord.app.uid);
4868        }
4869
4870        // TODO: Switch to user app stacks here.
4871        try {
4872            return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
4873                    .setCallingUid(targetUid)
4874                    .setCallingPackage(targetPackage)
4875                    .setResolvedType(resolvedType)
4876                    .setResultTo(resultTo)
4877                    .setResultWho(resultWho)
4878                    .setRequestCode(requestCode)
4879                    .setStartFlags(startFlags)
4880                    .setActivityOptions(bOptions)
4881                    .setMayWait(userId)
4882                    .setIgnoreTargetSecurity(ignoreTargetSecurity)
4883                    .execute();
4884        } catch (SecurityException e) {
4885            // XXX need to figure out how to propagate to original app.
4886            // A SecurityException here is generally actually a fault of the original
4887            // calling activity (such as a fairly granting permissions), so propagate it
4888            // back to them.
4889            /*
4890            StringBuilder msg = new StringBuilder();
4891            msg.append("While launching");
4892            msg.append(intent.toString());
4893            msg.append(": ");
4894            msg.append(e.getMessage());
4895            */
4896            throw e;
4897        }
4898    }
4899
4900    @Override
4901    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4902            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4903            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4904        enforceNotIsolatedCaller("startActivityAndWait");
4905        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4906                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4907        WaitResult res = new WaitResult();
4908        // TODO: Switch to user app stacks here.
4909        mActivityStartController.obtainStarter(intent, "startActivityAndWait")
4910                .setCaller(caller)
4911                .setCallingPackage(callingPackage)
4912                .setResolvedType(resolvedType)
4913                .setResultTo(resultTo)
4914                .setResultWho(resultWho)
4915                .setRequestCode(requestCode)
4916                .setStartFlags(startFlags)
4917                .setActivityOptions(bOptions)
4918                .setMayWait(userId)
4919                .setProfilerInfo(profilerInfo)
4920                .setWaitResult(res)
4921                .execute();
4922        return res;
4923    }
4924
4925    @Override
4926    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4927            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4928            int startFlags, Configuration config, Bundle bOptions, int userId) {
4929        enforceNotIsolatedCaller("startActivityWithConfig");
4930        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4931                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4932        // TODO: Switch to user app stacks here.
4933        return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
4934                .setCaller(caller)
4935                .setCallingPackage(callingPackage)
4936                .setResolvedType(resolvedType)
4937                .setResultTo(resultTo)
4938                .setResultWho(resultWho)
4939                .setRequestCode(requestCode)
4940                .setStartFlags(startFlags)
4941                .setGlobalConfiguration(config)
4942                .setActivityOptions(bOptions)
4943                .setMayWait(userId)
4944                .execute();
4945    }
4946
4947    @Override
4948    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4949            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4950            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4951            throws TransactionTooLargeException {
4952        enforceNotIsolatedCaller("startActivityIntentSender");
4953        // Refuse possible leaked file descriptors
4954        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4955            throw new IllegalArgumentException("File descriptors passed in Intent");
4956        }
4957
4958        if (!(target instanceof PendingIntentRecord)) {
4959            throw new IllegalArgumentException("Bad PendingIntent object");
4960        }
4961
4962        PendingIntentRecord pir = (PendingIntentRecord)target;
4963
4964        synchronized (this) {
4965            // If this is coming from the currently resumed activity, it is
4966            // effectively saying that app switches are allowed at this point.
4967            final ActivityStack stack = getFocusedStack();
4968            if (stack.mResumedActivity != null &&
4969                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4970                mAppSwitchesAllowedTime = 0;
4971            }
4972        }
4973        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4974                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4975        return ret;
4976    }
4977
4978    @Override
4979    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4980            Intent intent, String resolvedType, IVoiceInteractionSession session,
4981            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4982            Bundle bOptions, int userId) {
4983        enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
4984        if (session == null || interactor == null) {
4985            throw new NullPointerException("null session or interactor");
4986        }
4987        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4988                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4989        // TODO: Switch to user app stacks here.
4990        return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
4991                .setCallingUid(callingUid)
4992                .setCallingPackage(callingPackage)
4993                .setResolvedType(resolvedType)
4994                .setVoiceSession(session)
4995                .setVoiceInteractor(interactor)
4996                .setStartFlags(startFlags)
4997                .setProfilerInfo(profilerInfo)
4998                .setActivityOptions(bOptions)
4999                .setMayWait(userId)
5000                .execute();
5001    }
5002
5003    @Override
5004    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
5005            Intent intent, String resolvedType, Bundle bOptions, int userId) {
5006        enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
5007        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5008                ALLOW_FULL_ONLY, "startAssistantActivity", null);
5009
5010        return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
5011                .setCallingUid(callingUid)
5012                .setCallingPackage(callingPackage)
5013                .setResolvedType(resolvedType)
5014                .setActivityOptions(bOptions)
5015                .setMayWait(userId)
5016                .execute();
5017    }
5018
5019    @Override
5020    public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
5021                IRecentsAnimationRunner recentsAnimationRunner) {
5022        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
5023        final long origId = Binder.clearCallingIdentity();
5024        try {
5025            synchronized (this) {
5026                final int recentsUid = mRecentTasks.getRecentsComponentUid();
5027                final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
5028                final String recentsPackage = recentsComponent.getPackageName();
5029
5030                // If provided, kick off the request for the assist data in the background before
5031                // starting the activity
5032                if (assistDataReceiver != null) {
5033                    final AppOpsManager appOpsManager = (AppOpsManager)
5034                            mContext.getSystemService(Context.APP_OPS_SERVICE);
5035                    final AssistDataReceiverProxy proxy = new AssistDataReceiverProxy(
5036                            assistDataReceiver, recentsPackage);
5037                    final AssistDataRequester requester = new AssistDataRequester(mContext, this,
5038                            mWindowManager, appOpsManager, proxy, this,
5039                            OP_ASSIST_STRUCTURE, OP_NONE);
5040                    requester.requestAssistData(mStackSupervisor.getTopVisibleActivities(),
5041                            true /* fetchData */, false /* fetchScreenshots */,
5042                            true /* allowFetchData */, false /* alloweFetchScreenshots */,
5043                            recentsUid, recentsPackage);
5044                }
5045
5046                // Start a new recents animation
5047                final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
5048                        mActivityStartController, mWindowManager, mUserController);
5049                anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
5050                        recentsUid);
5051            }
5052        } finally {
5053            Binder.restoreCallingIdentity(origId);
5054        }
5055    }
5056
5057    @Override
5058    public void cancelRecentsAnimation() {
5059        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
5060        final long origId = Binder.clearCallingIdentity();
5061        try {
5062            synchronized (this) {
5063                mWindowManager.cancelRecentsAnimation();
5064            }
5065        } finally {
5066            Binder.restoreCallingIdentity(origId);
5067        }
5068    }
5069
5070    @Override
5071    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
5072            throws RemoteException {
5073        Slog.i(TAG, "Activity tried to startVoiceInteraction");
5074        synchronized (this) {
5075            ActivityRecord activity = getFocusedStack().getTopActivity();
5076            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
5077                throw new SecurityException("Only focused activity can call startVoiceInteraction");
5078            }
5079            if (mRunningVoice != null || activity.getTask().voiceSession != null
5080                    || activity.voiceSession != null) {
5081                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
5082                return;
5083            }
5084            if (activity.pendingVoiceInteractionStart) {
5085                Slog.w(TAG, "Pending start of voice interaction already.");
5086                return;
5087            }
5088            activity.pendingVoiceInteractionStart = true;
5089        }
5090        LocalServices.getService(VoiceInteractionManagerInternal.class)
5091                .startLocalVoiceInteraction(callingActivity, options);
5092    }
5093
5094    @Override
5095    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5096        LocalServices.getService(VoiceInteractionManagerInternal.class)
5097                .stopLocalVoiceInteraction(callingActivity);
5098    }
5099
5100    @Override
5101    public boolean supportsLocalVoiceInteraction() throws RemoteException {
5102        return LocalServices.getService(VoiceInteractionManagerInternal.class)
5103                .supportsLocalVoiceInteraction();
5104    }
5105
5106    void onLocalVoiceInteractionStartedLocked(IBinder activity,
5107            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5108        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
5109        if (activityToCallback == null) return;
5110        activityToCallback.setVoiceSessionLocked(voiceSession);
5111
5112        // Inform the activity
5113        try {
5114            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5115                    voiceInteractor);
5116            long token = Binder.clearCallingIdentity();
5117            try {
5118                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5119            } finally {
5120                Binder.restoreCallingIdentity(token);
5121            }
5122            // TODO: VI Should we cache the activity so that it's easier to find later
5123            // rather than scan through all the stacks and activities?
5124        } catch (RemoteException re) {
5125            activityToCallback.clearVoiceSessionLocked();
5126            // TODO: VI Should this terminate the voice session?
5127        }
5128    }
5129
5130    @Override
5131    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5132        synchronized (this) {
5133            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5134                if (keepAwake) {
5135                    mVoiceWakeLock.acquire();
5136                } else {
5137                    mVoiceWakeLock.release();
5138                }
5139            }
5140        }
5141    }
5142
5143    @Override
5144    public boolean startNextMatchingActivity(IBinder callingActivity,
5145            Intent intent, Bundle bOptions) {
5146        // Refuse possible leaked file descriptors
5147        if (intent != null && intent.hasFileDescriptors() == true) {
5148            throw new IllegalArgumentException("File descriptors passed in Intent");
5149        }
5150        SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5151
5152        synchronized (this) {
5153            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5154            if (r == null) {
5155                SafeActivityOptions.abort(options);
5156                return false;
5157            }
5158            if (r.app == null || r.app.thread == null) {
5159                // The caller is not running...  d'oh!
5160                SafeActivityOptions.abort(options);
5161                return false;
5162            }
5163            intent = new Intent(intent);
5164            // The caller is not allowed to change the data.
5165            intent.setDataAndType(r.intent.getData(), r.intent.getType());
5166            // And we are resetting to find the next component...
5167            intent.setComponent(null);
5168
5169            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5170
5171            ActivityInfo aInfo = null;
5172            try {
5173                List<ResolveInfo> resolves =
5174                    AppGlobals.getPackageManager().queryIntentActivities(
5175                            intent, r.resolvedType,
5176                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5177                            UserHandle.getCallingUserId()).getList();
5178
5179                // Look for the original activity in the list...
5180                final int N = resolves != null ? resolves.size() : 0;
5181                for (int i=0; i<N; i++) {
5182                    ResolveInfo rInfo = resolves.get(i);
5183                    if (rInfo.activityInfo.packageName.equals(r.packageName)
5184                            && rInfo.activityInfo.name.equals(r.info.name)) {
5185                        // We found the current one...  the next matching is
5186                        // after it.
5187                        i++;
5188                        if (i<N) {
5189                            aInfo = resolves.get(i).activityInfo;
5190                        }
5191                        if (debug) {
5192                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
5193                                    + "/" + r.info.name);
5194                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5195                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
5196                        }
5197                        break;
5198                    }
5199                }
5200            } catch (RemoteException e) {
5201            }
5202
5203            if (aInfo == null) {
5204                // Nobody who is next!
5205                SafeActivityOptions.abort(options);
5206                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5207                return false;
5208            }
5209
5210            intent.setComponent(new ComponentName(
5211                    aInfo.applicationInfo.packageName, aInfo.name));
5212            intent.setFlags(intent.getFlags()&~(
5213                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5214                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
5215                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5216                    FLAG_ACTIVITY_NEW_TASK));
5217
5218            // Okay now we need to start the new activity, replacing the
5219            // currently running activity.  This is a little tricky because
5220            // we want to start the new one as if the current one is finished,
5221            // but not finish the current one first so that there is no flicker.
5222            // And thus...
5223            final boolean wasFinishing = r.finishing;
5224            r.finishing = true;
5225
5226            // Propagate reply information over to the new activity.
5227            final ActivityRecord resultTo = r.resultTo;
5228            final String resultWho = r.resultWho;
5229            final int requestCode = r.requestCode;
5230            r.resultTo = null;
5231            if (resultTo != null) {
5232                resultTo.removeResultsLocked(r, resultWho, requestCode);
5233            }
5234
5235            final long origId = Binder.clearCallingIdentity();
5236            // TODO(b/64750076): Check if calling pid should really be -1.
5237            final int res = mActivityStartController
5238                    .obtainStarter(intent, "startNextMatchingActivity")
5239                    .setCaller(r.app.thread)
5240                    .setResolvedType(r.resolvedType)
5241                    .setActivityInfo(aInfo)
5242                    .setResultTo(resultTo != null ? resultTo.appToken : null)
5243                    .setResultWho(resultWho)
5244                    .setRequestCode(requestCode)
5245                    .setCallingPid(-1)
5246                    .setCallingUid(r.launchedFromUid)
5247                    .setCallingPackage(r.launchedFromPackage)
5248                    .setRealCallingPid(-1)
5249                    .setRealCallingUid(r.launchedFromUid)
5250                    .setActivityOptions(options)
5251                    .execute();
5252            Binder.restoreCallingIdentity(origId);
5253
5254            r.finishing = wasFinishing;
5255            if (res != ActivityManager.START_SUCCESS) {
5256                return false;
5257            }
5258            return true;
5259        }
5260    }
5261
5262    @Override
5263    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5264        enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5265                "startActivityFromRecents()");
5266
5267        final int callingPid = Binder.getCallingPid();
5268        final int callingUid = Binder.getCallingUid();
5269        final long origId = Binder.clearCallingIdentity();
5270        try {
5271            synchronized (this) {
5272                return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5273                        SafeActivityOptions.fromBundle(bOptions));
5274            }
5275        } finally {
5276            Binder.restoreCallingIdentity(origId);
5277        }
5278    }
5279
5280    @Override
5281    public final int startActivities(IApplicationThread caller, String callingPackage,
5282            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5283            int userId) {
5284        final String reason = "startActivities";
5285        enforceNotIsolatedCaller(reason);
5286        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5287                userId, false, ALLOW_FULL_ONLY, reason, null);
5288        // TODO: Switch to user app stacks here.
5289        int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
5290                intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
5291                reason);
5292        return ret;
5293    }
5294
5295    @Override
5296    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5297        synchronized (this) {
5298            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5299            if (r == null) {
5300                return;
5301            }
5302            r.reportFullyDrawnLocked(restoredFromBundle);
5303        }
5304    }
5305
5306    @Override
5307    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5308        synchronized (this) {
5309            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5310            if (r == null) {
5311                return;
5312            }
5313            final long origId = Binder.clearCallingIdentity();
5314            try {
5315                r.setRequestedOrientation(requestedOrientation);
5316            } finally {
5317                Binder.restoreCallingIdentity(origId);
5318            }
5319        }
5320    }
5321
5322    @Override
5323    public int getRequestedOrientation(IBinder token) {
5324        synchronized (this) {
5325            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5326            if (r == null) {
5327                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5328            }
5329            return r.getRequestedOrientation();
5330        }
5331    }
5332
5333    @Override
5334    public final void requestActivityRelaunch(IBinder token) {
5335        synchronized(this) {
5336            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5337            if (r == null) {
5338                return;
5339            }
5340            final long origId = Binder.clearCallingIdentity();
5341            try {
5342                r.forceNewConfig = true;
5343                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5344                        true /* preserveWindow */);
5345            } finally {
5346                Binder.restoreCallingIdentity(origId);
5347            }
5348        }
5349    }
5350
5351    /**
5352     * This is the internal entry point for handling Activity.finish().
5353     *
5354     * @param token The Binder token referencing the Activity we want to finish.
5355     * @param resultCode Result code, if any, from this Activity.
5356     * @param resultData Result data (Intent), if any, from this Activity.
5357     * @param finishTask Whether to finish the task associated with this Activity.
5358     *
5359     * @return Returns true if the activity successfully finished, or false if it is still running.
5360     */
5361    @Override
5362    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5363            int finishTask) {
5364        // Refuse possible leaked file descriptors
5365        if (resultData != null && resultData.hasFileDescriptors() == true) {
5366            throw new IllegalArgumentException("File descriptors passed in Intent");
5367        }
5368
5369        synchronized(this) {
5370            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5371            if (r == null) {
5372                return true;
5373            }
5374            // Keep track of the root activity of the task before we finish it
5375            TaskRecord tr = r.getTask();
5376            ActivityRecord rootR = tr.getRootActivity();
5377            if (rootR == null) {
5378                Slog.w(TAG, "Finishing task with all activities already finished");
5379            }
5380            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5381            // finish.
5382            if (mLockTaskController.activityBlockedFromFinish(r)) {
5383                return false;
5384            }
5385
5386            if (mController != null) {
5387                // Find the first activity that is not finishing.
5388                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5389                if (next != null) {
5390                    // ask watcher if this is allowed
5391                    boolean resumeOK = true;
5392                    try {
5393                        resumeOK = mController.activityResuming(next.packageName);
5394                    } catch (RemoteException e) {
5395                        mController = null;
5396                        Watchdog.getInstance().setActivityController(null);
5397                    }
5398
5399                    if (!resumeOK) {
5400                        Slog.i(TAG, "Not finishing activity because controller resumed");
5401                        return false;
5402                    }
5403                }
5404            }
5405            final long origId = Binder.clearCallingIdentity();
5406            try {
5407                boolean res;
5408                final boolean finishWithRootActivity =
5409                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5410                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5411                        || (finishWithRootActivity && r == rootR)) {
5412                    // If requested, remove the task that is associated to this activity only if it
5413                    // was the root activity in the task. The result code and data is ignored
5414                    // because we don't support returning them across task boundaries. Also, to
5415                    // keep backwards compatibility we remove the task from recents when finishing
5416                    // task with root activity.
5417                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5418                            finishWithRootActivity, "finish-activity");
5419                    if (!res) {
5420                        Slog.i(TAG, "Removing task failed to finish activity");
5421                    }
5422                } else {
5423                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5424                            resultData, "app-request", true);
5425                    if (!res) {
5426                        Slog.i(TAG, "Failed to finish by app-request");
5427                    }
5428                }
5429                return res;
5430            } finally {
5431                Binder.restoreCallingIdentity(origId);
5432            }
5433        }
5434    }
5435
5436    @Override
5437    public final void finishHeavyWeightApp() {
5438        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5439                != PackageManager.PERMISSION_GRANTED) {
5440            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5441                    + Binder.getCallingPid()
5442                    + ", uid=" + Binder.getCallingUid()
5443                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5444            Slog.w(TAG, msg);
5445            throw new SecurityException(msg);
5446        }
5447
5448        synchronized(this) {
5449            final ProcessRecord proc = mHeavyWeightProcess;
5450            if (proc == null) {
5451                return;
5452            }
5453
5454            ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5455            for (int i = 0; i < activities.size(); i++) {
5456                ActivityRecord r = activities.get(i);
5457                if (!r.finishing && r.isInStackLocked()) {
5458                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5459                            null, "finish-heavy", true);
5460                }
5461            }
5462
5463            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5464                    proc.userId, 0));
5465            mHeavyWeightProcess = null;
5466        }
5467    }
5468
5469    @Override
5470    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5471            String message) {
5472        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5473                != PackageManager.PERMISSION_GRANTED) {
5474            String msg = "Permission Denial: crashApplication() from pid="
5475                    + Binder.getCallingPid()
5476                    + ", uid=" + Binder.getCallingUid()
5477                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5478            Slog.w(TAG, msg);
5479            throw new SecurityException(msg);
5480        }
5481
5482        synchronized(this) {
5483            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5484        }
5485    }
5486
5487    @Override
5488    public final void finishSubActivity(IBinder token, String resultWho,
5489            int requestCode) {
5490        synchronized(this) {
5491            final long origId = Binder.clearCallingIdentity();
5492            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5493            if (r != null) {
5494                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5495            }
5496            Binder.restoreCallingIdentity(origId);
5497        }
5498    }
5499
5500    @Override
5501    public boolean finishActivityAffinity(IBinder token) {
5502        synchronized(this) {
5503            final long origId = Binder.clearCallingIdentity();
5504            try {
5505                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5506                if (r == null) {
5507                    return false;
5508                }
5509
5510                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5511                // can finish.
5512                final TaskRecord task = r.getTask();
5513                if (mLockTaskController.activityBlockedFromFinish(r)) {
5514                    return false;
5515                }
5516                return task.getStack().finishActivityAffinityLocked(r);
5517            } finally {
5518                Binder.restoreCallingIdentity(origId);
5519            }
5520        }
5521    }
5522
5523    @Override
5524    public void finishVoiceTask(IVoiceInteractionSession session) {
5525        synchronized (this) {
5526            final long origId = Binder.clearCallingIdentity();
5527            try {
5528                // TODO: VI Consider treating local voice interactions and voice tasks
5529                // differently here
5530                mStackSupervisor.finishVoiceTask(session);
5531            } finally {
5532                Binder.restoreCallingIdentity(origId);
5533            }
5534        }
5535
5536    }
5537
5538    @Override
5539    public boolean releaseActivityInstance(IBinder token) {
5540        synchronized(this) {
5541            final long origId = Binder.clearCallingIdentity();
5542            try {
5543                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5544                if (r == null) {
5545                    return false;
5546                }
5547                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5548            } finally {
5549                Binder.restoreCallingIdentity(origId);
5550            }
5551        }
5552    }
5553
5554    @Override
5555    public void releaseSomeActivities(IApplicationThread appInt) {
5556        synchronized(this) {
5557            final long origId = Binder.clearCallingIdentity();
5558            try {
5559                ProcessRecord app = getRecordForAppLocked(appInt);
5560                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5561            } finally {
5562                Binder.restoreCallingIdentity(origId);
5563            }
5564        }
5565    }
5566
5567    @Override
5568    public boolean willActivityBeVisible(IBinder token) {
5569        synchronized(this) {
5570            ActivityStack stack = ActivityRecord.getStackLocked(token);
5571            if (stack != null) {
5572                return stack.willActivityBeVisibleLocked(token);
5573            }
5574            return false;
5575        }
5576    }
5577
5578    @Override
5579    public void overridePendingTransition(IBinder token, String packageName,
5580            int enterAnim, int exitAnim) {
5581        synchronized(this) {
5582            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5583            if (self == null) {
5584                return;
5585            }
5586
5587            final long origId = Binder.clearCallingIdentity();
5588
5589            if (self.state == ActivityState.RESUMED
5590                    || self.state == ActivityState.PAUSING) {
5591                mWindowManager.overridePendingAppTransition(packageName,
5592                        enterAnim, exitAnim, null);
5593            }
5594
5595            Binder.restoreCallingIdentity(origId);
5596        }
5597    }
5598
5599    /**
5600     * Main function for removing an existing process from the activity manager
5601     * as a result of that process going away.  Clears out all connections
5602     * to the process.
5603     */
5604    private final void handleAppDiedLocked(ProcessRecord app,
5605            boolean restarting, boolean allowRestart) {
5606        int pid = app.pid;
5607        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5608                false /*replacingPid*/);
5609        if (!kept && !restarting) {
5610            removeLruProcessLocked(app);
5611            if (pid > 0) {
5612                ProcessList.remove(pid);
5613            }
5614        }
5615
5616        if (mProfileProc == app) {
5617            clearProfilerLocked();
5618        }
5619
5620        // Remove this application's activities from active lists.
5621        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5622
5623        app.clearRecentTasks();
5624
5625        app.activities.clear();
5626
5627        if (app.instr != null) {
5628            Slog.w(TAG, "Crash of app " + app.processName
5629                  + " running instrumentation " + app.instr.mClass);
5630            Bundle info = new Bundle();
5631            info.putString("shortMsg", "Process crashed.");
5632            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5633        }
5634
5635        mWindowManager.deferSurfaceLayout();
5636        try {
5637            if (!restarting && hasVisibleActivities
5638                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5639                // If there was nothing to resume, and we are not already restarting this process, but
5640                // there is a visible activity that is hosted by the process...  then make sure all
5641                // visible activities are running, taking care of restarting this process.
5642                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5643            }
5644        } finally {
5645            mWindowManager.continueSurfaceLayout();
5646        }
5647    }
5648
5649    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5650        final IBinder threadBinder = thread.asBinder();
5651        // Find the application record.
5652        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5653            final ProcessRecord rec = mLruProcesses.get(i);
5654            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5655                return i;
5656            }
5657        }
5658        return -1;
5659    }
5660
5661    ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5662        if (thread == null) {
5663            return null;
5664        }
5665
5666        int appIndex = getLRURecordIndexForAppLocked(thread);
5667        if (appIndex >= 0) {
5668            return mLruProcesses.get(appIndex);
5669        }
5670
5671        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5672        // double-check that.
5673        final IBinder threadBinder = thread.asBinder();
5674        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5675        for (int i = pmap.size()-1; i >= 0; i--) {
5676            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5677            for (int j = procs.size()-1; j >= 0; j--) {
5678                final ProcessRecord proc = procs.valueAt(j);
5679                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5680                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5681                            + proc);
5682                    return proc;
5683                }
5684            }
5685        }
5686
5687        return null;
5688    }
5689
5690    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5691        // If there are no longer any background processes running,
5692        // and the app that died was not running instrumentation,
5693        // then tell everyone we are now low on memory.
5694        boolean haveBg = false;
5695        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5696            ProcessRecord rec = mLruProcesses.get(i);
5697            if (rec.thread != null
5698                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5699                haveBg = true;
5700                break;
5701            }
5702        }
5703
5704        if (!haveBg) {
5705            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5706            if (doReport) {
5707                long now = SystemClock.uptimeMillis();
5708                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5709                    doReport = false;
5710                } else {
5711                    mLastMemUsageReportTime = now;
5712                }
5713            }
5714            final ArrayList<ProcessMemInfo> memInfos
5715                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5716            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5717            long now = SystemClock.uptimeMillis();
5718            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5719                ProcessRecord rec = mLruProcesses.get(i);
5720                if (rec == dyingProc || rec.thread == null) {
5721                    continue;
5722                }
5723                if (doReport) {
5724                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5725                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5726                }
5727                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5728                    // The low memory report is overriding any current
5729                    // state for a GC request.  Make sure to do
5730                    // heavy/important/visible/foreground processes first.
5731                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5732                        rec.lastRequestedGc = 0;
5733                    } else {
5734                        rec.lastRequestedGc = rec.lastLowMemory;
5735                    }
5736                    rec.reportLowMemory = true;
5737                    rec.lastLowMemory = now;
5738                    mProcessesToGc.remove(rec);
5739                    addProcessToGcListLocked(rec);
5740                }
5741            }
5742            if (doReport) {
5743                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5744                mHandler.sendMessage(msg);
5745            }
5746            scheduleAppGcsLocked();
5747        }
5748    }
5749
5750    final void appDiedLocked(ProcessRecord app) {
5751       appDiedLocked(app, app.pid, app.thread, false);
5752    }
5753
5754    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5755            boolean fromBinderDied) {
5756        // First check if this ProcessRecord is actually active for the pid.
5757        synchronized (mPidsSelfLocked) {
5758            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5759            if (curProc != app) {
5760                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5761                return;
5762            }
5763        }
5764
5765        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5766        synchronized (stats) {
5767            stats.noteProcessDiedLocked(app.info.uid, pid);
5768        }
5769
5770        if (!app.killed) {
5771            if (!fromBinderDied) {
5772                killProcessQuiet(pid);
5773            }
5774            killProcessGroup(app.uid, pid);
5775            app.killed = true;
5776        }
5777
5778        // Clean up already done if the process has been re-started.
5779        if (app.pid == pid && app.thread != null &&
5780                app.thread.asBinder() == thread.asBinder()) {
5781            boolean doLowMem = app.instr == null;
5782            boolean doOomAdj = doLowMem;
5783            if (!app.killedByAm) {
5784                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5785                        + ProcessList.makeOomAdjString(app.setAdj)
5786                        + ProcessList.makeProcStateString(app.setProcState));
5787                mAllowLowerMemLevel = true;
5788            } else {
5789                // Note that we always want to do oom adj to update our state with the
5790                // new number of procs.
5791                mAllowLowerMemLevel = false;
5792                doLowMem = false;
5793            }
5794            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5795                    app.setAdj, app.setProcState);
5796            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5797                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5798            handleAppDiedLocked(app, false, true);
5799
5800            if (doOomAdj) {
5801                updateOomAdjLocked();
5802            }
5803            if (doLowMem) {
5804                doLowMemReportIfNeededLocked(app);
5805            }
5806        } else if (app.pid != pid) {
5807            // A new process has already been started.
5808            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5809                    + ") has died and restarted (pid " + app.pid + ").");
5810            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5811        } else if (DEBUG_PROCESSES) {
5812            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5813                    + thread.asBinder());
5814        }
5815    }
5816
5817    /**
5818     * If a stack trace dump file is configured, dump process stack traces.
5819     * @param clearTraces causes the dump file to be erased prior to the new
5820     *    traces being written, if true; when false, the new traces will be
5821     *    appended to any existing file content.
5822     * @param firstPids of dalvik VM processes to dump stack traces for first
5823     * @param lastPids of dalvik VM processes to dump stack traces for last
5824     * @param nativePids optional list of native pids to dump stack crawls
5825     */
5826    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5827            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5828            ArrayList<Integer> nativePids) {
5829        ArrayList<Integer> extraPids = null;
5830
5831        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5832        // of the top users at the time of the request.
5833        if (processCpuTracker != null) {
5834            processCpuTracker.init();
5835            try {
5836                Thread.sleep(200);
5837            } catch (InterruptedException ignored) {
5838            }
5839
5840            processCpuTracker.update();
5841
5842            // We'll take the stack crawls of just the top apps using CPU.
5843            final int N = processCpuTracker.countWorkingStats();
5844            extraPids = new ArrayList<>();
5845            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5846                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5847                if (lastPids.indexOfKey(stats.pid) >= 0) {
5848                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5849
5850                    extraPids.add(stats.pid);
5851                } else if (DEBUG_ANR) {
5852                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5853                            + stats.pid);
5854                }
5855            }
5856        }
5857
5858        boolean useTombstonedForJavaTraces = false;
5859        File tracesFile;
5860
5861        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5862        if (tracesDirProp.isEmpty()) {
5863            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5864            // dumping scheme. All traces are written to a global trace file (usually
5865            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5866            // the file if requested.
5867            //
5868            // This mode of operation will be removed in the near future.
5869
5870
5871            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5872            if (globalTracesPath.isEmpty()) {
5873                Slog.w(TAG, "dumpStackTraces: no trace path configured");
5874                return null;
5875            }
5876
5877            tracesFile = new File(globalTracesPath);
5878            try {
5879                if (clearTraces && tracesFile.exists()) {
5880                    tracesFile.delete();
5881                }
5882
5883                tracesFile.createNewFile();
5884                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5885            } catch (IOException e) {
5886                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5887                return null;
5888            }
5889        } else {
5890            File tracesDir = new File(tracesDirProp);
5891            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5892            // Each set of ANR traces is written to a separate file and dumpstate will process
5893            // all such files and add them to a captured bug report if they're recent enough.
5894            maybePruneOldTraces(tracesDir);
5895
5896            // NOTE: We should consider creating the file in native code atomically once we've
5897            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5898            // can be removed.
5899            tracesFile = createAnrDumpFile(tracesDir);
5900            if (tracesFile == null) {
5901                return null;
5902            }
5903
5904            useTombstonedForJavaTraces = true;
5905        }
5906
5907        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5908                useTombstonedForJavaTraces);
5909        return tracesFile;
5910    }
5911
5912    @GuardedBy("ActivityManagerService.class")
5913    private static SimpleDateFormat sAnrFileDateFormat;
5914
5915    private static synchronized File createAnrDumpFile(File tracesDir) {
5916        if (sAnrFileDateFormat == null) {
5917            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5918        }
5919
5920        final String formattedDate = sAnrFileDateFormat.format(new Date());
5921        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5922
5923        try {
5924            if (anrFile.createNewFile()) {
5925                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5926                return anrFile;
5927            } else {
5928                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5929            }
5930        } catch (IOException ioe) {
5931            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5932        }
5933
5934        return null;
5935    }
5936
5937    /**
5938     * Prune all trace files that are more than a day old.
5939     *
5940     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5941     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5942     * since it's the system_server that creates trace files for most ANRs.
5943     */
5944    private static void maybePruneOldTraces(File tracesDir) {
5945        final long now = System.currentTimeMillis();
5946        final File[] traceFiles = tracesDir.listFiles();
5947
5948        if (traceFiles != null) {
5949            for (File file : traceFiles) {
5950                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5951                    if (!file.delete()) {
5952                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
5953                    }
5954                }
5955            }
5956        }
5957    }
5958
5959    /**
5960     * Legacy code, do not use. Existing users will be deleted.
5961     *
5962     * @deprecated
5963     */
5964    @Deprecated
5965    public static class DumpStackFileObserver extends FileObserver {
5966        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5967        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5968
5969        private final String mTracesPath;
5970        private boolean mClosed;
5971
5972        public DumpStackFileObserver(String tracesPath) {
5973            super(tracesPath, FileObserver.CLOSE_WRITE);
5974            mTracesPath = tracesPath;
5975        }
5976
5977        @Override
5978        public synchronized void onEvent(int event, String path) {
5979            mClosed = true;
5980            notify();
5981        }
5982
5983        public long dumpWithTimeout(int pid, long timeout) {
5984            sendSignal(pid, SIGNAL_QUIT);
5985            final long start = SystemClock.elapsedRealtime();
5986
5987            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5988            synchronized (this) {
5989                try {
5990                    wait(waitTime); // Wait for traces file to be closed.
5991                } catch (InterruptedException e) {
5992                    Slog.wtf(TAG, e);
5993                }
5994            }
5995
5996            // This avoids a corner case of passing a negative time to the native
5997            // trace in case we've already hit the overall timeout.
5998            final long timeWaited = SystemClock.elapsedRealtime() - start;
5999            if (timeWaited >= timeout) {
6000                return timeWaited;
6001            }
6002
6003            if (!mClosed) {
6004                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
6005                       ". Attempting native stack collection.");
6006
6007                final long nativeDumpTimeoutMs = Math.min(
6008                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
6009
6010                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
6011                        (int) (nativeDumpTimeoutMs / 1000));
6012            }
6013
6014            final long end = SystemClock.elapsedRealtime();
6015            mClosed = false;
6016
6017            return (end - start);
6018        }
6019    }
6020
6021    /**
6022     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
6023     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
6024     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
6025     * attempting to obtain native traces in the case of a failure. Returns the total time spent
6026     * capturing traces.
6027     */
6028    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
6029        final long timeStart = SystemClock.elapsedRealtime();
6030        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
6031            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
6032                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
6033        }
6034
6035        return SystemClock.elapsedRealtime() - timeStart;
6036    }
6037
6038    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6039            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6040            boolean useTombstonedForJavaTraces) {
6041
6042        // We don't need any sort of inotify based monitoring when we're dumping traces via
6043        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
6044        // control of all writes to the file in question.
6045        final DumpStackFileObserver observer;
6046        if (useTombstonedForJavaTraces) {
6047            observer = null;
6048        } else {
6049            // Use a FileObserver to detect when traces finish writing.
6050            // The order of traces is considered important to maintain for legibility.
6051            observer = new DumpStackFileObserver(tracesFile);
6052        }
6053
6054        // We must complete all stack dumps within 20 seconds.
6055        long remainingTime = 20 * 1000;
6056        try {
6057            if (observer != null) {
6058                observer.startWatching();
6059            }
6060
6061            // First collect all of the stacks of the most important pids.
6062            if (firstPids != null) {
6063                int num = firstPids.size();
6064                for (int i = 0; i < num; i++) {
6065                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
6066                            + firstPids.get(i));
6067                    final long timeTaken;
6068                    if (useTombstonedForJavaTraces) {
6069                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
6070                    } else {
6071                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6072                    }
6073
6074                    remainingTime -= timeTaken;
6075                    if (remainingTime <= 0) {
6076                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6077                            "); deadline exceeded.");
6078                        return;
6079                    }
6080
6081                    if (DEBUG_ANR) {
6082                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
6083                    }
6084                }
6085            }
6086
6087            // Next collect the stacks of the native pids
6088            if (nativePids != null) {
6089                for (int pid : nativePids) {
6090                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
6091                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
6092
6093                    final long start = SystemClock.elapsedRealtime();
6094                    Debug.dumpNativeBacktraceToFileTimeout(
6095                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6096                    final long timeTaken = SystemClock.elapsedRealtime() - start;
6097
6098                    remainingTime -= timeTaken;
6099                    if (remainingTime <= 0) {
6100                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6101                            "); deadline exceeded.");
6102                        return;
6103                    }
6104
6105                    if (DEBUG_ANR) {
6106                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
6107                    }
6108                }
6109            }
6110
6111            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
6112            if (extraPids != null) {
6113                for (int pid : extraPids) {
6114                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6115
6116                    final long timeTaken;
6117                    if (useTombstonedForJavaTraces) {
6118                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6119                    } else {
6120                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6121                    }
6122
6123                    remainingTime -= timeTaken;
6124                    if (remainingTime <= 0) {
6125                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6126                                "); deadline exceeded.");
6127                        return;
6128                    }
6129
6130                    if (DEBUG_ANR) {
6131                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6132                    }
6133                }
6134            }
6135        } finally {
6136            if (observer != null) {
6137                observer.stopWatching();
6138            }
6139        }
6140    }
6141
6142    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6143        if (true || Build.IS_USER) {
6144            return;
6145        }
6146        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6147        if (tracesPath == null || tracesPath.length() == 0) {
6148            return;
6149        }
6150
6151        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6152        StrictMode.allowThreadDiskWrites();
6153        try {
6154            final File tracesFile = new File(tracesPath);
6155            final File tracesDir = tracesFile.getParentFile();
6156            final File tracesTmp = new File(tracesDir, "__tmp__");
6157            try {
6158                if (tracesFile.exists()) {
6159                    tracesTmp.delete();
6160                    tracesFile.renameTo(tracesTmp);
6161                }
6162                StringBuilder sb = new StringBuilder();
6163                Time tobj = new Time();
6164                tobj.set(System.currentTimeMillis());
6165                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6166                sb.append(": ");
6167                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6168                sb.append(" since ");
6169                sb.append(msg);
6170                FileOutputStream fos = new FileOutputStream(tracesFile);
6171                fos.write(sb.toString().getBytes());
6172                if (app == null) {
6173                    fos.write("\n*** No application process!".getBytes());
6174                }
6175                fos.close();
6176                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6177            } catch (IOException e) {
6178                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6179                return;
6180            }
6181
6182            if (app != null && app.pid > 0) {
6183                ArrayList<Integer> firstPids = new ArrayList<Integer>();
6184                firstPids.add(app.pid);
6185                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6186            }
6187
6188            File lastTracesFile = null;
6189            File curTracesFile = null;
6190            for (int i=9; i>=0; i--) {
6191                String name = String.format(Locale.US, "slow%02d.txt", i);
6192                curTracesFile = new File(tracesDir, name);
6193                if (curTracesFile.exists()) {
6194                    if (lastTracesFile != null) {
6195                        curTracesFile.renameTo(lastTracesFile);
6196                    } else {
6197                        curTracesFile.delete();
6198                    }
6199                }
6200                lastTracesFile = curTracesFile;
6201            }
6202            tracesFile.renameTo(curTracesFile);
6203            if (tracesTmp.exists()) {
6204                tracesTmp.renameTo(tracesFile);
6205            }
6206        } finally {
6207            StrictMode.setThreadPolicy(oldPolicy);
6208        }
6209    }
6210
6211    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6212        if (!mLaunchWarningShown) {
6213            mLaunchWarningShown = true;
6214            mUiHandler.post(new Runnable() {
6215                @Override
6216                public void run() {
6217                    synchronized (ActivityManagerService.this) {
6218                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6219                        d.show();
6220                        mUiHandler.postDelayed(new Runnable() {
6221                            @Override
6222                            public void run() {
6223                                synchronized (ActivityManagerService.this) {
6224                                    d.dismiss();
6225                                    mLaunchWarningShown = false;
6226                                }
6227                            }
6228                        }, 4000);
6229                    }
6230                }
6231            });
6232        }
6233    }
6234
6235    @Override
6236    public boolean clearApplicationUserData(final String packageName, boolean keepState,
6237            final IPackageDataObserver observer, int userId) {
6238        enforceNotIsolatedCaller("clearApplicationUserData");
6239        int uid = Binder.getCallingUid();
6240        int pid = Binder.getCallingPid();
6241        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6242                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6243
6244        final ApplicationInfo appInfo;
6245        final boolean isInstantApp;
6246
6247        long callingId = Binder.clearCallingIdentity();
6248        try {
6249            IPackageManager pm = AppGlobals.getPackageManager();
6250            synchronized(this) {
6251                // Instant packages are not protected
6252                if (getPackageManagerInternalLocked().isPackageDataProtected(
6253                        resolvedUserId, packageName)) {
6254                    throw new SecurityException(
6255                            "Cannot clear data for a protected package: " + packageName);
6256                }
6257
6258                ApplicationInfo applicationInfo = null;
6259                try {
6260                    applicationInfo = pm.getApplicationInfo(packageName,
6261                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6262                } catch (RemoteException e) {
6263                    /* ignore */
6264                }
6265                appInfo = applicationInfo;
6266
6267                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6268
6269                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6270                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6271                    throw new SecurityException("PID " + pid + " does not have permission "
6272                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6273                            + " of package " + packageName);
6274                }
6275
6276                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6277                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
6278                final boolean isUninstalledAppWithoutInstantMetadata =
6279                        (appInfo == null && !hasInstantMetadata);
6280                isInstantApp = (appInfo != null && appInfo.isInstantApp())
6281                        || hasInstantMetadata;
6282                final boolean canAccessInstantApps = checkComponentPermission(
6283                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6284                        == PackageManager.PERMISSION_GRANTED;
6285
6286                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6287                        && !canAccessInstantApps)) {
6288                    Slog.w(TAG, "Invalid packageName: " + packageName);
6289                    if (observer != null) {
6290                        try {
6291                            observer.onRemoveCompleted(packageName, false);
6292                        } catch (RemoteException e) {
6293                            Slog.i(TAG, "Observer no longer exists.");
6294                        }
6295                    }
6296                    return false;
6297                }
6298
6299                if (appInfo != null) {
6300                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6301                    mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6302                }
6303            }
6304
6305            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6306                @Override
6307                public void onRemoveCompleted(String packageName, boolean succeeded)
6308                        throws RemoteException {
6309                    if (appInfo != null) {
6310                        synchronized (ActivityManagerService.this) {
6311                            finishForceStopPackageLocked(packageName, appInfo.uid);
6312                        }
6313                    }
6314                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6315                            Uri.fromParts("package", packageName, null));
6316                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6317                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6318                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6319                    if (isInstantApp) {
6320                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6321                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6322                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6323                                resolvedUserId);
6324                    } else {
6325                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6326                                null, null, null, null, false, false, resolvedUserId);
6327                    }
6328
6329                    if (observer != null) {
6330                        observer.onRemoveCompleted(packageName, succeeded);
6331                    }
6332                }
6333            };
6334
6335            try {
6336                // Clear application user data
6337                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6338
6339                if (appInfo != null) {
6340                    // Restore already established notification state and permission grants,
6341                    // so it told us to keep those intact -- it's about to emplace app data
6342                    // that is appropriate for those bits of system state.
6343                    if (!keepState) {
6344                        synchronized (this) {
6345                            // Remove all permissions granted from/to this package
6346                            removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
6347                                    false);
6348                        }
6349
6350                        // Reset notification state
6351                        INotificationManager inm = NotificationManager.getService();
6352                        inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6353                    }
6354
6355                    // Clear its scheduled jobs
6356                    JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6357                    js.cancelJobsForUid(appInfo.uid, "clear data");
6358
6359                    // Clear its pending alarms
6360                    AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6361                    ami.removeAlarmsForUid(appInfo.uid);
6362                }
6363            } catch (RemoteException e) {
6364            }
6365        } finally {
6366            Binder.restoreCallingIdentity(callingId);
6367        }
6368        return true;
6369    }
6370
6371    @Override
6372    public void killBackgroundProcesses(final String packageName, int userId) {
6373        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6374                != PackageManager.PERMISSION_GRANTED &&
6375                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6376                        != PackageManager.PERMISSION_GRANTED) {
6377            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6378                    + Binder.getCallingPid()
6379                    + ", uid=" + Binder.getCallingUid()
6380                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6381            Slog.w(TAG, msg);
6382            throw new SecurityException(msg);
6383        }
6384
6385        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6386                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6387        long callingId = Binder.clearCallingIdentity();
6388        try {
6389            IPackageManager pm = AppGlobals.getPackageManager();
6390            synchronized(this) {
6391                int appId = -1;
6392                try {
6393                    appId = UserHandle.getAppId(
6394                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6395                } catch (RemoteException e) {
6396                }
6397                if (appId == -1) {
6398                    Slog.w(TAG, "Invalid packageName: " + packageName);
6399                    return;
6400                }
6401                killPackageProcessesLocked(packageName, appId, userId,
6402                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6403            }
6404        } finally {
6405            Binder.restoreCallingIdentity(callingId);
6406        }
6407    }
6408
6409    @Override
6410    public void killAllBackgroundProcesses() {
6411        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6412                != PackageManager.PERMISSION_GRANTED) {
6413            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6414                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6415                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6416            Slog.w(TAG, msg);
6417            throw new SecurityException(msg);
6418        }
6419
6420        final long callingId = Binder.clearCallingIdentity();
6421        try {
6422            synchronized (this) {
6423                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6424                final int NP = mProcessNames.getMap().size();
6425                for (int ip = 0; ip < NP; ip++) {
6426                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6427                    final int NA = apps.size();
6428                    for (int ia = 0; ia < NA; ia++) {
6429                        final ProcessRecord app = apps.valueAt(ia);
6430                        if (app.persistent) {
6431                            // We don't kill persistent processes.
6432                            continue;
6433                        }
6434                        if (app.removed) {
6435                            procs.add(app);
6436                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6437                            app.removed = true;
6438                            procs.add(app);
6439                        }
6440                    }
6441                }
6442
6443                final int N = procs.size();
6444                for (int i = 0; i < N; i++) {
6445                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6446                }
6447
6448                mAllowLowerMemLevel = true;
6449
6450                updateOomAdjLocked();
6451                doLowMemReportIfNeededLocked(null);
6452            }
6453        } finally {
6454            Binder.restoreCallingIdentity(callingId);
6455        }
6456    }
6457
6458    /**
6459     * Kills all background processes, except those matching any of the
6460     * specified properties.
6461     *
6462     * @param minTargetSdk the target SDK version at or above which to preserve
6463     *                     processes, or {@code -1} to ignore the target SDK
6464     * @param maxProcState the process state at or below which to preserve
6465     *                     processes, or {@code -1} to ignore the process state
6466     */
6467    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6468        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6469                != PackageManager.PERMISSION_GRANTED) {
6470            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6471                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6472                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6473            Slog.w(TAG, msg);
6474            throw new SecurityException(msg);
6475        }
6476
6477        final long callingId = Binder.clearCallingIdentity();
6478        try {
6479            synchronized (this) {
6480                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6481                final int NP = mProcessNames.getMap().size();
6482                for (int ip = 0; ip < NP; ip++) {
6483                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6484                    final int NA = apps.size();
6485                    for (int ia = 0; ia < NA; ia++) {
6486                        final ProcessRecord app = apps.valueAt(ia);
6487                        if (app.removed) {
6488                            procs.add(app);
6489                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6490                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6491                            app.removed = true;
6492                            procs.add(app);
6493                        }
6494                    }
6495                }
6496
6497                final int N = procs.size();
6498                for (int i = 0; i < N; i++) {
6499                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6500                }
6501            }
6502        } finally {
6503            Binder.restoreCallingIdentity(callingId);
6504        }
6505    }
6506
6507    @Override
6508    public void forceStopPackage(final String packageName, int userId) {
6509        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6510                != PackageManager.PERMISSION_GRANTED) {
6511            String msg = "Permission Denial: forceStopPackage() from pid="
6512                    + Binder.getCallingPid()
6513                    + ", uid=" + Binder.getCallingUid()
6514                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6515            Slog.w(TAG, msg);
6516            throw new SecurityException(msg);
6517        }
6518        final int callingPid = Binder.getCallingPid();
6519        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6520                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6521        long callingId = Binder.clearCallingIdentity();
6522        try {
6523            IPackageManager pm = AppGlobals.getPackageManager();
6524            synchronized(this) {
6525                int[] users = userId == UserHandle.USER_ALL
6526                        ? mUserController.getUsers() : new int[] { userId };
6527                for (int user : users) {
6528                    int pkgUid = -1;
6529                    try {
6530                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6531                                user);
6532                    } catch (RemoteException e) {
6533                    }
6534                    if (pkgUid == -1) {
6535                        Slog.w(TAG, "Invalid packageName: " + packageName);
6536                        continue;
6537                    }
6538                    try {
6539                        pm.setPackageStoppedState(packageName, true, user);
6540                    } catch (RemoteException e) {
6541                    } catch (IllegalArgumentException e) {
6542                        Slog.w(TAG, "Failed trying to unstop package "
6543                                + packageName + ": " + e);
6544                    }
6545                    if (mUserController.isUserRunning(user, 0)) {
6546                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6547                        finishForceStopPackageLocked(packageName, pkgUid);
6548                    }
6549                }
6550            }
6551        } finally {
6552            Binder.restoreCallingIdentity(callingId);
6553        }
6554    }
6555
6556    @Override
6557    public void addPackageDependency(String packageName) {
6558        synchronized (this) {
6559            int callingPid = Binder.getCallingPid();
6560            if (callingPid == myPid()) {
6561                //  Yeah, um, no.
6562                return;
6563            }
6564            ProcessRecord proc;
6565            synchronized (mPidsSelfLocked) {
6566                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6567            }
6568            if (proc != null) {
6569                if (proc.pkgDeps == null) {
6570                    proc.pkgDeps = new ArraySet<String>(1);
6571                }
6572                proc.pkgDeps.add(packageName);
6573            }
6574        }
6575    }
6576
6577    /*
6578     * The pkg name and app id have to be specified.
6579     */
6580    @Override
6581    public void killApplication(String pkg, int appId, int userId, String reason) {
6582        if (pkg == null) {
6583            return;
6584        }
6585        // Make sure the uid is valid.
6586        if (appId < 0) {
6587            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6588            return;
6589        }
6590        int callerUid = Binder.getCallingUid();
6591        // Only the system server can kill an application
6592        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6593            // Post an aysnc message to kill the application
6594            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6595            msg.arg1 = appId;
6596            msg.arg2 = userId;
6597            Bundle bundle = new Bundle();
6598            bundle.putString("pkg", pkg);
6599            bundle.putString("reason", reason);
6600            msg.obj = bundle;
6601            mHandler.sendMessage(msg);
6602        } else {
6603            throw new SecurityException(callerUid + " cannot kill pkg: " +
6604                    pkg);
6605        }
6606    }
6607
6608    @Override
6609    public void closeSystemDialogs(String reason) {
6610        enforceNotIsolatedCaller("closeSystemDialogs");
6611
6612        final int pid = Binder.getCallingPid();
6613        final int uid = Binder.getCallingUid();
6614        final long origId = Binder.clearCallingIdentity();
6615        try {
6616            synchronized (this) {
6617                // Only allow this from foreground processes, so that background
6618                // applications can't abuse it to prevent system UI from being shown.
6619                if (uid >= FIRST_APPLICATION_UID) {
6620                    ProcessRecord proc;
6621                    synchronized (mPidsSelfLocked) {
6622                        proc = mPidsSelfLocked.get(pid);
6623                    }
6624                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6625                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6626                                + " from background process " + proc);
6627                        return;
6628                    }
6629                }
6630                closeSystemDialogsLocked(reason);
6631            }
6632        } finally {
6633            Binder.restoreCallingIdentity(origId);
6634        }
6635    }
6636
6637    void closeSystemDialogsLocked(String reason) {
6638        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6639        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6640                | Intent.FLAG_RECEIVER_FOREGROUND);
6641        if (reason != null) {
6642            intent.putExtra("reason", reason);
6643        }
6644        mWindowManager.closeSystemDialogs(reason);
6645
6646        mStackSupervisor.closeSystemDialogsLocked();
6647
6648        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6649                OP_NONE, null, false, false,
6650                -1, SYSTEM_UID, UserHandle.USER_ALL);
6651    }
6652
6653    @Override
6654    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6655        enforceNotIsolatedCaller("getProcessMemoryInfo");
6656        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6657        for (int i=pids.length-1; i>=0; i--) {
6658            ProcessRecord proc;
6659            int oomAdj;
6660            synchronized (this) {
6661                synchronized (mPidsSelfLocked) {
6662                    proc = mPidsSelfLocked.get(pids[i]);
6663                    oomAdj = proc != null ? proc.setAdj : 0;
6664                }
6665            }
6666            infos[i] = new Debug.MemoryInfo();
6667            long startTime = SystemClock.currentThreadTimeMillis();
6668            Debug.getMemoryInfo(pids[i], infos[i]);
6669            long endTime = SystemClock.currentThreadTimeMillis();
6670            if (proc != null) {
6671                synchronized (this) {
6672                    if (proc.thread != null && proc.setAdj == oomAdj) {
6673                        // Record this for posterity if the process has been stable.
6674                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6675                                infos[i].getTotalUss(), infos[i].getTotalRss(), false,
6676                                ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
6677                                proc.pkgList);
6678                    }
6679                }
6680            }
6681        }
6682        return infos;
6683    }
6684
6685    @Override
6686    public long[] getProcessPss(int[] pids) {
6687        enforceNotIsolatedCaller("getProcessPss");
6688        long[] pss = new long[pids.length];
6689        for (int i=pids.length-1; i>=0; i--) {
6690            ProcessRecord proc;
6691            int oomAdj;
6692            synchronized (this) {
6693                synchronized (mPidsSelfLocked) {
6694                    proc = mPidsSelfLocked.get(pids[i]);
6695                    oomAdj = proc != null ? proc.setAdj : 0;
6696                }
6697            }
6698            long[] tmpUss = new long[3];
6699            long startTime = SystemClock.currentThreadTimeMillis();
6700            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6701            long endTime = SystemClock.currentThreadTimeMillis();
6702            if (proc != null) {
6703                synchronized (this) {
6704                    if (proc.thread != null && proc.setAdj == oomAdj) {
6705                        // Record this for posterity if the process has been stable.
6706                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
6707                                ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
6708                    }
6709                }
6710            }
6711        }
6712        return pss;
6713    }
6714
6715    @Override
6716    public void killApplicationProcess(String processName, int uid) {
6717        if (processName == null) {
6718            return;
6719        }
6720
6721        int callerUid = Binder.getCallingUid();
6722        // Only the system server can kill an application
6723        if (callerUid == SYSTEM_UID) {
6724            synchronized (this) {
6725                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6726                if (app != null && app.thread != null) {
6727                    try {
6728                        app.thread.scheduleSuicide();
6729                    } catch (RemoteException e) {
6730                        // If the other end already died, then our work here is done.
6731                    }
6732                } else {
6733                    Slog.w(TAG, "Process/uid not found attempting kill of "
6734                            + processName + " / " + uid);
6735                }
6736            }
6737        } else {
6738            throw new SecurityException(callerUid + " cannot kill app process: " +
6739                    processName);
6740        }
6741    }
6742
6743    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6744        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6745                false, true, false, false, UserHandle.getUserId(uid), reason);
6746    }
6747
6748    private void finishForceStopPackageLocked(final String packageName, int uid) {
6749        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6750                Uri.fromParts("package", packageName, null));
6751        if (!mProcessesReady) {
6752            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6753                    | Intent.FLAG_RECEIVER_FOREGROUND);
6754        }
6755        intent.putExtra(Intent.EXTRA_UID, uid);
6756        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6757        broadcastIntentLocked(null, null, intent,
6758                null, null, 0, null, null, null, OP_NONE,
6759                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6760    }
6761
6762
6763    private final boolean killPackageProcessesLocked(String packageName, int appId,
6764            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6765            boolean doit, boolean evenPersistent, String reason) {
6766        ArrayList<ProcessRecord> procs = new ArrayList<>();
6767
6768        // Remove all processes this package may have touched: all with the
6769        // same UID (except for the system or root user), and all whose name
6770        // matches the package name.
6771        final int NP = mProcessNames.getMap().size();
6772        for (int ip=0; ip<NP; ip++) {
6773            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6774            final int NA = apps.size();
6775            for (int ia=0; ia<NA; ia++) {
6776                ProcessRecord app = apps.valueAt(ia);
6777                if (app.persistent && !evenPersistent) {
6778                    // we don't kill persistent processes
6779                    continue;
6780                }
6781                if (app.removed) {
6782                    if (doit) {
6783                        procs.add(app);
6784                    }
6785                    continue;
6786                }
6787
6788                // Skip process if it doesn't meet our oom adj requirement.
6789                if (app.setAdj < minOomAdj) {
6790                    continue;
6791                }
6792
6793                // If no package is specified, we call all processes under the
6794                // give user id.
6795                if (packageName == null) {
6796                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6797                        continue;
6798                    }
6799                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6800                        continue;
6801                    }
6802                // Package has been specified, we want to hit all processes
6803                // that match it.  We need to qualify this by the processes
6804                // that are running under the specified app and user ID.
6805                } else {
6806                    final boolean isDep = app.pkgDeps != null
6807                            && app.pkgDeps.contains(packageName);
6808                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6809                        continue;
6810                    }
6811                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6812                        continue;
6813                    }
6814                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6815                        continue;
6816                    }
6817                }
6818
6819                // Process has passed all conditions, kill it!
6820                if (!doit) {
6821                    return true;
6822                }
6823                app.removed = true;
6824                procs.add(app);
6825            }
6826        }
6827
6828        int N = procs.size();
6829        for (int i=0; i<N; i++) {
6830            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6831        }
6832        updateOomAdjLocked();
6833        return N > 0;
6834    }
6835
6836    private void cleanupDisabledPackageComponentsLocked(
6837            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6838
6839        Set<String> disabledClasses = null;
6840        boolean packageDisabled = false;
6841        IPackageManager pm = AppGlobals.getPackageManager();
6842
6843        if (changedClasses == null) {
6844            // Nothing changed...
6845            return;
6846        }
6847
6848        // Determine enable/disable state of the package and its components.
6849        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6850        for (int i = changedClasses.length - 1; i >= 0; i--) {
6851            final String changedClass = changedClasses[i];
6852
6853            if (changedClass.equals(packageName)) {
6854                try {
6855                    // Entire package setting changed
6856                    enabled = pm.getApplicationEnabledSetting(packageName,
6857                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6858                } catch (Exception e) {
6859                    // No such package/component; probably racing with uninstall.  In any
6860                    // event it means we have nothing further to do here.
6861                    return;
6862                }
6863                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6864                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6865                if (packageDisabled) {
6866                    // Entire package is disabled.
6867                    // No need to continue to check component states.
6868                    disabledClasses = null;
6869                    break;
6870                }
6871            } else {
6872                try {
6873                    enabled = pm.getComponentEnabledSetting(
6874                            new ComponentName(packageName, changedClass),
6875                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6876                } catch (Exception e) {
6877                    // As above, probably racing with uninstall.
6878                    return;
6879                }
6880                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6881                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6882                    if (disabledClasses == null) {
6883                        disabledClasses = new ArraySet<>(changedClasses.length);
6884                    }
6885                    disabledClasses.add(changedClass);
6886                }
6887            }
6888        }
6889
6890        if (!packageDisabled && disabledClasses == null) {
6891            // Nothing to do here...
6892            return;
6893        }
6894
6895        // Clean-up disabled activities.
6896        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6897                packageName, disabledClasses, true, false, userId) && mBooted) {
6898            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6899            mStackSupervisor.scheduleIdleLocked();
6900        }
6901
6902        // Clean-up disabled tasks
6903        mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6904
6905        // Clean-up disabled services.
6906        mServices.bringDownDisabledPackageServicesLocked(
6907                packageName, disabledClasses, userId, false, killProcess, true);
6908
6909        // Clean-up disabled providers.
6910        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6911        mProviderMap.collectPackageProvidersLocked(
6912                packageName, disabledClasses, true, false, userId, providers);
6913        for (int i = providers.size() - 1; i >= 0; i--) {
6914            removeDyingProviderLocked(null, providers.get(i), true);
6915        }
6916
6917        // Clean-up disabled broadcast receivers.
6918        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6919            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6920                    packageName, disabledClasses, userId, true);
6921        }
6922
6923    }
6924
6925    final boolean clearBroadcastQueueForUserLocked(int userId) {
6926        boolean didSomething = false;
6927        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6928            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6929                    null, null, userId, true);
6930        }
6931        return didSomething;
6932    }
6933
6934    final boolean forceStopPackageLocked(String packageName, int appId,
6935            boolean callerWillRestart, boolean purgeCache, boolean doit,
6936            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6937        int i;
6938
6939        if (userId == UserHandle.USER_ALL && packageName == null) {
6940            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6941        }
6942
6943        if (appId < 0 && packageName != null) {
6944            try {
6945                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6946                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6947            } catch (RemoteException e) {
6948            }
6949        }
6950
6951        if (doit) {
6952            if (packageName != null) {
6953                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6954                        + " user=" + userId + ": " + reason);
6955            } else {
6956                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6957            }
6958
6959            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6960        }
6961
6962        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6963                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6964                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6965
6966        didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
6967
6968        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6969                packageName, null, doit, evenPersistent, userId)) {
6970            if (!doit) {
6971                return true;
6972            }
6973            didSomething = true;
6974        }
6975
6976        if (mServices.bringDownDisabledPackageServicesLocked(
6977                packageName, null, userId, evenPersistent, true, doit)) {
6978            if (!doit) {
6979                return true;
6980            }
6981            didSomething = true;
6982        }
6983
6984        if (packageName == null) {
6985            // Remove all sticky broadcasts from this user.
6986            mStickyBroadcasts.remove(userId);
6987        }
6988
6989        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6990        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6991                userId, providers)) {
6992            if (!doit) {
6993                return true;
6994            }
6995            didSomething = true;
6996        }
6997        for (i = providers.size() - 1; i >= 0; i--) {
6998            removeDyingProviderLocked(null, providers.get(i), true);
6999        }
7000
7001        // Remove transient permissions granted from/to this package/user
7002        removeUriPermissionsForPackageLocked(packageName, userId, false, false);
7003
7004        if (doit) {
7005            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
7006                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7007                        packageName, null, userId, doit);
7008            }
7009        }
7010
7011        if (packageName == null || uninstalling) {
7012            // Remove pending intents.  For now we only do this when force
7013            // stopping users, because we have some problems when doing this
7014            // for packages -- app widgets are not currently cleaned up for
7015            // such packages, so they can be left with bad pending intents.
7016            if (mIntentSenderRecords.size() > 0) {
7017                Iterator<WeakReference<PendingIntentRecord>> it
7018                        = mIntentSenderRecords.values().iterator();
7019                while (it.hasNext()) {
7020                    WeakReference<PendingIntentRecord> wpir = it.next();
7021                    if (wpir == null) {
7022                        it.remove();
7023                        continue;
7024                    }
7025                    PendingIntentRecord pir = wpir.get();
7026                    if (pir == null) {
7027                        it.remove();
7028                        continue;
7029                    }
7030                    if (packageName == null) {
7031                        // Stopping user, remove all objects for the user.
7032                        if (pir.key.userId != userId) {
7033                            // Not the same user, skip it.
7034                            continue;
7035                        }
7036                    } else {
7037                        if (UserHandle.getAppId(pir.uid) != appId) {
7038                            // Different app id, skip it.
7039                            continue;
7040                        }
7041                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7042                            // Different user, skip it.
7043                            continue;
7044                        }
7045                        if (!pir.key.packageName.equals(packageName)) {
7046                            // Different package, skip it.
7047                            continue;
7048                        }
7049                    }
7050                    if (!doit) {
7051                        return true;
7052                    }
7053                    didSomething = true;
7054                    it.remove();
7055                    makeIntentSenderCanceledLocked(pir);
7056                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7057                        pir.key.activity.pendingResults.remove(pir.ref);
7058                    }
7059                }
7060            }
7061        }
7062
7063        if (doit) {
7064            if (purgeCache && packageName != null) {
7065                AttributeCache ac = AttributeCache.instance();
7066                if (ac != null) {
7067                    ac.removePackage(packageName);
7068                }
7069            }
7070            if (mBooted) {
7071                mStackSupervisor.resumeFocusedStackTopActivityLocked();
7072                mStackSupervisor.scheduleIdleLocked();
7073            }
7074        }
7075
7076        return didSomething;
7077    }
7078
7079    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7080        return removeProcessNameLocked(name, uid, null);
7081    }
7082
7083    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
7084            final ProcessRecord expecting) {
7085        ProcessRecord old = mProcessNames.get(name, uid);
7086        // Only actually remove when the currently recorded value matches the
7087        // record that we expected; if it doesn't match then we raced with a
7088        // newly created process and we don't want to destroy the new one.
7089        if ((expecting == null) || (old == expecting)) {
7090            mProcessNames.remove(name, uid);
7091        }
7092        if (old != null && old.uidRecord != null) {
7093            old.uidRecord.numProcs--;
7094            if (old.uidRecord.numProcs == 0) {
7095                // No more processes using this uid, tell clients it is gone.
7096                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7097                        "No more processes in " + old.uidRecord);
7098                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
7099                EventLogTags.writeAmUidStopped(uid);
7100                mActiveUids.remove(uid);
7101                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
7102            }
7103            old.uidRecord = null;
7104        }
7105        mIsolatedProcesses.remove(uid);
7106        return old;
7107    }
7108
7109    private final void addProcessNameLocked(ProcessRecord proc) {
7110        // We shouldn't already have a process under this name, but just in case we
7111        // need to clean up whatever may be there now.
7112        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
7113        if (old == proc && proc.persistent) {
7114            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
7115            Slog.w(TAG, "Re-adding persistent process " + proc);
7116        } else if (old != null) {
7117            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7118        }
7119        UidRecord uidRec = mActiveUids.get(proc.uid);
7120        if (uidRec == null) {
7121            uidRec = new UidRecord(proc.uid);
7122            // This is the first appearance of the uid, report it now!
7123            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7124                    "Creating new process uid: " + uidRec);
7125            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7126                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7127                uidRec.setWhitelist = uidRec.curWhitelist = true;
7128            }
7129            uidRec.updateHasInternetPermission();
7130            mActiveUids.put(proc.uid, uidRec);
7131            EventLogTags.writeAmUidRunning(uidRec.uid);
7132            noteUidProcessState(uidRec.uid, uidRec.curProcState);
7133        }
7134        proc.uidRecord = uidRec;
7135
7136        // Reset render thread tid if it was already set, so new process can set it again.
7137        proc.renderThreadTid = 0;
7138        uidRec.numProcs++;
7139        mProcessNames.put(proc.processName, proc.uid, proc);
7140        if (proc.isolated) {
7141            mIsolatedProcesses.put(proc.uid, proc);
7142        }
7143    }
7144
7145    boolean removeProcessLocked(ProcessRecord app,
7146            boolean callerWillRestart, boolean allowRestart, String reason) {
7147        final String name = app.processName;
7148        final int uid = app.uid;
7149        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7150            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7151
7152        ProcessRecord old = mProcessNames.get(name, uid);
7153        if (old != app) {
7154            // This process is no longer active, so nothing to do.
7155            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7156            return false;
7157        }
7158        removeProcessNameLocked(name, uid);
7159        if (mHeavyWeightProcess == app) {
7160            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7161                    mHeavyWeightProcess.userId, 0));
7162            mHeavyWeightProcess = null;
7163        }
7164        boolean needRestart = false;
7165        if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7166            int pid = app.pid;
7167            if (pid > 0) {
7168                synchronized (mPidsSelfLocked) {
7169                    mPidsSelfLocked.remove(pid);
7170                    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7171                }
7172                mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7173                if (app.isolated) {
7174                    mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7175                    getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7176                }
7177            }
7178            boolean willRestart = false;
7179            if (app.persistent && !app.isolated) {
7180                if (!callerWillRestart) {
7181                    willRestart = true;
7182                } else {
7183                    needRestart = true;
7184                }
7185            }
7186            app.kill(reason, true);
7187            handleAppDiedLocked(app, willRestart, allowRestart);
7188            if (willRestart) {
7189                removeLruProcessLocked(app);
7190                addAppLocked(app.info, null, false, null /* ABI override */);
7191            }
7192        } else {
7193            mRemovedProcesses.add(app);
7194        }
7195
7196        return needRestart;
7197    }
7198
7199    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7200        cleanupAppInLaunchingProvidersLocked(app, true);
7201        removeProcessLocked(app, false, true, "timeout publishing content providers");
7202    }
7203
7204    private final void processStartTimedOutLocked(ProcessRecord app) {
7205        final int pid = app.pid;
7206        boolean gone = false;
7207        synchronized (mPidsSelfLocked) {
7208            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7209            if (knownApp != null && knownApp.thread == null) {
7210                mPidsSelfLocked.remove(pid);
7211                gone = true;
7212            }
7213        }
7214
7215        if (gone) {
7216            Slog.w(TAG, "Process " + app + " failed to attach");
7217            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7218                    pid, app.uid, app.processName);
7219            removeProcessNameLocked(app.processName, app.uid);
7220            if (mHeavyWeightProcess == app) {
7221                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7222                        mHeavyWeightProcess.userId, 0));
7223                mHeavyWeightProcess = null;
7224            }
7225            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7226            // Take care of any launching providers waiting for this process.
7227            cleanupAppInLaunchingProvidersLocked(app, true);
7228            // Take care of any services that are waiting for the process.
7229            mServices.processStartTimedOutLocked(app);
7230            app.kill("start timeout", true);
7231            if (app.isolated) {
7232                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7233            }
7234            removeLruProcessLocked(app);
7235            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7236                Slog.w(TAG, "Unattached app died before backup, skipping");
7237                mHandler.post(new Runnable() {
7238                @Override
7239                    public void run(){
7240                        try {
7241                            IBackupManager bm = IBackupManager.Stub.asInterface(
7242                                    ServiceManager.getService(Context.BACKUP_SERVICE));
7243                            bm.agentDisconnected(app.info.packageName);
7244                        } catch (RemoteException e) {
7245                            // Can't happen; the backup manager is local
7246                        }
7247                    }
7248                });
7249            }
7250            if (isPendingBroadcastProcessLocked(pid)) {
7251                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7252                skipPendingBroadcastLocked(pid);
7253            }
7254        } else {
7255            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7256        }
7257    }
7258
7259    private final boolean attachApplicationLocked(IApplicationThread thread,
7260            int pid, int callingUid, long startSeq) {
7261
7262        // Find the application record that is being attached...  either via
7263        // the pid if we are running in multiple processes, or just pull the
7264        // next app record if we are emulating process with anonymous threads.
7265        ProcessRecord app;
7266        long startTime = SystemClock.uptimeMillis();
7267        if (pid != MY_PID && pid >= 0) {
7268            synchronized (mPidsSelfLocked) {
7269                app = mPidsSelfLocked.get(pid);
7270            }
7271        } else {
7272            app = null;
7273        }
7274
7275        // It's possible that process called attachApplication before we got a chance to
7276        // update the internal state.
7277        if (app == null && startSeq > 0) {
7278            final ProcessRecord pending = mPendingStarts.get(startSeq);
7279            if (pending != null && pending.startUid == callingUid
7280                    && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7281                            startSeq, true)) {
7282                app = pending;
7283            }
7284        }
7285
7286        if (app == null) {
7287            Slog.w(TAG, "No pending application record for pid " + pid
7288                    + " (IApplicationThread " + thread + "); dropping process");
7289            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7290            if (pid > 0 && pid != MY_PID) {
7291                killProcessQuiet(pid);
7292                //TODO: killProcessGroup(app.info.uid, pid);
7293            } else {
7294                try {
7295                    thread.scheduleExit();
7296                } catch (Exception e) {
7297                    // Ignore exceptions.
7298                }
7299            }
7300            return false;
7301        }
7302
7303        // If this application record is still attached to a previous
7304        // process, clean it up now.
7305        if (app.thread != null) {
7306            handleAppDiedLocked(app, true, true);
7307        }
7308
7309        // Tell the process all about itself.
7310
7311        if (DEBUG_ALL) Slog.v(
7312                TAG, "Binding process pid " + pid + " to record " + app);
7313
7314        final String processName = app.processName;
7315        try {
7316            AppDeathRecipient adr = new AppDeathRecipient(
7317                    app, pid, thread);
7318            thread.asBinder().linkToDeath(adr, 0);
7319            app.deathRecipient = adr;
7320        } catch (RemoteException e) {
7321            app.resetPackageList(mProcessStats);
7322            startProcessLocked(app, "link fail", processName);
7323            return false;
7324        }
7325
7326        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7327
7328        app.makeActive(thread, mProcessStats);
7329        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7330        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7331        app.forcingToImportant = null;
7332        updateProcessForegroundLocked(app, false, false);
7333        app.hasShownUi = false;
7334        app.debugging = false;
7335        app.cached = false;
7336        app.killedByAm = false;
7337        app.killed = false;
7338
7339
7340        // We carefully use the same state that PackageManager uses for
7341        // filtering, since we use this flag to decide if we need to install
7342        // providers when user is unlocked later
7343        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7344
7345        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7346
7347        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7348        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7349
7350        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7351            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7352            msg.obj = app;
7353            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7354        }
7355
7356        checkTime(startTime, "attachApplicationLocked: before bindApplication");
7357
7358        if (!normalMode) {
7359            Slog.i(TAG, "Launching preboot mode app: " + app);
7360        }
7361
7362        if (DEBUG_ALL) Slog.v(
7363            TAG, "New app record " + app
7364            + " thread=" + thread.asBinder() + " pid=" + pid);
7365        try {
7366            int testMode = ApplicationThreadConstants.DEBUG_OFF;
7367            if (mDebugApp != null && mDebugApp.equals(processName)) {
7368                testMode = mWaitForDebugger
7369                    ? ApplicationThreadConstants.DEBUG_WAIT
7370                    : ApplicationThreadConstants.DEBUG_ON;
7371                app.debugging = true;
7372                if (mDebugTransient) {
7373                    mDebugApp = mOrigDebugApp;
7374                    mWaitForDebugger = mOrigWaitForDebugger;
7375                }
7376            }
7377
7378            boolean enableTrackAllocation = false;
7379            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7380                enableTrackAllocation = true;
7381                mTrackAllocationApp = null;
7382            }
7383
7384            // If the app is being launched for restore or full backup, set it up specially
7385            boolean isRestrictedBackupMode = false;
7386            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7387                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7388                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7389                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7390                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7391            }
7392
7393            if (app.instr != null) {
7394                notifyPackageUse(app.instr.mClass.getPackageName(),
7395                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7396            }
7397            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7398                    + processName + " with config " + getGlobalConfiguration());
7399            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7400            app.compat = compatibilityInfoForPackageLocked(appInfo);
7401
7402            ProfilerInfo profilerInfo = null;
7403            String preBindAgent = null;
7404            if (mProfileApp != null && mProfileApp.equals(processName)) {
7405                mProfileProc = app;
7406                if (mProfilerInfo != null) {
7407                    // Send a profiler info object to the app if either a file is given, or
7408                    // an agent should be loaded at bind-time.
7409                    boolean needsInfo = mProfilerInfo.profileFile != null
7410                            || mProfilerInfo.attachAgentDuringBind;
7411                    profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7412                    if (mProfilerInfo.agent != null) {
7413                        preBindAgent = mProfilerInfo.agent;
7414                    }
7415                }
7416            } else if (app.instr != null && app.instr.mProfileFile != null) {
7417                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7418                        null, false);
7419            }
7420            if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7421                // We need to do a debuggable check here. See setAgentApp for why the check is
7422                // postponed to here.
7423                if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7424                    String agent = mAppAgentMap.get(processName);
7425                    // Do not overwrite already requested agent.
7426                    if (profilerInfo == null) {
7427                        profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7428                                mAppAgentMap.get(processName), true);
7429                    } else if (profilerInfo.agent == null) {
7430                        profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7431                    }
7432                }
7433            }
7434
7435            if (profilerInfo != null && profilerInfo.profileFd != null) {
7436                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7437            }
7438
7439            // We deprecated Build.SERIAL and it is not accessible to
7440            // apps that target the v2 security sandbox and to apps that
7441            // target APIs higher than O MR1. Since access to the serial
7442            // is now behind a permission we push down the value.
7443            final String buildSerial = (appInfo.targetSandboxVersion < 2
7444                    && appInfo.targetSdkVersion <= Build.VERSION_CODES.O_MR1)
7445                            ? sTheRealBuildSerial : Build.UNKNOWN;
7446
7447            // Check if this is a secondary process that should be incorporated into some
7448            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7449            // stuff above because profiling can currently happen only in the primary
7450            // instrumentation process.)
7451            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7452                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7453                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7454                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7455                        if (aInstr.mTargetProcesses.length == 0) {
7456                            // This is the wildcard mode, where every process brought up for
7457                            // the target instrumentation should be included.
7458                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7459                                app.instr = aInstr;
7460                                aInstr.mRunningProcesses.add(app);
7461                            }
7462                        } else {
7463                            for (String proc : aInstr.mTargetProcesses) {
7464                                if (proc.equals(app.processName)) {
7465                                    app.instr = aInstr;
7466                                    aInstr.mRunningProcesses.add(app);
7467                                    break;
7468                                }
7469                            }
7470                        }
7471                    }
7472                }
7473            }
7474
7475            // If we were asked to attach an agent on startup, do so now, before we're binding
7476            // application code.
7477            if (preBindAgent != null) {
7478                thread.attachAgent(preBindAgent);
7479            }
7480
7481            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7482            mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7483            if (app.isolatedEntryPoint != null) {
7484                // This is an isolated process which should just call an entry point instead of
7485                // being bound to an application.
7486                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7487            } else if (app.instr != null) {
7488                thread.bindApplication(processName, appInfo, providers,
7489                        app.instr.mClass,
7490                        profilerInfo, app.instr.mArguments,
7491                        app.instr.mWatcher,
7492                        app.instr.mUiAutomationConnection, testMode,
7493                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7494                        isRestrictedBackupMode || !normalMode, app.persistent,
7495                        new Configuration(getGlobalConfiguration()), app.compat,
7496                        getCommonServicesLocked(app.isolated),
7497                        mCoreSettingsObserver.getCoreSettingsLocked(),
7498                        buildSerial);
7499            } else {
7500                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7501                        null, null, null, testMode,
7502                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7503                        isRestrictedBackupMode || !normalMode, app.persistent,
7504                        new Configuration(getGlobalConfiguration()), app.compat,
7505                        getCommonServicesLocked(app.isolated),
7506                        mCoreSettingsObserver.getCoreSettingsLocked(),
7507                        buildSerial);
7508            }
7509
7510            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7511            updateLruProcessLocked(app, false, null);
7512            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7513            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7514        } catch (Exception e) {
7515            // todo: Yikes!  What should we do?  For now we will try to
7516            // start another process, but that could easily get us in
7517            // an infinite loop of restarting processes...
7518            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7519
7520            app.resetPackageList(mProcessStats);
7521            app.unlinkDeathRecipient();
7522            startProcessLocked(app, "bind fail", processName);
7523            return false;
7524        }
7525
7526        // Remove this record from the list of starting applications.
7527        mPersistentStartingProcesses.remove(app);
7528        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7529                "Attach application locked removing on hold: " + app);
7530        mProcessesOnHold.remove(app);
7531
7532        boolean badApp = false;
7533        boolean didSomething = false;
7534
7535        // See if the top visible activity is waiting to run in this process...
7536        if (normalMode) {
7537            try {
7538                if (mStackSupervisor.attachApplicationLocked(app)) {
7539                    didSomething = true;
7540                }
7541            } catch (Exception e) {
7542                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7543                badApp = true;
7544            }
7545        }
7546
7547        // Find any services that should be running in this process...
7548        if (!badApp) {
7549            try {
7550                didSomething |= mServices.attachApplicationLocked(app, processName);
7551                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7552            } catch (Exception e) {
7553                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7554                badApp = true;
7555            }
7556        }
7557
7558        // Check if a next-broadcast receiver is in this process...
7559        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7560            try {
7561                didSomething |= sendPendingBroadcastsLocked(app);
7562                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7563            } catch (Exception e) {
7564                // If the app died trying to launch the receiver we declare it 'bad'
7565                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7566                badApp = true;
7567            }
7568        }
7569
7570        // Check whether the next backup agent is in this process...
7571        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7572            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7573                    "New app is backup target, launching agent for " + app);
7574            notifyPackageUse(mBackupTarget.appInfo.packageName,
7575                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7576            try {
7577                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7578                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7579                        mBackupTarget.backupMode);
7580            } catch (Exception e) {
7581                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7582                badApp = true;
7583            }
7584        }
7585
7586        if (badApp) {
7587            app.kill("error during init", true);
7588            handleAppDiedLocked(app, false, true);
7589            return false;
7590        }
7591
7592        if (!didSomething) {
7593            updateOomAdjLocked();
7594            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7595        }
7596
7597        return true;
7598    }
7599
7600    @Override
7601    public final void attachApplication(IApplicationThread thread, long startSeq) {
7602        synchronized (this) {
7603            int callingPid = Binder.getCallingPid();
7604            final int callingUid = Binder.getCallingUid();
7605            final long origId = Binder.clearCallingIdentity();
7606            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7607            Binder.restoreCallingIdentity(origId);
7608        }
7609    }
7610
7611    @Override
7612    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7613        final long origId = Binder.clearCallingIdentity();
7614        synchronized (this) {
7615            ActivityStack stack = ActivityRecord.getStackLocked(token);
7616            if (stack != null) {
7617                ActivityRecord r =
7618                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7619                                false /* processPausingActivities */, config);
7620                if (stopProfiling) {
7621                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7622                        clearProfilerLocked();
7623                    }
7624                }
7625            }
7626        }
7627        Binder.restoreCallingIdentity(origId);
7628    }
7629
7630    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7631        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7632                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7633    }
7634
7635    void enableScreenAfterBoot() {
7636        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7637                SystemClock.uptimeMillis());
7638        mWindowManager.enableScreenAfterBoot();
7639
7640        synchronized (this) {
7641            updateEventDispatchingLocked();
7642        }
7643    }
7644
7645    @Override
7646    public void showBootMessage(final CharSequence msg, final boolean always) {
7647        if (Binder.getCallingUid() != myUid()) {
7648            throw new SecurityException();
7649        }
7650        mWindowManager.showBootMessage(msg, always);
7651    }
7652
7653    @Override
7654    public void keyguardGoingAway(int flags) {
7655        enforceNotIsolatedCaller("keyguardGoingAway");
7656        final long token = Binder.clearCallingIdentity();
7657        try {
7658            synchronized (this) {
7659                mKeyguardController.keyguardGoingAway(flags);
7660            }
7661        } finally {
7662            Binder.restoreCallingIdentity(token);
7663        }
7664    }
7665
7666    /**
7667     * @return whther the keyguard is currently locked.
7668     */
7669    boolean isKeyguardLocked() {
7670        return mKeyguardController.isKeyguardLocked();
7671    }
7672
7673    final void finishBooting() {
7674        synchronized (this) {
7675            if (!mBootAnimationComplete) {
7676                mCallFinishBooting = true;
7677                return;
7678            }
7679            mCallFinishBooting = false;
7680        }
7681
7682        ArraySet<String> completedIsas = new ArraySet<String>();
7683        for (String abi : Build.SUPPORTED_ABIS) {
7684            zygoteProcess.establishZygoteConnectionForAbi(abi);
7685            final String instructionSet = VMRuntime.getInstructionSet(abi);
7686            if (!completedIsas.contains(instructionSet)) {
7687                try {
7688                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7689                } catch (InstallerException e) {
7690                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7691                            e.getMessage() +")");
7692                }
7693                completedIsas.add(instructionSet);
7694            }
7695        }
7696
7697        IntentFilter pkgFilter = new IntentFilter();
7698        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7699        pkgFilter.addDataScheme("package");
7700        mContext.registerReceiver(new BroadcastReceiver() {
7701            @Override
7702            public void onReceive(Context context, Intent intent) {
7703                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7704                if (pkgs != null) {
7705                    for (String pkg : pkgs) {
7706                        synchronized (ActivityManagerService.this) {
7707                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7708                                    0, "query restart")) {
7709                                setResultCode(Activity.RESULT_OK);
7710                                return;
7711                            }
7712                        }
7713                    }
7714                }
7715            }
7716        }, pkgFilter);
7717
7718        IntentFilter dumpheapFilter = new IntentFilter();
7719        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7720        mContext.registerReceiver(new BroadcastReceiver() {
7721            @Override
7722            public void onReceive(Context context, Intent intent) {
7723                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7724                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7725                } else {
7726                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7727                }
7728            }
7729        }, dumpheapFilter);
7730
7731        // Let system services know.
7732        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7733
7734        synchronized (this) {
7735            // Ensure that any processes we had put on hold are now started
7736            // up.
7737            final int NP = mProcessesOnHold.size();
7738            if (NP > 0) {
7739                ArrayList<ProcessRecord> procs =
7740                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7741                for (int ip=0; ip<NP; ip++) {
7742                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7743                            + procs.get(ip));
7744                    startProcessLocked(procs.get(ip), "on-hold", null);
7745                }
7746            }
7747            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7748                return;
7749            }
7750            // Start looking for apps that are abusing wake locks.
7751            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7752            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7753            // Tell anyone interested that we are done booting!
7754            SystemProperties.set("sys.boot_completed", "1");
7755
7756            // And trigger dev.bootcomplete if we are not showing encryption progress
7757            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7758                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7759                SystemProperties.set("dev.bootcomplete", "1");
7760            }
7761            mUserController.sendBootCompleted(
7762                    new IIntentReceiver.Stub() {
7763                        @Override
7764                        public void performReceive(Intent intent, int resultCode,
7765                                String data, Bundle extras, boolean ordered,
7766                                boolean sticky, int sendingUser) {
7767                            synchronized (ActivityManagerService.this) {
7768                                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
7769                            }
7770                        }
7771                    });
7772            mUserController.scheduleStartProfiles();
7773        }
7774    }
7775
7776    @Override
7777    public void bootAnimationComplete() {
7778        final boolean callFinishBooting;
7779        synchronized (this) {
7780            callFinishBooting = mCallFinishBooting;
7781            mBootAnimationComplete = true;
7782        }
7783        if (callFinishBooting) {
7784            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7785            finishBooting();
7786            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7787        }
7788    }
7789
7790    final void ensureBootCompleted() {
7791        boolean booting;
7792        boolean enableScreen;
7793        synchronized (this) {
7794            booting = mBooting;
7795            mBooting = false;
7796            enableScreen = !mBooted;
7797            mBooted = true;
7798        }
7799
7800        if (booting) {
7801            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7802            finishBooting();
7803            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7804        }
7805
7806        if (enableScreen) {
7807            enableScreenAfterBoot();
7808        }
7809    }
7810
7811    @Override
7812    public final void activityResumed(IBinder token) {
7813        final long origId = Binder.clearCallingIdentity();
7814        synchronized(this) {
7815            ActivityRecord.activityResumedLocked(token);
7816            mWindowManager.notifyAppResumedFinished(token);
7817        }
7818        Binder.restoreCallingIdentity(origId);
7819    }
7820
7821    @Override
7822    public final void activityPaused(IBinder token) {
7823        final long origId = Binder.clearCallingIdentity();
7824        synchronized(this) {
7825            ActivityStack stack = ActivityRecord.getStackLocked(token);
7826            if (stack != null) {
7827                stack.activityPausedLocked(token, false);
7828            }
7829        }
7830        Binder.restoreCallingIdentity(origId);
7831    }
7832
7833    @Override
7834    public final void activityStopped(IBinder token, Bundle icicle,
7835            PersistableBundle persistentState, CharSequence description) {
7836        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7837
7838        // Refuse possible leaked file descriptors
7839        if (icicle != null && icicle.hasFileDescriptors()) {
7840            throw new IllegalArgumentException("File descriptors passed in Bundle");
7841        }
7842
7843        final long origId = Binder.clearCallingIdentity();
7844
7845        synchronized (this) {
7846            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7847            if (r != null) {
7848                r.activityStoppedLocked(icicle, persistentState, description);
7849            }
7850        }
7851
7852        trimApplications();
7853
7854        Binder.restoreCallingIdentity(origId);
7855    }
7856
7857    @Override
7858    public final void activityDestroyed(IBinder token) {
7859        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7860        synchronized (this) {
7861            ActivityStack stack = ActivityRecord.getStackLocked(token);
7862            if (stack != null) {
7863                stack.activityDestroyedLocked(token, "activityDestroyed");
7864            }
7865        }
7866    }
7867
7868    @Override
7869    public final void activityRelaunched(IBinder token) {
7870        final long origId = Binder.clearCallingIdentity();
7871        synchronized (this) {
7872            mStackSupervisor.activityRelaunchedLocked(token);
7873        }
7874        Binder.restoreCallingIdentity(origId);
7875    }
7876
7877    @Override
7878    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7879            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7880        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7881                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7882        synchronized (this) {
7883            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7884            if (record == null) {
7885                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7886                        + "found for: " + token);
7887            }
7888            record.setSizeConfigurations(horizontalSizeConfiguration,
7889                    verticalSizeConfigurations, smallestSizeConfigurations);
7890        }
7891    }
7892
7893    @Override
7894    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7895        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7896    }
7897
7898    @Override
7899    public final void notifyEnterAnimationComplete(IBinder token) {
7900        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7901    }
7902
7903    @Override
7904    public String getCallingPackage(IBinder token) {
7905        synchronized (this) {
7906            ActivityRecord r = getCallingRecordLocked(token);
7907            return r != null ? r.info.packageName : null;
7908        }
7909    }
7910
7911    @Override
7912    public ComponentName getCallingActivity(IBinder token) {
7913        synchronized (this) {
7914            ActivityRecord r = getCallingRecordLocked(token);
7915            return r != null ? r.intent.getComponent() : null;
7916        }
7917    }
7918
7919    private ActivityRecord getCallingRecordLocked(IBinder token) {
7920        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7921        if (r == null) {
7922            return null;
7923        }
7924        return r.resultTo;
7925    }
7926
7927    @Override
7928    public ComponentName getActivityClassForToken(IBinder token) {
7929        synchronized(this) {
7930            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7931            if (r == null) {
7932                return null;
7933            }
7934            return r.intent.getComponent();
7935        }
7936    }
7937
7938    @Override
7939    public String getPackageForToken(IBinder token) {
7940        synchronized(this) {
7941            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7942            if (r == null) {
7943                return null;
7944            }
7945            return r.packageName;
7946        }
7947    }
7948
7949    @Override
7950    public boolean isRootVoiceInteraction(IBinder token) {
7951        synchronized(this) {
7952            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7953            if (r == null) {
7954                return false;
7955            }
7956            return r.rootVoiceInteraction;
7957        }
7958    }
7959
7960    @Override
7961    public IIntentSender getIntentSender(int type,
7962            String packageName, IBinder token, String resultWho,
7963            int requestCode, Intent[] intents, String[] resolvedTypes,
7964            int flags, Bundle bOptions, int userId) {
7965        enforceNotIsolatedCaller("getIntentSender");
7966        // Refuse possible leaked file descriptors
7967        if (intents != null) {
7968            if (intents.length < 1) {
7969                throw new IllegalArgumentException("Intents array length must be >= 1");
7970            }
7971            for (int i=0; i<intents.length; i++) {
7972                Intent intent = intents[i];
7973                if (intent != null) {
7974                    if (intent.hasFileDescriptors()) {
7975                        throw new IllegalArgumentException("File descriptors passed in Intent");
7976                    }
7977                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7978                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7979                        throw new IllegalArgumentException(
7980                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7981                    }
7982                    intents[i] = new Intent(intent);
7983                }
7984            }
7985            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7986                throw new IllegalArgumentException(
7987                        "Intent array length does not match resolvedTypes length");
7988            }
7989        }
7990        if (bOptions != null) {
7991            if (bOptions.hasFileDescriptors()) {
7992                throw new IllegalArgumentException("File descriptors passed in options");
7993            }
7994        }
7995
7996        synchronized(this) {
7997            int callingUid = Binder.getCallingUid();
7998            int origUserId = userId;
7999            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8000                    type == ActivityManager.INTENT_SENDER_BROADCAST,
8001                    ALLOW_NON_FULL, "getIntentSender", null);
8002            if (origUserId == UserHandle.USER_CURRENT) {
8003                // We don't want to evaluate this until the pending intent is
8004                // actually executed.  However, we do want to always do the
8005                // security checking for it above.
8006                userId = UserHandle.USER_CURRENT;
8007            }
8008            try {
8009                if (callingUid != 0 && callingUid != SYSTEM_UID) {
8010                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
8011                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
8012                    if (!UserHandle.isSameApp(callingUid, uid)) {
8013                        String msg = "Permission Denial: getIntentSender() from pid="
8014                            + Binder.getCallingPid()
8015                            + ", uid=" + Binder.getCallingUid()
8016                            + ", (need uid=" + uid + ")"
8017                            + " is not allowed to send as package " + packageName;
8018                        Slog.w(TAG, msg);
8019                        throw new SecurityException(msg);
8020                    }
8021                }
8022
8023                return getIntentSenderLocked(type, packageName, callingUid, userId,
8024                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
8025
8026            } catch (RemoteException e) {
8027                throw new SecurityException(e);
8028            }
8029        }
8030    }
8031
8032    IIntentSender getIntentSenderLocked(int type, String packageName,
8033            int callingUid, int userId, IBinder token, String resultWho,
8034            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
8035            Bundle bOptions) {
8036        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
8037        ActivityRecord activity = null;
8038        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8039            activity = ActivityRecord.isInStackLocked(token);
8040            if (activity == null) {
8041                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
8042                return null;
8043            }
8044            if (activity.finishing) {
8045                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
8046                return null;
8047            }
8048        }
8049
8050        // We're going to be splicing together extras before sending, so we're
8051        // okay poking into any contained extras.
8052        if (intents != null) {
8053            for (int i = 0; i < intents.length; i++) {
8054                intents[i].setDefusable(true);
8055            }
8056        }
8057        Bundle.setDefusable(bOptions, true);
8058
8059        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
8060        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
8061        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
8062        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
8063                |PendingIntent.FLAG_UPDATE_CURRENT);
8064
8065        PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
8066                resultWho, requestCode, intents, resolvedTypes, flags,
8067                SafeActivityOptions.fromBundle(bOptions), userId);
8068        WeakReference<PendingIntentRecord> ref;
8069        ref = mIntentSenderRecords.get(key);
8070        PendingIntentRecord rec = ref != null ? ref.get() : null;
8071        if (rec != null) {
8072            if (!cancelCurrent) {
8073                if (updateCurrent) {
8074                    if (rec.key.requestIntent != null) {
8075                        rec.key.requestIntent.replaceExtras(intents != null ?
8076                                intents[intents.length - 1] : null);
8077                    }
8078                    if (intents != null) {
8079                        intents[intents.length-1] = rec.key.requestIntent;
8080                        rec.key.allIntents = intents;
8081                        rec.key.allResolvedTypes = resolvedTypes;
8082                    } else {
8083                        rec.key.allIntents = null;
8084                        rec.key.allResolvedTypes = null;
8085                    }
8086                }
8087                return rec;
8088            }
8089            makeIntentSenderCanceledLocked(rec);
8090            mIntentSenderRecords.remove(key);
8091        }
8092        if (noCreate) {
8093            return rec;
8094        }
8095        rec = new PendingIntentRecord(this, key, callingUid);
8096        mIntentSenderRecords.put(key, rec.ref);
8097        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8098            if (activity.pendingResults == null) {
8099                activity.pendingResults
8100                        = new HashSet<WeakReference<PendingIntentRecord>>();
8101            }
8102            activity.pendingResults.add(rec.ref);
8103        }
8104        return rec;
8105    }
8106
8107    @Override
8108    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
8109            Intent intent, String resolvedType,
8110            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
8111        if (target instanceof PendingIntentRecord) {
8112            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
8113                    whitelistToken, finishedReceiver, requiredPermission, options);
8114        } else {
8115            if (intent == null) {
8116                // Weird case: someone has given us their own custom IIntentSender, and now
8117                // they have someone else trying to send to it but of course this isn't
8118                // really a PendingIntent, so there is no base Intent, and the caller isn't
8119                // supplying an Intent... but we never want to dispatch a null Intent to
8120                // a receiver, so um...  let's make something up.
8121                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
8122                intent = new Intent(Intent.ACTION_MAIN);
8123            }
8124            try {
8125                target.send(code, intent, resolvedType, whitelistToken, null,
8126                        requiredPermission, options);
8127            } catch (RemoteException e) {
8128            }
8129            // Platform code can rely on getting a result back when the send is done, but if
8130            // this intent sender is from outside of the system we can't rely on it doing that.
8131            // So instead we don't give it the result receiver, and instead just directly
8132            // report the finish immediately.
8133            if (finishedReceiver != null) {
8134                try {
8135                    finishedReceiver.performReceive(intent, 0,
8136                            null, null, false, false, UserHandle.getCallingUserId());
8137                } catch (RemoteException e) {
8138                }
8139            }
8140            return 0;
8141        }
8142    }
8143
8144    @Override
8145    public void cancelIntentSender(IIntentSender sender) {
8146        if (!(sender instanceof PendingIntentRecord)) {
8147            return;
8148        }
8149        synchronized(this) {
8150            PendingIntentRecord rec = (PendingIntentRecord)sender;
8151            try {
8152                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8153                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8154                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8155                    String msg = "Permission Denial: cancelIntentSender() from pid="
8156                        + Binder.getCallingPid()
8157                        + ", uid=" + Binder.getCallingUid()
8158                        + " is not allowed to cancel package "
8159                        + rec.key.packageName;
8160                    Slog.w(TAG, msg);
8161                    throw new SecurityException(msg);
8162                }
8163            } catch (RemoteException e) {
8164                throw new SecurityException(e);
8165            }
8166            cancelIntentSenderLocked(rec, true);
8167        }
8168    }
8169
8170    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8171        makeIntentSenderCanceledLocked(rec);
8172        mIntentSenderRecords.remove(rec.key);
8173        if (cleanActivity && rec.key.activity != null) {
8174            rec.key.activity.pendingResults.remove(rec.ref);
8175        }
8176    }
8177
8178    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8179        rec.canceled = true;
8180        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8181        if (callbacks != null) {
8182            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8183        }
8184    }
8185
8186    @Override
8187    public String getPackageForIntentSender(IIntentSender pendingResult) {
8188        if (!(pendingResult instanceof PendingIntentRecord)) {
8189            return null;
8190        }
8191        try {
8192            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8193            return res.key.packageName;
8194        } catch (ClassCastException e) {
8195        }
8196        return null;
8197    }
8198
8199    @Override
8200    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8201        if (!(sender instanceof PendingIntentRecord)) {
8202            return;
8203        }
8204        synchronized(this) {
8205            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
8206        }
8207    }
8208
8209    @Override
8210    public void unregisterIntentSenderCancelListener(IIntentSender sender,
8211            IResultReceiver receiver) {
8212        if (!(sender instanceof PendingIntentRecord)) {
8213            return;
8214        }
8215        synchronized(this) {
8216            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8217        }
8218    }
8219
8220    @Override
8221    public int getUidForIntentSender(IIntentSender sender) {
8222        if (sender instanceof PendingIntentRecord) {
8223            try {
8224                PendingIntentRecord res = (PendingIntentRecord)sender;
8225                return res.uid;
8226            } catch (ClassCastException e) {
8227            }
8228        }
8229        return -1;
8230    }
8231
8232    @Override
8233    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8234        if (!(pendingResult instanceof PendingIntentRecord)) {
8235            return false;
8236        }
8237        try {
8238            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8239            if (res.key.allIntents == null) {
8240                return false;
8241            }
8242            for (int i=0; i<res.key.allIntents.length; i++) {
8243                Intent intent = res.key.allIntents[i];
8244                if (intent.getPackage() != null && intent.getComponent() != null) {
8245                    return false;
8246                }
8247            }
8248            return true;
8249        } catch (ClassCastException e) {
8250        }
8251        return false;
8252    }
8253
8254    @Override
8255    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8256        if (!(pendingResult instanceof PendingIntentRecord)) {
8257            return false;
8258        }
8259        try {
8260            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8261            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8262                return true;
8263            }
8264            return false;
8265        } catch (ClassCastException e) {
8266        }
8267        return false;
8268    }
8269
8270    @Override
8271    public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8272        if (pendingResult instanceof PendingIntentRecord) {
8273            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8274            return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8275        }
8276        return false;
8277    }
8278
8279    @Override
8280    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8281        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8282                "getIntentForIntentSender()");
8283        if (!(pendingResult instanceof PendingIntentRecord)) {
8284            return null;
8285        }
8286        try {
8287            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8288            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8289        } catch (ClassCastException e) {
8290        }
8291        return null;
8292    }
8293
8294    @Override
8295    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8296        if (!(pendingResult instanceof PendingIntentRecord)) {
8297            return null;
8298        }
8299        try {
8300            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8301            synchronized (this) {
8302                return getTagForIntentSenderLocked(res, prefix);
8303            }
8304        } catch (ClassCastException e) {
8305        }
8306        return null;
8307    }
8308
8309    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8310        final Intent intent = res.key.requestIntent;
8311        if (intent != null) {
8312            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8313                    || res.lastTagPrefix.equals(prefix))) {
8314                return res.lastTag;
8315            }
8316            res.lastTagPrefix = prefix;
8317            final StringBuilder sb = new StringBuilder(128);
8318            if (prefix != null) {
8319                sb.append(prefix);
8320            }
8321            if (intent.getAction() != null) {
8322                sb.append(intent.getAction());
8323            } else if (intent.getComponent() != null) {
8324                intent.getComponent().appendShortString(sb);
8325            } else {
8326                sb.append("?");
8327            }
8328            return res.lastTag = sb.toString();
8329        }
8330        return null;
8331    }
8332
8333    @Override
8334    public void setProcessLimit(int max) {
8335        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8336                "setProcessLimit()");
8337        synchronized (this) {
8338            mConstants.setOverrideMaxCachedProcesses(max);
8339        }
8340        trimApplications();
8341    }
8342
8343    @Override
8344    public int getProcessLimit() {
8345        synchronized (this) {
8346            return mConstants.getOverrideMaxCachedProcesses();
8347        }
8348    }
8349
8350    void importanceTokenDied(ImportanceToken token) {
8351        synchronized (ActivityManagerService.this) {
8352            synchronized (mPidsSelfLocked) {
8353                ImportanceToken cur
8354                    = mImportantProcesses.get(token.pid);
8355                if (cur != token) {
8356                    return;
8357                }
8358                mImportantProcesses.remove(token.pid);
8359                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8360                if (pr == null) {
8361                    return;
8362                }
8363                pr.forcingToImportant = null;
8364                updateProcessForegroundLocked(pr, false, false);
8365            }
8366            updateOomAdjLocked();
8367        }
8368    }
8369
8370    @Override
8371    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8372        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8373                "setProcessImportant()");
8374        synchronized(this) {
8375            boolean changed = false;
8376
8377            synchronized (mPidsSelfLocked) {
8378                ProcessRecord pr = mPidsSelfLocked.get(pid);
8379                if (pr == null && isForeground) {
8380                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8381                    return;
8382                }
8383                ImportanceToken oldToken = mImportantProcesses.get(pid);
8384                if (oldToken != null) {
8385                    oldToken.token.unlinkToDeath(oldToken, 0);
8386                    mImportantProcesses.remove(pid);
8387                    if (pr != null) {
8388                        pr.forcingToImportant = null;
8389                    }
8390                    changed = true;
8391                }
8392                if (isForeground && token != null) {
8393                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8394                        @Override
8395                        public void binderDied() {
8396                            importanceTokenDied(this);
8397                        }
8398                    };
8399                    try {
8400                        token.linkToDeath(newToken, 0);
8401                        mImportantProcesses.put(pid, newToken);
8402                        pr.forcingToImportant = newToken;
8403                        changed = true;
8404                    } catch (RemoteException e) {
8405                        // If the process died while doing this, we will later
8406                        // do the cleanup with the process death link.
8407                    }
8408                }
8409            }
8410
8411            if (changed) {
8412                updateOomAdjLocked();
8413            }
8414        }
8415    }
8416
8417    @Override
8418    public boolean isAppForeground(int uid) throws RemoteException {
8419        synchronized (this) {
8420            UidRecord uidRec = mActiveUids.get(uid);
8421            if (uidRec == null || uidRec.idle) {
8422                return false;
8423            }
8424            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8425        }
8426    }
8427
8428    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8429    // be guarded by permission checking.
8430    int getUidState(int uid) {
8431        synchronized (this) {
8432            return getUidStateLocked(uid);
8433        }
8434    }
8435
8436    int getUidStateLocked(int uid) {
8437        UidRecord uidRec = mActiveUids.get(uid);
8438        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8439    }
8440
8441    @Override
8442    public boolean isInMultiWindowMode(IBinder token) {
8443        final long origId = Binder.clearCallingIdentity();
8444        try {
8445            synchronized(this) {
8446                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8447                if (r == null) {
8448                    return false;
8449                }
8450                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8451                return r.inMultiWindowMode();
8452            }
8453        } finally {
8454            Binder.restoreCallingIdentity(origId);
8455        }
8456    }
8457
8458    @Override
8459    public boolean isInPictureInPictureMode(IBinder token) {
8460        final long origId = Binder.clearCallingIdentity();
8461        try {
8462            synchronized(this) {
8463                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8464            }
8465        } finally {
8466            Binder.restoreCallingIdentity(origId);
8467        }
8468    }
8469
8470    private boolean isInPictureInPictureMode(ActivityRecord r) {
8471        if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8472                || r.getStack().isInStackLocked(r) == null) {
8473            return false;
8474        }
8475
8476        // If we are animating to fullscreen then we have already dispatched the PIP mode
8477        // changed, so we should reflect that check here as well.
8478        final PinnedActivityStack stack = r.getStack();
8479        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8480        return !windowController.isAnimatingBoundsToFullscreen();
8481    }
8482
8483    @Override
8484    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8485        final long origId = Binder.clearCallingIdentity();
8486        try {
8487            synchronized(this) {
8488                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8489                        "enterPictureInPictureMode", token, params);
8490
8491                // If the activity is already in picture in picture mode, then just return early
8492                if (isInPictureInPictureMode(r)) {
8493                    return true;
8494                }
8495
8496                // Activity supports picture-in-picture, now check that we can enter PiP at this
8497                // point, if it is
8498                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8499                        false /* beforeStopping */)) {
8500                    return false;
8501                }
8502
8503                final Runnable enterPipRunnable = () -> {
8504                    // Only update the saved args from the args that are set
8505                    r.pictureInPictureArgs.copyOnlySet(params);
8506                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8507                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8508                    // Adjust the source bounds by the insets for the transition down
8509                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8510                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8511                            "enterPictureInPictureMode");
8512                    final PinnedActivityStack stack = r.getStack();
8513                    stack.setPictureInPictureAspectRatio(aspectRatio);
8514                    stack.setPictureInPictureActions(actions);
8515
8516                    MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.supportsEnterPipOnTaskSwitch);
8517                    logPictureInPictureArgs(params);
8518                };
8519
8520                if (isKeyguardLocked()) {
8521                    // If the keyguard is showing or occluded, then try and dismiss it before
8522                    // entering picture-in-picture (this will prompt the user to authenticate if the
8523                    // device is currently locked).
8524                    try {
8525                        dismissKeyguard(token, new KeyguardDismissCallback() {
8526                            @Override
8527                            public void onDismissSucceeded() throws RemoteException {
8528                                mHandler.post(enterPipRunnable);
8529                            }
8530                        }, null /* message */);
8531                    } catch (RemoteException e) {
8532                        // Local call
8533                    }
8534                } else {
8535                    // Enter picture in picture immediately otherwise
8536                    enterPipRunnable.run();
8537                }
8538                return true;
8539            }
8540        } finally {
8541            Binder.restoreCallingIdentity(origId);
8542        }
8543    }
8544
8545    @Override
8546    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8547        final long origId = Binder.clearCallingIdentity();
8548        try {
8549            synchronized(this) {
8550                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8551                        "setPictureInPictureParams", token, params);
8552
8553                // Only update the saved args from the args that are set
8554                r.pictureInPictureArgs.copyOnlySet(params);
8555                if (r.inPinnedWindowingMode()) {
8556                    // If the activity is already in picture-in-picture, update the pinned stack now
8557                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8558                    // be used the next time the activity enters PiP
8559                    final PinnedActivityStack stack = r.getStack();
8560                    if (!stack.isAnimatingBoundsToFullscreen()) {
8561                        stack.setPictureInPictureAspectRatio(
8562                                r.pictureInPictureArgs.getAspectRatio());
8563                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8564                    }
8565                }
8566                logPictureInPictureArgs(params);
8567            }
8568        } finally {
8569            Binder.restoreCallingIdentity(origId);
8570        }
8571    }
8572
8573    @Override
8574    public int getMaxNumPictureInPictureActions(IBinder token) {
8575        // Currently, this is a static constant, but later, we may change this to be dependent on
8576        // the context of the activity
8577        return 3;
8578    }
8579
8580    private void logPictureInPictureArgs(PictureInPictureParams params) {
8581        if (params.hasSetActions()) {
8582            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8583                    params.getActions().size());
8584        }
8585        if (params.hasSetAspectRatio()) {
8586            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8587            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8588            MetricsLogger.action(lm);
8589        }
8590    }
8591
8592    /**
8593     * Checks the state of the system and the activity associated with the given {@param token} to
8594     * verify that picture-in-picture is supported for that activity.
8595     *
8596     * @return the activity record for the given {@param token} if all the checks pass.
8597     */
8598    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8599            IBinder token, PictureInPictureParams params) {
8600        if (!mSupportsPictureInPicture) {
8601            throw new IllegalStateException(caller
8602                    + ": Device doesn't support picture-in-picture mode.");
8603        }
8604
8605        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8606        if (r == null) {
8607            throw new IllegalStateException(caller
8608                    + ": Can't find activity for token=" + token);
8609        }
8610
8611        if (!r.supportsPictureInPicture()) {
8612            throw new IllegalStateException(caller
8613                    + ": Current activity does not support picture-in-picture.");
8614        }
8615
8616        if (params.hasSetAspectRatio()
8617                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8618                        params.getAspectRatio())) {
8619            final float minAspectRatio = mContext.getResources().getFloat(
8620                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8621            final float maxAspectRatio = mContext.getResources().getFloat(
8622                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8623            throw new IllegalArgumentException(String.format(caller
8624                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8625                            minAspectRatio, maxAspectRatio));
8626        }
8627
8628        // Truncate the number of actions if necessary
8629        params.truncateActions(getMaxNumPictureInPictureActions(token));
8630
8631        return r;
8632    }
8633
8634    // =========================================================
8635    // PROCESS INFO
8636    // =========================================================
8637
8638    static class ProcessInfoService extends IProcessInfoService.Stub {
8639        final ActivityManagerService mActivityManagerService;
8640        ProcessInfoService(ActivityManagerService activityManagerService) {
8641            mActivityManagerService = activityManagerService;
8642        }
8643
8644        @Override
8645        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8646            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8647                    /*in*/ pids, /*out*/ states, null);
8648        }
8649
8650        @Override
8651        public void getProcessStatesAndOomScoresFromPids(
8652                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8653            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8654                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8655        }
8656    }
8657
8658    /**
8659     * For each PID in the given input array, write the current process state
8660     * for that process into the states array, or -1 to indicate that no
8661     * process with the given PID exists. If scores array is provided, write
8662     * the oom score for the process into the scores array, with INVALID_ADJ
8663     * indicating the PID doesn't exist.
8664     */
8665    public void getProcessStatesAndOomScoresForPIDs(
8666            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8667        if (scores != null) {
8668            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8669                    "getProcessStatesAndOomScoresForPIDs()");
8670        }
8671
8672        if (pids == null) {
8673            throw new NullPointerException("pids");
8674        } else if (states == null) {
8675            throw new NullPointerException("states");
8676        } else if (pids.length != states.length) {
8677            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8678        } else if (scores != null && pids.length != scores.length) {
8679            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8680        }
8681
8682        synchronized (mPidsSelfLocked) {
8683            for (int i = 0; i < pids.length; i++) {
8684                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8685                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8686                        pr.curProcState;
8687                if (scores != null) {
8688                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8689                }
8690            }
8691        }
8692    }
8693
8694    // =========================================================
8695    // PERMISSIONS
8696    // =========================================================
8697
8698    static class PermissionController extends IPermissionController.Stub {
8699        ActivityManagerService mActivityManagerService;
8700        PermissionController(ActivityManagerService activityManagerService) {
8701            mActivityManagerService = activityManagerService;
8702        }
8703
8704        @Override
8705        public boolean checkPermission(String permission, int pid, int uid) {
8706            return mActivityManagerService.checkPermission(permission, pid,
8707                    uid) == PackageManager.PERMISSION_GRANTED;
8708        }
8709
8710        @Override
8711        public String[] getPackagesForUid(int uid) {
8712            return mActivityManagerService.mContext.getPackageManager()
8713                    .getPackagesForUid(uid);
8714        }
8715
8716        @Override
8717        public boolean isRuntimePermission(String permission) {
8718            try {
8719                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8720                        .getPermissionInfo(permission, 0);
8721                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8722                        == PermissionInfo.PROTECTION_DANGEROUS;
8723            } catch (NameNotFoundException nnfe) {
8724                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8725            }
8726            return false;
8727        }
8728
8729        @Override
8730        public int getPackageUid(String packageName, int flags) {
8731            try {
8732                return mActivityManagerService.mContext.getPackageManager()
8733                        .getPackageUid(packageName, flags);
8734            } catch (NameNotFoundException nnfe) {
8735                return -1;
8736            }
8737        }
8738    }
8739
8740    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8741        @Override
8742        public int checkComponentPermission(String permission, int pid, int uid,
8743                int owningUid, boolean exported) {
8744            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8745                    owningUid, exported);
8746        }
8747
8748        @Override
8749        public Object getAMSLock() {
8750            return ActivityManagerService.this;
8751        }
8752    }
8753
8754    int checkComponentPermission(String permission, int pid, int uid,
8755            int owningUid, boolean exported) {
8756        if (pid == MY_PID) {
8757            return PackageManager.PERMISSION_GRANTED;
8758        }
8759        return ActivityManager.checkComponentPermission(permission, uid,
8760                owningUid, exported);
8761    }
8762
8763    /**
8764     * As the only public entry point for permissions checking, this method
8765     * can enforce the semantic that requesting a check on a null global
8766     * permission is automatically denied.  (Internally a null permission
8767     * string is used when calling {@link #checkComponentPermission} in cases
8768     * when only uid-based security is needed.)
8769     *
8770     * This can be called with or without the global lock held.
8771     */
8772    @Override
8773    public int checkPermission(String permission, int pid, int uid) {
8774        if (permission == null) {
8775            return PackageManager.PERMISSION_DENIED;
8776        }
8777        return checkComponentPermission(permission, pid, uid, -1, true);
8778    }
8779
8780    @Override
8781    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8782        if (permission == null) {
8783            return PackageManager.PERMISSION_DENIED;
8784        }
8785
8786        // We might be performing an operation on behalf of an indirect binder
8787        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8788        // client identity accordingly before proceeding.
8789        Identity tlsIdentity = sCallerIdentity.get();
8790        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8791            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8792                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8793            uid = tlsIdentity.uid;
8794            pid = tlsIdentity.pid;
8795        }
8796
8797        return checkComponentPermission(permission, pid, uid, -1, true);
8798    }
8799
8800    /**
8801     * Binder IPC calls go through the public entry point.
8802     * This can be called with or without the global lock held.
8803     */
8804    int checkCallingPermission(String permission) {
8805        return checkPermission(permission,
8806                Binder.getCallingPid(),
8807                UserHandle.getAppId(Binder.getCallingUid()));
8808    }
8809
8810    /**
8811     * This can be called with or without the global lock held.
8812     */
8813    void enforceCallingPermission(String permission, String func) {
8814        if (checkCallingPermission(permission)
8815                == PackageManager.PERMISSION_GRANTED) {
8816            return;
8817        }
8818
8819        String msg = "Permission Denial: " + func + " from pid="
8820                + Binder.getCallingPid()
8821                + ", uid=" + Binder.getCallingUid()
8822                + " requires " + permission;
8823        Slog.w(TAG, msg);
8824        throw new SecurityException(msg);
8825    }
8826
8827    /**
8828     * This can be called with or without the global lock held.
8829     */
8830    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
8831        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
8832            enforceCallingPermission(permission, func);
8833        }
8834    }
8835
8836    /**
8837     * Determine if UID is holding permissions required to access {@link Uri} in
8838     * the given {@link ProviderInfo}. Final permission checking is always done
8839     * in {@link ContentProvider}.
8840     */
8841    private final boolean checkHoldingPermissionsLocked(
8842            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8843        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8844                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8845        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8846            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8847                    != PERMISSION_GRANTED) {
8848                return false;
8849            }
8850        }
8851        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8852    }
8853
8854    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8855            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8856        if (pi.applicationInfo.uid == uid) {
8857            return true;
8858        } else if (!pi.exported) {
8859            return false;
8860        }
8861
8862        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8863        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8864        try {
8865            // check if target holds top-level <provider> permissions
8866            if (!readMet && pi.readPermission != null && considerUidPermissions
8867                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8868                readMet = true;
8869            }
8870            if (!writeMet && pi.writePermission != null && considerUidPermissions
8871                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8872                writeMet = true;
8873            }
8874
8875            // track if unprotected read/write is allowed; any denied
8876            // <path-permission> below removes this ability
8877            boolean allowDefaultRead = pi.readPermission == null;
8878            boolean allowDefaultWrite = pi.writePermission == null;
8879
8880            // check if target holds any <path-permission> that match uri
8881            final PathPermission[] pps = pi.pathPermissions;
8882            if (pps != null) {
8883                final String path = grantUri.uri.getPath();
8884                int i = pps.length;
8885                while (i > 0 && (!readMet || !writeMet)) {
8886                    i--;
8887                    PathPermission pp = pps[i];
8888                    if (pp.match(path)) {
8889                        if (!readMet) {
8890                            final String pprperm = pp.getReadPermission();
8891                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8892                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8893                                    + ": match=" + pp.match(path)
8894                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8895                            if (pprperm != null) {
8896                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8897                                        == PERMISSION_GRANTED) {
8898                                    readMet = true;
8899                                } else {
8900                                    allowDefaultRead = false;
8901                                }
8902                            }
8903                        }
8904                        if (!writeMet) {
8905                            final String ppwperm = pp.getWritePermission();
8906                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8907                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8908                                    + ": match=" + pp.match(path)
8909                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8910                            if (ppwperm != null) {
8911                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8912                                        == PERMISSION_GRANTED) {
8913                                    writeMet = true;
8914                                } else {
8915                                    allowDefaultWrite = false;
8916                                }
8917                            }
8918                        }
8919                    }
8920                }
8921            }
8922
8923            // grant unprotected <provider> read/write, if not blocked by
8924            // <path-permission> above
8925            if (allowDefaultRead) readMet = true;
8926            if (allowDefaultWrite) writeMet = true;
8927
8928        } catch (RemoteException e) {
8929            return false;
8930        }
8931
8932        return readMet && writeMet;
8933    }
8934
8935    public boolean isAppStartModeDisabled(int uid, String packageName) {
8936        synchronized (this) {
8937            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8938                    == ActivityManager.APP_START_MODE_DISABLED;
8939        }
8940    }
8941
8942    // Unified app-op and target sdk check
8943    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8944        // Apps that target O+ are always subject to background check
8945        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8946            if (DEBUG_BACKGROUND_CHECK) {
8947                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8948            }
8949            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8950        }
8951        // ...and legacy apps get an AppOp check
8952        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8953                uid, packageName);
8954        if (DEBUG_BACKGROUND_CHECK) {
8955            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8956        }
8957        switch (appop) {
8958            case AppOpsManager.MODE_ALLOWED:
8959                // If force-background-check is enabled, restrict all apps that aren't whitelisted.
8960                if (mForceBackgroundCheck &&
8961                        !UserHandle.isCore(uid) &&
8962                        !isOnDeviceIdleWhitelistLocked(uid)) {
8963                    if (DEBUG_BACKGROUND_CHECK) {
8964                        Slog.i(TAG, "Force background check: " +
8965                                uid + "/" + packageName + " restricted");
8966                    }
8967                    return ActivityManager.APP_START_MODE_DELAYED;
8968                }
8969                return ActivityManager.APP_START_MODE_NORMAL;
8970            case AppOpsManager.MODE_IGNORED:
8971                return ActivityManager.APP_START_MODE_DELAYED;
8972            default:
8973                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8974        }
8975    }
8976
8977    // Service launch is available to apps with run-in-background exemptions but
8978    // some other background operations are not.  If we're doing a check
8979    // of service-launch policy, allow those callers to proceed unrestricted.
8980    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8981        // Persistent app?
8982        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8983            if (DEBUG_BACKGROUND_CHECK) {
8984                Slog.i(TAG, "App " + uid + "/" + packageName
8985                        + " is persistent; not restricted in background");
8986            }
8987            return ActivityManager.APP_START_MODE_NORMAL;
8988        }
8989
8990        // Non-persistent but background whitelisted?
8991        if (uidOnBackgroundWhitelist(uid)) {
8992            if (DEBUG_BACKGROUND_CHECK) {
8993                Slog.i(TAG, "App " + uid + "/" + packageName
8994                        + " on background whitelist; not restricted in background");
8995            }
8996            return ActivityManager.APP_START_MODE_NORMAL;
8997        }
8998
8999        // Is this app on the battery whitelist?
9000        if (isOnDeviceIdleWhitelistLocked(uid)) {
9001            if (DEBUG_BACKGROUND_CHECK) {
9002                Slog.i(TAG, "App " + uid + "/" + packageName
9003                        + " on idle whitelist; not restricted in background");
9004            }
9005            return ActivityManager.APP_START_MODE_NORMAL;
9006        }
9007
9008        // None of the service-policy criteria apply, so we apply the common criteria
9009        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
9010    }
9011
9012    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
9013            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
9014        UidRecord uidRec = mActiveUids.get(uid);
9015        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
9016                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
9017                + (uidRec != null ? uidRec.idle : false));
9018        if (uidRec == null || alwaysRestrict || uidRec.idle) {
9019            boolean ephemeral;
9020            if (uidRec == null) {
9021                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
9022                        UserHandle.getUserId(uid), packageName);
9023            } else {
9024                ephemeral = uidRec.ephemeral;
9025            }
9026
9027            if (ephemeral) {
9028                // We are hard-core about ephemeral apps not running in the background.
9029                return ActivityManager.APP_START_MODE_DISABLED;
9030            } else {
9031                if (disabledOnly) {
9032                    // The caller is only interested in whether app starts are completely
9033                    // disabled for the given package (that is, it is an instant app).  So
9034                    // we don't need to go further, which is all just seeing if we should
9035                    // apply a "delayed" mode for a regular app.
9036                    return ActivityManager.APP_START_MODE_NORMAL;
9037                }
9038                final int startMode = (alwaysRestrict)
9039                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
9040                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
9041                                packageTargetSdk);
9042                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
9043                        + " pkg=" + packageName + " startMode=" + startMode
9044                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
9045                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
9046                    // This is an old app that has been forced into a "compatible as possible"
9047                    // mode of background check.  To increase compatibility, we will allow other
9048                    // foreground apps to cause its services to start.
9049                    if (callingPid >= 0) {
9050                        ProcessRecord proc;
9051                        synchronized (mPidsSelfLocked) {
9052                            proc = mPidsSelfLocked.get(callingPid);
9053                        }
9054                        if (proc != null &&
9055                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
9056                            // Whoever is instigating this is in the foreground, so we will allow it
9057                            // to go through.
9058                            return ActivityManager.APP_START_MODE_NORMAL;
9059                        }
9060                    }
9061                }
9062                return startMode;
9063            }
9064        }
9065        return ActivityManager.APP_START_MODE_NORMAL;
9066    }
9067
9068    /**
9069     * @return whether a UID is in the system, user or temp doze whitelist.
9070     */
9071    boolean isOnDeviceIdleWhitelistLocked(int uid) {
9072        final int appId = UserHandle.getAppId(uid);
9073        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
9074                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9075                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9076    }
9077
9078    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9079        ProviderInfo pi = null;
9080        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9081        if (cpr != null) {
9082            pi = cpr.info;
9083        } else {
9084            try {
9085                pi = AppGlobals.getPackageManager().resolveContentProvider(
9086                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9087                        userHandle);
9088            } catch (RemoteException ex) {
9089            }
9090        }
9091        return pi;
9092    }
9093
9094    void grantEphemeralAccessLocked(int userId, Intent intent,
9095            int targetAppId, int ephemeralAppId) {
9096        getPackageManagerInternalLocked().
9097                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
9098    }
9099
9100    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
9101        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9102        if (targetUris != null) {
9103            return targetUris.get(grantUri);
9104        }
9105        return null;
9106    }
9107
9108    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
9109            String targetPkg, int targetUid, GrantUri grantUri) {
9110        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9111        if (targetUris == null) {
9112            targetUris = Maps.newArrayMap();
9113            mGrantedUriPermissions.put(targetUid, targetUris);
9114        }
9115
9116        UriPermission perm = targetUris.get(grantUri);
9117        if (perm == null) {
9118            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9119            targetUris.put(grantUri, perm);
9120        }
9121
9122        return perm;
9123    }
9124
9125    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
9126            final int modeFlags) {
9127        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
9128        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9129                : UriPermission.STRENGTH_OWNED;
9130
9131        // Root gets to do everything.
9132        if (uid == 0) {
9133            return true;
9134        }
9135
9136        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9137        if (perms == null) return false;
9138
9139        // First look for exact match
9140        final UriPermission exactPerm = perms.get(grantUri);
9141        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9142            return true;
9143        }
9144
9145        // No exact match, look for prefixes
9146        final int N = perms.size();
9147        for (int i = 0; i < N; i++) {
9148            final UriPermission perm = perms.valueAt(i);
9149            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9150                    && perm.getStrength(modeFlags) >= minStrength) {
9151                return true;
9152            }
9153        }
9154
9155        return false;
9156    }
9157
9158    /**
9159     * @param uri This uri must NOT contain an embedded userId.
9160     * @param userId The userId in which the uri is to be resolved.
9161     */
9162    @Override
9163    public int checkUriPermission(Uri uri, int pid, int uid,
9164            final int modeFlags, int userId, IBinder callerToken) {
9165        enforceNotIsolatedCaller("checkUriPermission");
9166
9167        // Another redirected-binder-call permissions check as in
9168        // {@link checkPermissionWithToken}.
9169        Identity tlsIdentity = sCallerIdentity.get();
9170        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9171            uid = tlsIdentity.uid;
9172            pid = tlsIdentity.pid;
9173        }
9174
9175        // Our own process gets to do everything.
9176        if (pid == MY_PID) {
9177            return PackageManager.PERMISSION_GRANTED;
9178        }
9179        synchronized (this) {
9180            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9181                    ? PackageManager.PERMISSION_GRANTED
9182                    : PackageManager.PERMISSION_DENIED;
9183        }
9184    }
9185
9186    /**
9187     * Check if the targetPkg can be granted permission to access uri by
9188     * the callingUid using the given modeFlags.  Throws a security exception
9189     * if callingUid is not allowed to do this.  Returns the uid of the target
9190     * if the URI permission grant should be performed; returns -1 if it is not
9191     * needed (for example targetPkg already has permission to access the URI).
9192     * If you already know the uid of the target, you can supply it in
9193     * lastTargetUid else set that to -1.
9194     */
9195    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9196            final int modeFlags, int lastTargetUid) {
9197        if (!Intent.isAccessUriMode(modeFlags)) {
9198            return -1;
9199        }
9200
9201        if (targetPkg != null) {
9202            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9203                    "Checking grant " + targetPkg + " permission to " + grantUri);
9204        }
9205
9206        final IPackageManager pm = AppGlobals.getPackageManager();
9207
9208        // If this is not a content: uri, we can't do anything with it.
9209        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9210            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9211                    "Can't grant URI permission for non-content URI: " + grantUri);
9212            return -1;
9213        }
9214
9215        // Bail early if system is trying to hand out permissions directly; it
9216        // must always grant permissions on behalf of someone explicit.
9217        final int callingAppId = UserHandle.getAppId(callingUid);
9218        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9219            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9220                // Exempted authority for
9221                // 1. cropping user photos and sharing a generated license html
9222                //    file in Settings app
9223                // 2. sharing a generated license html file in TvSettings app
9224            } else {
9225                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9226                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9227                return -1;
9228            }
9229        }
9230
9231        final String authority = grantUri.uri.getAuthority();
9232        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9233                MATCH_DEBUG_TRIAGED_MISSING);
9234        if (pi == null) {
9235            Slog.w(TAG, "No content provider found for permission check: " +
9236                    grantUri.uri.toSafeString());
9237            return -1;
9238        }
9239
9240        int targetUid = lastTargetUid;
9241        if (targetUid < 0 && targetPkg != null) {
9242            try {
9243                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9244                        UserHandle.getUserId(callingUid));
9245                if (targetUid < 0) {
9246                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9247                            "Can't grant URI permission no uid for: " + targetPkg);
9248                    return -1;
9249                }
9250            } catch (RemoteException ex) {
9251                return -1;
9252            }
9253        }
9254
9255        // If we're extending a persistable grant, then we always need to create
9256        // the grant data structure so that take/release APIs work
9257        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9258            return targetUid;
9259        }
9260
9261        if (targetUid >= 0) {
9262            // First...  does the target actually need this permission?
9263            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9264                // No need to grant the target this permission.
9265                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9266                        "Target " + targetPkg + " already has full permission to " + grantUri);
9267                return -1;
9268            }
9269        } else {
9270            // First...  there is no target package, so can anyone access it?
9271            boolean allowed = pi.exported;
9272            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9273                if (pi.readPermission != null) {
9274                    allowed = false;
9275                }
9276            }
9277            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9278                if (pi.writePermission != null) {
9279                    allowed = false;
9280                }
9281            }
9282            if (allowed) {
9283                return -1;
9284            }
9285        }
9286
9287        /* There is a special cross user grant if:
9288         * - The target is on another user.
9289         * - Apps on the current user can access the uri without any uid permissions.
9290         * In this case, we grant a uri permission, even if the ContentProvider does not normally
9291         * grant uri permissions.
9292         */
9293        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9294                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9295                modeFlags, false /*without considering the uid permissions*/);
9296
9297        // Second...  is the provider allowing granting of URI permissions?
9298        if (!specialCrossUserGrant) {
9299            if (!pi.grantUriPermissions) {
9300                throw new SecurityException("Provider " + pi.packageName
9301                        + "/" + pi.name
9302                        + " does not allow granting of Uri permissions (uri "
9303                        + grantUri + ")");
9304            }
9305            if (pi.uriPermissionPatterns != null) {
9306                final int N = pi.uriPermissionPatterns.length;
9307                boolean allowed = false;
9308                for (int i=0; i<N; i++) {
9309                    if (pi.uriPermissionPatterns[i] != null
9310                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9311                        allowed = true;
9312                        break;
9313                    }
9314                }
9315                if (!allowed) {
9316                    throw new SecurityException("Provider " + pi.packageName
9317                            + "/" + pi.name
9318                            + " does not allow granting of permission to path of Uri "
9319                            + grantUri);
9320                }
9321            }
9322        }
9323
9324        // Third...  does the caller itself have permission to access
9325        // this uri?
9326        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9327            // Require they hold a strong enough Uri permission
9328            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9329                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9330                    throw new SecurityException(
9331                            "UID " + callingUid + " does not have permission to " + grantUri
9332                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9333                                    + "or related APIs");
9334                } else {
9335                    throw new SecurityException(
9336                            "UID " + callingUid + " does not have permission to " + grantUri);
9337                }
9338            }
9339        }
9340        return targetUid;
9341    }
9342
9343    /**
9344     * @param uri This uri must NOT contain an embedded userId.
9345     * @param userId The userId in which the uri is to be resolved.
9346     */
9347    @Override
9348    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9349            final int modeFlags, int userId) {
9350        enforceNotIsolatedCaller("checkGrantUriPermission");
9351        synchronized(this) {
9352            return checkGrantUriPermissionLocked(callingUid, targetPkg,
9353                    new GrantUri(userId, uri, false), modeFlags, -1);
9354        }
9355    }
9356
9357    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9358            final int modeFlags, UriPermissionOwner owner) {
9359        if (!Intent.isAccessUriMode(modeFlags)) {
9360            return;
9361        }
9362
9363        // So here we are: the caller has the assumed permission
9364        // to the uri, and the target doesn't.  Let's now give this to
9365        // the target.
9366
9367        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9368                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9369
9370        final String authority = grantUri.uri.getAuthority();
9371        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9372                MATCH_DEBUG_TRIAGED_MISSING);
9373        if (pi == null) {
9374            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9375            return;
9376        }
9377
9378        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9379            grantUri.prefix = true;
9380        }
9381        final UriPermission perm = findOrCreateUriPermissionLocked(
9382                pi.packageName, targetPkg, targetUid, grantUri);
9383        perm.grantModes(modeFlags, owner);
9384    }
9385
9386    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9387            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9388        if (targetPkg == null) {
9389            throw new NullPointerException("targetPkg");
9390        }
9391        int targetUid;
9392        final IPackageManager pm = AppGlobals.getPackageManager();
9393        try {
9394            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9395        } catch (RemoteException ex) {
9396            return;
9397        }
9398
9399        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9400                targetUid);
9401        if (targetUid < 0) {
9402            return;
9403        }
9404
9405        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9406                owner);
9407    }
9408
9409    static class NeededUriGrants extends ArrayList<GrantUri> {
9410        final String targetPkg;
9411        final int targetUid;
9412        final int flags;
9413
9414        NeededUriGrants(String targetPkg, int targetUid, int flags) {
9415            this.targetPkg = targetPkg;
9416            this.targetUid = targetUid;
9417            this.flags = flags;
9418        }
9419
9420        void writeToProto(ProtoOutputStream proto, long fieldId) {
9421            long token = proto.start(fieldId);
9422            proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9423            proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9424            proto.write(NeededUriGrantsProto.FLAGS, flags);
9425
9426            final int N = this.size();
9427            for (int i=0; i<N; i++) {
9428                this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9429            }
9430            proto.end(token);
9431        }
9432    }
9433
9434    /**
9435     * Like checkGrantUriPermissionLocked, but takes an Intent.
9436     */
9437    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9438            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9439        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9440                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9441                + " clip=" + (intent != null ? intent.getClipData() : null)
9442                + " from " + intent + "; flags=0x"
9443                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9444
9445        if (targetPkg == null) {
9446            throw new NullPointerException("targetPkg");
9447        }
9448
9449        if (intent == null) {
9450            return null;
9451        }
9452        Uri data = intent.getData();
9453        ClipData clip = intent.getClipData();
9454        if (data == null && clip == null) {
9455            return null;
9456        }
9457        // Default userId for uris in the intent (if they don't specify it themselves)
9458        int contentUserHint = intent.getContentUserHint();
9459        if (contentUserHint == UserHandle.USER_CURRENT) {
9460            contentUserHint = UserHandle.getUserId(callingUid);
9461        }
9462        final IPackageManager pm = AppGlobals.getPackageManager();
9463        int targetUid;
9464        if (needed != null) {
9465            targetUid = needed.targetUid;
9466        } else {
9467            try {
9468                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9469                        targetUserId);
9470            } catch (RemoteException ex) {
9471                return null;
9472            }
9473            if (targetUid < 0) {
9474                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9475                        "Can't grant URI permission no uid for: " + targetPkg
9476                        + " on user " + targetUserId);
9477                return null;
9478            }
9479        }
9480        if (data != null) {
9481            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9482            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9483                    targetUid);
9484            if (targetUid > 0) {
9485                if (needed == null) {
9486                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9487                }
9488                needed.add(grantUri);
9489            }
9490        }
9491        if (clip != null) {
9492            for (int i=0; i<clip.getItemCount(); i++) {
9493                Uri uri = clip.getItemAt(i).getUri();
9494                if (uri != null) {
9495                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9496                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9497                            targetUid);
9498                    if (targetUid > 0) {
9499                        if (needed == null) {
9500                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9501                        }
9502                        needed.add(grantUri);
9503                    }
9504                } else {
9505                    Intent clipIntent = clip.getItemAt(i).getIntent();
9506                    if (clipIntent != null) {
9507                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9508                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9509                        if (newNeeded != null) {
9510                            needed = newNeeded;
9511                        }
9512                    }
9513                }
9514            }
9515        }
9516
9517        return needed;
9518    }
9519
9520    /**
9521     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9522     */
9523    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9524            UriPermissionOwner owner) {
9525        if (needed != null) {
9526            for (int i=0; i<needed.size(); i++) {
9527                GrantUri grantUri = needed.get(i);
9528                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9529                        grantUri, needed.flags, owner);
9530            }
9531        }
9532    }
9533
9534    void grantUriPermissionFromIntentLocked(int callingUid,
9535            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9536        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9537                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9538        if (needed == null) {
9539            return;
9540        }
9541
9542        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9543    }
9544
9545    /**
9546     * @param uri This uri must NOT contain an embedded userId.
9547     * @param userId The userId in which the uri is to be resolved.
9548     */
9549    @Override
9550    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9551            final int modeFlags, int userId) {
9552        enforceNotIsolatedCaller("grantUriPermission");
9553        GrantUri grantUri = new GrantUri(userId, uri, false);
9554        synchronized(this) {
9555            final ProcessRecord r = getRecordForAppLocked(caller);
9556            if (r == null) {
9557                throw new SecurityException("Unable to find app for caller "
9558                        + caller
9559                        + " when granting permission to uri " + grantUri);
9560            }
9561            if (targetPkg == null) {
9562                throw new IllegalArgumentException("null target");
9563            }
9564            if (grantUri == null) {
9565                throw new IllegalArgumentException("null uri");
9566            }
9567
9568            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9569                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9570                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9571                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9572
9573            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9574                    UserHandle.getUserId(r.uid));
9575        }
9576    }
9577
9578    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9579        if (perm.modeFlags == 0) {
9580            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9581                    perm.targetUid);
9582            if (perms != null) {
9583                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9584                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9585
9586                perms.remove(perm.uri);
9587                if (perms.isEmpty()) {
9588                    mGrantedUriPermissions.remove(perm.targetUid);
9589                }
9590            }
9591        }
9592    }
9593
9594    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9595            final int modeFlags) {
9596        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9597                "Revoking all granted permissions to " + grantUri);
9598
9599        final IPackageManager pm = AppGlobals.getPackageManager();
9600        final String authority = grantUri.uri.getAuthority();
9601        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9602                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9603        if (pi == null) {
9604            Slog.w(TAG, "No content provider found for permission revoke: "
9605                    + grantUri.toSafeString());
9606            return;
9607        }
9608
9609        // Does the caller have this permission on the URI?
9610        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9611            // If they don't have direct access to the URI, then revoke any
9612            // ownerless URI permissions that have been granted to them.
9613            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9614            if (perms != null) {
9615                boolean persistChanged = false;
9616                for (int i = perms.size()-1; i >= 0; i--) {
9617                    final UriPermission perm = perms.valueAt(i);
9618                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9619                        continue;
9620                    }
9621                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9622                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9623                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9624                                "Revoking non-owned " + perm.targetUid
9625                                + " permission to " + perm.uri);
9626                        persistChanged |= perm.revokeModes(
9627                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9628                        if (perm.modeFlags == 0) {
9629                            perms.removeAt(i);
9630                        }
9631                    }
9632                }
9633                if (perms.isEmpty()) {
9634                    mGrantedUriPermissions.remove(callingUid);
9635                }
9636                if (persistChanged) {
9637                    schedulePersistUriGrants();
9638                }
9639            }
9640            return;
9641        }
9642
9643        boolean persistChanged = false;
9644
9645        // Go through all of the permissions and remove any that match.
9646        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9647            final int targetUid = mGrantedUriPermissions.keyAt(i);
9648            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9649
9650            for (int j = perms.size()-1; j >= 0; j--) {
9651                final UriPermission perm = perms.valueAt(j);
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 " + perm.targetUid + " permission to " + perm.uri);
9659                    persistChanged |= perm.revokeModes(
9660                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9661                            targetPackage == null);
9662                    if (perm.modeFlags == 0) {
9663                        perms.removeAt(j);
9664                    }
9665                }
9666            }
9667
9668            if (perms.isEmpty()) {
9669                mGrantedUriPermissions.removeAt(i);
9670            }
9671        }
9672
9673        if (persistChanged) {
9674            schedulePersistUriGrants();
9675        }
9676    }
9677
9678    /**
9679     * @param uri This uri must NOT contain an embedded userId.
9680     * @param userId The userId in which the uri is to be resolved.
9681     */
9682    @Override
9683    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9684            final int modeFlags, int userId) {
9685        enforceNotIsolatedCaller("revokeUriPermission");
9686        synchronized(this) {
9687            final ProcessRecord r = getRecordForAppLocked(caller);
9688            if (r == null) {
9689                throw new SecurityException("Unable to find app for caller "
9690                        + caller
9691                        + " when revoking permission to uri " + uri);
9692            }
9693            if (uri == null) {
9694                Slog.w(TAG, "revokeUriPermission: null uri");
9695                return;
9696            }
9697
9698            if (!Intent.isAccessUriMode(modeFlags)) {
9699                return;
9700            }
9701
9702            final String authority = uri.getAuthority();
9703            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9704                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9705            if (pi == null) {
9706                Slog.w(TAG, "No content provider found for permission revoke: "
9707                        + uri.toSafeString());
9708                return;
9709            }
9710
9711            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9712                    modeFlags);
9713        }
9714    }
9715
9716    /**
9717     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9718     * given package.
9719     *
9720     * @param packageName Package name to match, or {@code null} to apply to all
9721     *            packages.
9722     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9723     *            to all users.
9724     * @param persistable If persistable grants should be removed.
9725     * @param targetOnly When {@code true}, only remove permissions where the app is the target,
9726     * not source.
9727     */
9728    private void removeUriPermissionsForPackageLocked(
9729            String packageName, int userHandle, boolean persistable, boolean targetOnly) {
9730        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9731            throw new IllegalArgumentException("Must narrow by either package or user");
9732        }
9733
9734        boolean persistChanged = false;
9735
9736        int N = mGrantedUriPermissions.size();
9737        for (int i = 0; i < N; i++) {
9738            final int targetUid = mGrantedUriPermissions.keyAt(i);
9739            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9740
9741            // Only inspect grants matching user
9742            if (userHandle == UserHandle.USER_ALL
9743                    || userHandle == UserHandle.getUserId(targetUid)) {
9744                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9745                    final UriPermission perm = it.next();
9746
9747                    // Only inspect grants matching package
9748                    if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
9749                            || perm.targetPkg.equals(packageName)) {
9750                        // Hacky solution as part of fixing a security bug; ignore
9751                        // grants associated with DownloadManager so we don't have
9752                        // to immediately launch it to regrant the permissions
9753                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9754                                && !persistable) continue;
9755
9756                        persistChanged |= perm.revokeModes(persistable
9757                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9758
9759                        // Only remove when no modes remain; any persisted grants
9760                        // will keep this alive.
9761                        if (perm.modeFlags == 0) {
9762                            it.remove();
9763                        }
9764                    }
9765                }
9766
9767                if (perms.isEmpty()) {
9768                    mGrantedUriPermissions.remove(targetUid);
9769                    N--;
9770                    i--;
9771                }
9772            }
9773        }
9774
9775        if (persistChanged) {
9776            schedulePersistUriGrants();
9777        }
9778    }
9779
9780    @Override
9781    public IBinder newUriPermissionOwner(String name) {
9782        enforceNotIsolatedCaller("newUriPermissionOwner");
9783        synchronized(this) {
9784            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9785            return owner.getExternalTokenLocked();
9786        }
9787    }
9788
9789    @Override
9790    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9791        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9792        synchronized(this) {
9793            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9794            if (r == null) {
9795                throw new IllegalArgumentException("Activity does not exist; token="
9796                        + activityToken);
9797            }
9798            return r.getUriPermissionsLocked().getExternalTokenLocked();
9799        }
9800    }
9801    /**
9802     * @param uri This uri must NOT contain an embedded userId.
9803     * @param sourceUserId The userId in which the uri is to be resolved.
9804     * @param targetUserId The userId of the app that receives the grant.
9805     */
9806    @Override
9807    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9808            final int modeFlags, int sourceUserId, int targetUserId) {
9809        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9810                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9811                "grantUriPermissionFromOwner", null);
9812        synchronized(this) {
9813            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9814            if (owner == null) {
9815                throw new IllegalArgumentException("Unknown owner: " + token);
9816            }
9817            if (fromUid != Binder.getCallingUid()) {
9818                if (Binder.getCallingUid() != myUid()) {
9819                    // Only system code can grant URI permissions on behalf
9820                    // of other users.
9821                    throw new SecurityException("nice try");
9822                }
9823            }
9824            if (targetPkg == null) {
9825                throw new IllegalArgumentException("null target");
9826            }
9827            if (uri == null) {
9828                throw new IllegalArgumentException("null uri");
9829            }
9830
9831            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9832                    modeFlags, owner, targetUserId);
9833        }
9834    }
9835
9836    /**
9837     * @param uri This uri must NOT contain an embedded userId.
9838     * @param userId The userId in which the uri is to be resolved.
9839     */
9840    @Override
9841    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9842        synchronized(this) {
9843            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9844            if (owner == null) {
9845                throw new IllegalArgumentException("Unknown owner: " + token);
9846            }
9847
9848            if (uri == null) {
9849                owner.removeUriPermissionsLocked(mode);
9850            } else {
9851                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9852                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9853            }
9854        }
9855    }
9856
9857    private void schedulePersistUriGrants() {
9858        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9859            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9860                    10 * DateUtils.SECOND_IN_MILLIS);
9861        }
9862    }
9863
9864    private void writeGrantedUriPermissions() {
9865        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9866
9867        final long startTime = SystemClock.uptimeMillis();
9868
9869        // Snapshot permissions so we can persist without lock
9870        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9871        synchronized (this) {
9872            final int size = mGrantedUriPermissions.size();
9873            for (int i = 0; i < size; i++) {
9874                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9875                for (UriPermission perm : perms.values()) {
9876                    if (perm.persistedModeFlags != 0) {
9877                        persist.add(perm.snapshot());
9878                    }
9879                }
9880            }
9881        }
9882
9883        FileOutputStream fos = null;
9884        try {
9885            fos = mGrantFile.startWrite(startTime);
9886
9887            XmlSerializer out = new FastXmlSerializer();
9888            out.setOutput(fos, StandardCharsets.UTF_8.name());
9889            out.startDocument(null, true);
9890            out.startTag(null, TAG_URI_GRANTS);
9891            for (UriPermission.Snapshot perm : persist) {
9892                out.startTag(null, TAG_URI_GRANT);
9893                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9894                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9895                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9896                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9897                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9898                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9899                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9900                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9901                out.endTag(null, TAG_URI_GRANT);
9902            }
9903            out.endTag(null, TAG_URI_GRANTS);
9904            out.endDocument();
9905
9906            mGrantFile.finishWrite(fos);
9907        } catch (IOException e) {
9908            if (fos != null) {
9909                mGrantFile.failWrite(fos);
9910            }
9911        }
9912    }
9913
9914    private void readGrantedUriPermissionsLocked() {
9915        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9916
9917        final long now = System.currentTimeMillis();
9918
9919        FileInputStream fis = null;
9920        try {
9921            fis = mGrantFile.openRead();
9922            final XmlPullParser in = Xml.newPullParser();
9923            in.setInput(fis, StandardCharsets.UTF_8.name());
9924
9925            int type;
9926            while ((type = in.next()) != END_DOCUMENT) {
9927                final String tag = in.getName();
9928                if (type == START_TAG) {
9929                    if (TAG_URI_GRANT.equals(tag)) {
9930                        final int sourceUserId;
9931                        final int targetUserId;
9932                        final int userHandle = readIntAttribute(in,
9933                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9934                        if (userHandle != UserHandle.USER_NULL) {
9935                            // For backwards compatibility.
9936                            sourceUserId = userHandle;
9937                            targetUserId = userHandle;
9938                        } else {
9939                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9940                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9941                        }
9942                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9943                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9944                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9945                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9946                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9947                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9948
9949                        // Sanity check that provider still belongs to source package
9950                        // Both direct boot aware and unaware packages are fine as we
9951                        // will do filtering at query time to avoid multiple parsing.
9952                        final ProviderInfo pi = getProviderInfoLocked(
9953                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9954                                        | MATCH_DIRECT_BOOT_UNAWARE);
9955                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9956                            int targetUid = -1;
9957                            try {
9958                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9959                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9960                            } catch (RemoteException e) {
9961                            }
9962                            if (targetUid != -1) {
9963                                final UriPermission perm = findOrCreateUriPermissionLocked(
9964                                        sourcePkg, targetPkg, targetUid,
9965                                        new GrantUri(sourceUserId, uri, prefix));
9966                                perm.initPersistedModes(modeFlags, createdTime);
9967                            }
9968                        } else {
9969                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9970                                    + " but instead found " + pi);
9971                        }
9972                    }
9973                }
9974            }
9975        } catch (FileNotFoundException e) {
9976            // Missing grants is okay
9977        } catch (IOException e) {
9978            Slog.wtf(TAG, "Failed reading Uri grants", e);
9979        } catch (XmlPullParserException e) {
9980            Slog.wtf(TAG, "Failed reading Uri grants", e);
9981        } finally {
9982            IoUtils.closeQuietly(fis);
9983        }
9984    }
9985
9986    /**
9987     * @param uri This uri must NOT contain an embedded userId.
9988     * @param userId The userId in which the uri is to be resolved.
9989     */
9990    @Override
9991    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9992        enforceNotIsolatedCaller("takePersistableUriPermission");
9993
9994        Preconditions.checkFlagsArgument(modeFlags,
9995                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9996
9997        synchronized (this) {
9998            final int callingUid = Binder.getCallingUid();
9999            boolean persistChanged = false;
10000            GrantUri grantUri = new GrantUri(userId, uri, false);
10001
10002            UriPermission exactPerm = findUriPermissionLocked(callingUid, grantUri);
10003            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
10004                    new GrantUri(userId, uri, true));
10005
10006            final boolean exactValid = (exactPerm != null)
10007                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
10008            final boolean prefixValid = (prefixPerm != null)
10009                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
10010
10011            if (!(exactValid || prefixValid)) {
10012                throw new SecurityException("No persistable permission grants found for UID "
10013                        + callingUid + " and Uri " + grantUri.toSafeString());
10014            }
10015
10016            if (exactValid) {
10017                persistChanged |= exactPerm.takePersistableModes(modeFlags);
10018            }
10019            if (prefixValid) {
10020                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
10021            }
10022
10023            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
10024
10025            if (persistChanged) {
10026                schedulePersistUriGrants();
10027            }
10028        }
10029    }
10030
10031    /**
10032     * @param uri This uri must NOT contain an embedded userId.
10033     * @param userId The userId in which the uri is to be resolved.
10034     */
10035    @Override
10036    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
10037        enforceNotIsolatedCaller("releasePersistableUriPermission");
10038
10039        Preconditions.checkFlagsArgument(modeFlags,
10040                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10041
10042        synchronized (this) {
10043            final int callingUid = Binder.getCallingUid();
10044            boolean persistChanged = false;
10045
10046            UriPermission exactPerm = findUriPermissionLocked(callingUid,
10047                    new GrantUri(userId, uri, false));
10048            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
10049                    new GrantUri(userId, uri, true));
10050            if (exactPerm == null && prefixPerm == null) {
10051                throw new SecurityException("No permission grants found for UID " + callingUid
10052                        + " and Uri " + uri.toSafeString());
10053            }
10054
10055            if (exactPerm != null) {
10056                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10057                removeUriPermissionIfNeededLocked(exactPerm);
10058            }
10059            if (prefixPerm != null) {
10060                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10061                removeUriPermissionIfNeededLocked(prefixPerm);
10062            }
10063
10064            if (persistChanged) {
10065                schedulePersistUriGrants();
10066            }
10067        }
10068    }
10069
10070    /**
10071     * Prune any older {@link UriPermission} for the given UID until outstanding
10072     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10073     *
10074     * @return if any mutations occured that require persisting.
10075     */
10076    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
10077        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
10078        if (perms == null) return false;
10079        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
10080
10081        final ArrayList<UriPermission> persisted = Lists.newArrayList();
10082        for (UriPermission perm : perms.values()) {
10083            if (perm.persistedModeFlags != 0) {
10084                persisted.add(perm);
10085            }
10086        }
10087
10088        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10089        if (trimCount <= 0) return false;
10090
10091        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10092        for (int i = 0; i < trimCount; i++) {
10093            final UriPermission perm = persisted.get(i);
10094
10095            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10096                    "Trimming grant created at " + perm.persistedCreateTime);
10097
10098            perm.releasePersistableModes(~0);
10099            removeUriPermissionIfNeededLocked(perm);
10100        }
10101
10102        return true;
10103    }
10104
10105    @Override
10106    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10107            String packageName, boolean incoming) {
10108        enforceNotIsolatedCaller("getPersistedUriPermissions");
10109        Preconditions.checkNotNull(packageName, "packageName");
10110
10111        final int callingUid = Binder.getCallingUid();
10112        final int callingUserId = UserHandle.getUserId(callingUid);
10113        final IPackageManager pm = AppGlobals.getPackageManager();
10114        try {
10115            final int packageUid = pm.getPackageUid(packageName,
10116                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
10117            if (packageUid != callingUid) {
10118                throw new SecurityException(
10119                        "Package " + packageName + " does not belong to calling UID " + callingUid);
10120            }
10121        } catch (RemoteException e) {
10122            throw new SecurityException("Failed to verify package name ownership");
10123        }
10124
10125        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10126        synchronized (this) {
10127            if (incoming) {
10128                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10129                        callingUid);
10130                if (perms == null) {
10131                    Slog.w(TAG, "No permission grants found for " + packageName);
10132                } else {
10133                    for (int j = 0; j < perms.size(); j++) {
10134                        final UriPermission perm = perms.valueAt(j);
10135                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10136                            result.add(perm.buildPersistedPublicApiObject());
10137                        }
10138                    }
10139                }
10140            } else {
10141                final int size = mGrantedUriPermissions.size();
10142                for (int i = 0; i < size; i++) {
10143                    final ArrayMap<GrantUri, UriPermission> perms =
10144                            mGrantedUriPermissions.valueAt(i);
10145                    for (int j = 0; j < perms.size(); j++) {
10146                        final UriPermission perm = perms.valueAt(j);
10147                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10148                            result.add(perm.buildPersistedPublicApiObject());
10149                        }
10150                    }
10151                }
10152            }
10153        }
10154        return new ParceledListSlice<android.content.UriPermission>(result);
10155    }
10156
10157    @Override
10158    public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
10159            @Nullable String packageName, int userId) {
10160        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10161                "getGrantedUriPermissions");
10162
10163        final List<GrantedUriPermission> result = new ArrayList<>();
10164        synchronized (this) {
10165            final int size = mGrantedUriPermissions.size();
10166            for (int i = 0; i < size; i++) {
10167                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10168                for (int j = 0; j < perms.size(); j++) {
10169                    final UriPermission perm = perms.valueAt(j);
10170                    if ((packageName == null || packageName.equals(perm.targetPkg))
10171                            && perm.targetUserId == userId
10172                            && perm.persistedModeFlags != 0) {
10173                        result.add(perm.buildGrantedUriPermission());
10174                    }
10175                }
10176            }
10177        }
10178        return new ParceledListSlice<>(result);
10179    }
10180
10181    @Override
10182    public void clearGrantedUriPermissions(String packageName, int userId) {
10183        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10184                "clearGrantedUriPermissions");
10185        synchronized(this) {
10186            removeUriPermissionsForPackageLocked(packageName, userId, true, true);
10187        }
10188    }
10189
10190    @Override
10191    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10192        synchronized (this) {
10193            ProcessRecord app =
10194                who != null ? getRecordForAppLocked(who) : null;
10195            if (app == null) return;
10196
10197            Message msg = Message.obtain();
10198            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10199            msg.obj = app;
10200            msg.arg1 = waiting ? 1 : 0;
10201            mUiHandler.sendMessage(msg);
10202        }
10203    }
10204
10205    @Override
10206    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10207        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10208        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10209        outInfo.availMem = getFreeMemory();
10210        outInfo.totalMem = getTotalMemory();
10211        outInfo.threshold = homeAppMem;
10212        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10213        outInfo.hiddenAppThreshold = cachedAppMem;
10214        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10215                ProcessList.SERVICE_ADJ);
10216        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10217                ProcessList.VISIBLE_APP_ADJ);
10218        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10219                ProcessList.FOREGROUND_APP_ADJ);
10220    }
10221
10222    // =========================================================
10223    // TASK MANAGEMENT
10224    // =========================================================
10225
10226    @Override
10227    public List<IBinder> getAppTasks(String callingPackage) {
10228        int callingUid = Binder.getCallingUid();
10229        long ident = Binder.clearCallingIdentity();
10230        try {
10231            synchronized(this) {
10232                return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10233            }
10234        } finally {
10235            Binder.restoreCallingIdentity(ident);
10236        }
10237    }
10238
10239    @Override
10240    public List<RunningTaskInfo> getTasks(int maxNum) {
10241       return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10242    }
10243
10244    @Override
10245    public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10246            @WindowingMode int ignoreWindowingMode) {
10247        final int callingUid = Binder.getCallingUid();
10248        ArrayList<RunningTaskInfo> list = new ArrayList<>();
10249
10250        synchronized(this) {
10251            if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10252
10253            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10254                    callingUid);
10255            mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10256                    ignoreWindowingMode, callingUid, allowed);
10257        }
10258
10259        return list;
10260    }
10261
10262    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10263        if (mRecentTasks.isCallerRecents(callingUid)) {
10264            // Always allow the recents component to get tasks
10265            return true;
10266        }
10267
10268        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10269                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10270        if (!allowed) {
10271            if (checkPermission(android.Manifest.permission.GET_TASKS,
10272                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10273                // Temporary compatibility: some existing apps on the system image may
10274                // still be requesting the old permission and not switched to the new
10275                // one; if so, we'll still allow them full access.  This means we need
10276                // to see if they are holding the old permission and are a system app.
10277                try {
10278                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10279                        allowed = true;
10280                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10281                                + " is using old GET_TASKS but privileged; allowing");
10282                    }
10283                } catch (RemoteException e) {
10284                }
10285            }
10286        }
10287        if (!allowed) {
10288            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10289                    + " does not hold REAL_GET_TASKS; limiting output");
10290        }
10291        return allowed;
10292    }
10293
10294    @Override
10295    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10296            int userId) {
10297        final int callingUid = Binder.getCallingUid();
10298        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10299                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10300        final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10301                callingUid);
10302        final boolean detailed = checkCallingPermission(
10303                android.Manifest.permission.GET_DETAILED_TASKS)
10304                        == PackageManager.PERMISSION_GRANTED;
10305
10306        synchronized (this) {
10307            return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10308                    callingUid);
10309        }
10310    }
10311
10312    @Override
10313    public ActivityManager.TaskDescription getTaskDescription(int id) {
10314        synchronized (this) {
10315            enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10316            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10317                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10318            if (tr != null) {
10319                return tr.lastTaskDescription;
10320            }
10321        }
10322        return null;
10323    }
10324
10325    @Override
10326    public int addAppTask(IBinder activityToken, Intent intent,
10327            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10328        final int callingUid = Binder.getCallingUid();
10329        final long callingIdent = Binder.clearCallingIdentity();
10330
10331        try {
10332            synchronized (this) {
10333                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10334                if (r == null) {
10335                    throw new IllegalArgumentException("Activity does not exist; token="
10336                            + activityToken);
10337                }
10338                ComponentName comp = intent.getComponent();
10339                if (comp == null) {
10340                    throw new IllegalArgumentException("Intent " + intent
10341                            + " must specify explicit component");
10342                }
10343                if (thumbnail.getWidth() != mThumbnailWidth
10344                        || thumbnail.getHeight() != mThumbnailHeight) {
10345                    throw new IllegalArgumentException("Bad thumbnail size: got "
10346                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10347                            + mThumbnailWidth + "x" + mThumbnailHeight);
10348                }
10349                if (intent.getSelector() != null) {
10350                    intent.setSelector(null);
10351                }
10352                if (intent.getSourceBounds() != null) {
10353                    intent.setSourceBounds(null);
10354                }
10355                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10356                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10357                        // The caller has added this as an auto-remove task...  that makes no
10358                        // sense, so turn off auto-remove.
10359                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10360                    }
10361                }
10362                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10363                    mLastAddedTaskActivity = null;
10364                }
10365                ActivityInfo ainfo = mLastAddedTaskActivity;
10366                if (ainfo == null) {
10367                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10368                            comp, 0, UserHandle.getUserId(callingUid));
10369                    if (ainfo.applicationInfo.uid != callingUid) {
10370                        throw new SecurityException(
10371                                "Can't add task for another application: target uid="
10372                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10373                    }
10374                }
10375
10376                TaskRecord task = TaskRecord.create(this,
10377                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10378                        ainfo, intent, description);
10379                if (!mRecentTasks.addToBottom(task)) {
10380                    return INVALID_TASK_ID;
10381                }
10382                r.getStack().addTask(task, !ON_TOP, "addAppTask");
10383
10384                // TODO: Send the thumbnail to WM to store it.
10385
10386                return task.taskId;
10387            }
10388        } finally {
10389            Binder.restoreCallingIdentity(callingIdent);
10390        }
10391    }
10392
10393    @Override
10394    public Point getAppTaskThumbnailSize() {
10395        synchronized (this) {
10396            return new Point(mThumbnailWidth,  mThumbnailHeight);
10397        }
10398    }
10399
10400    @Override
10401    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10402        synchronized (this) {
10403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10404            if (r != null) {
10405                r.setTaskDescription(td);
10406                final TaskRecord task = r.getTask();
10407                task.updateTaskDescription();
10408                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10409            }
10410        }
10411    }
10412
10413    @Override
10414    public void setTaskResizeable(int taskId, int resizeableMode) {
10415        synchronized (this) {
10416            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10417                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10418            if (task == null) {
10419                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10420                return;
10421            }
10422            task.setResizeMode(resizeableMode);
10423        }
10424    }
10425
10426    @Override
10427    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10428        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10429        long ident = Binder.clearCallingIdentity();
10430        try {
10431            synchronized (this) {
10432                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10433                if (task == null) {
10434                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10435                    return;
10436                }
10437                // Place the task in the right stack if it isn't there already based on
10438                // the requested bounds.
10439                // The stack transition logic is:
10440                // - a null bounds on a freeform task moves that task to fullscreen
10441                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10442                //   that task to freeform
10443                // - otherwise the task is not moved
10444                ActivityStack stack = task.getStack();
10445                if (!task.getWindowConfiguration().canResizeTask()) {
10446                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10447                }
10448                if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10449                    stack = stack.getDisplay().getOrCreateStack(
10450                            WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10451                } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10452                    stack = stack.getDisplay().getOrCreateStack(
10453                            WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10454                }
10455
10456                // Reparent the task to the right stack if necessary
10457                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10458                if (stack != task.getStack()) {
10459                    // Defer resume until the task is resized below
10460                    task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10461                            DEFER_RESUME, "resizeTask");
10462                    preserveWindow = false;
10463                }
10464
10465                // After reparenting (which only resizes the task to the stack bounds), resize the
10466                // task to the actual bounds provided
10467                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10468            }
10469        } finally {
10470            Binder.restoreCallingIdentity(ident);
10471        }
10472    }
10473
10474    @Override
10475    public Rect getTaskBounds(int taskId) {
10476        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10477        long ident = Binder.clearCallingIdentity();
10478        Rect rect = new Rect();
10479        try {
10480            synchronized (this) {
10481                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10482                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10483                if (task == null) {
10484                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10485                    return rect;
10486                }
10487                if (task.getStack() != null) {
10488                    // Return the bounds from window manager since it will be adjusted for various
10489                    // things like the presense of a docked stack for tasks that aren't resizeable.
10490                    task.getWindowContainerBounds(rect);
10491                } else {
10492                    // Task isn't in window manager yet since it isn't associated with a stack.
10493                    // Return the persist value from activity manager
10494                    if (!task.matchParentBounds()) {
10495                        rect.set(task.getBounds());
10496                    } else if (task.mLastNonFullscreenBounds != null) {
10497                        rect.set(task.mLastNonFullscreenBounds);
10498                    }
10499                }
10500            }
10501        } finally {
10502            Binder.restoreCallingIdentity(ident);
10503        }
10504        return rect;
10505    }
10506
10507    @Override
10508    public void cancelTaskWindowTransition(int taskId) {
10509        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10510                "cancelTaskWindowTransition()");
10511        final long ident = Binder.clearCallingIdentity();
10512        try {
10513            synchronized (this) {
10514                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10515                        MATCH_TASK_IN_STACKS_ONLY);
10516                if (task == null) {
10517                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10518                    return;
10519                }
10520                task.cancelWindowTransition();
10521            }
10522        } finally {
10523            Binder.restoreCallingIdentity(ident);
10524        }
10525    }
10526
10527    @Override
10528    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10529        enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10530        final long ident = Binder.clearCallingIdentity();
10531        try {
10532            final TaskRecord task;
10533            synchronized (this) {
10534                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10535                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10536                if (task == null) {
10537                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10538                    return null;
10539                }
10540            }
10541            // Don't call this while holding the lock as this operation might hit the disk.
10542            return task.getSnapshot(reducedResolution);
10543        } finally {
10544            Binder.restoreCallingIdentity(ident);
10545        }
10546    }
10547
10548    @Override
10549    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10550        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10551                userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
10552
10553        final File passedIconFile = new File(filePath);
10554        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10555                passedIconFile.getName());
10556        if (!legitIconFile.getPath().equals(filePath)
10557                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10558            throw new IllegalArgumentException("Bad file path: " + filePath
10559                    + " passed for userId " + userId);
10560        }
10561        return mRecentTasks.getTaskDescriptionIcon(filePath);
10562    }
10563
10564    @Override
10565    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10566            throws RemoteException {
10567        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
10568        final ActivityOptions activityOptions = safeOptions != null
10569                ? safeOptions.getOptions(mStackSupervisor)
10570                : null;
10571        if (activityOptions == null
10572                || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
10573                || activityOptions.getCustomInPlaceResId() == 0) {
10574            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10575                    "with valid animation");
10576        }
10577        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10578        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10579                activityOptions.getCustomInPlaceResId());
10580        mWindowManager.executeAppTransition();
10581    }
10582
10583    @Override
10584    public void removeStack(int stackId) {
10585        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
10586        synchronized (this) {
10587            final long ident = Binder.clearCallingIdentity();
10588            try {
10589                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10590                if (stack == null) {
10591                    Slog.w(TAG, "removeStack: No stack with id=" + stackId);
10592                    return;
10593                }
10594                if (!stack.isActivityTypeStandardOrUndefined()) {
10595                    throw new IllegalArgumentException(
10596                            "Removing non-standard stack is not allowed.");
10597                }
10598                mStackSupervisor.removeStack(stack);
10599            } finally {
10600                Binder.restoreCallingIdentity(ident);
10601            }
10602        }
10603    }
10604
10605    /**
10606     * Removes stacks in the input windowing modes from the system if they are of activity type
10607     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
10608     */
10609    @Override
10610    public void removeStacksInWindowingModes(int[] windowingModes) {
10611        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10612                "removeStacksInWindowingModes()");
10613        synchronized (this) {
10614            final long ident = Binder.clearCallingIdentity();
10615            try {
10616                mStackSupervisor.removeStacksInWindowingModes(windowingModes);
10617            } finally {
10618                Binder.restoreCallingIdentity(ident);
10619            }
10620        }
10621    }
10622
10623    @Override
10624    public void removeStacksWithActivityTypes(int[] activityTypes) {
10625        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10626                "removeStacksWithActivityTypes()");
10627        synchronized (this) {
10628            final long ident = Binder.clearCallingIdentity();
10629            try {
10630                mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
10631            } finally {
10632                Binder.restoreCallingIdentity(ident);
10633            }
10634        }
10635    }
10636
10637    @Override
10638    public void moveStackToDisplay(int stackId, int displayId) {
10639        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10640
10641        synchronized (this) {
10642            final long ident = Binder.clearCallingIdentity();
10643            try {
10644                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10645                        + " to displayId=" + displayId);
10646                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10647            } finally {
10648                Binder.restoreCallingIdentity(ident);
10649            }
10650        }
10651    }
10652
10653    @Override
10654    public boolean removeTask(int taskId) {
10655        enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
10656        synchronized (this) {
10657            final long ident = Binder.clearCallingIdentity();
10658            try {
10659                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
10660                        "remove-task");
10661            } finally {
10662                Binder.restoreCallingIdentity(ident);
10663            }
10664        }
10665    }
10666
10667    /**
10668     * TODO: Add mController hook
10669     */
10670    @Override
10671    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10672        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10673
10674        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10675        synchronized(this) {
10676            moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
10677                    false /* fromRecents */);
10678        }
10679    }
10680
10681    void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
10682            boolean fromRecents) {
10683
10684        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10685                Binder.getCallingUid(), -1, -1, "Task to front")) {
10686            SafeActivityOptions.abort(options);
10687            return;
10688        }
10689        final long origId = Binder.clearCallingIdentity();
10690        try {
10691            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10692            if (task == null) {
10693                Slog.d(TAG, "Could not find task for id: "+ taskId);
10694                return;
10695            }
10696            if (mLockTaskController.isLockTaskModeViolation(task)) {
10697                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10698                return;
10699            }
10700            ActivityOptions realOptions = options != null
10701                    ? options.getOptions(mStackSupervisor)
10702                    : null;
10703            mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
10704                    false /* forceNonResizable */);
10705
10706            final ActivityRecord topActivity = task.getTopActivity();
10707            if (topActivity != null) {
10708
10709                // We are reshowing a task, use a starting window to hide the initial draw delay
10710                // so the transition can start earlier.
10711                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10712                        true /* taskSwitch */, fromRecents);
10713            }
10714        } finally {
10715            Binder.restoreCallingIdentity(origId);
10716        }
10717        SafeActivityOptions.abort(options);
10718    }
10719
10720    /**
10721     * Attempts to move a task backwards in z-order (the order of activities within the task is
10722     * unchanged).
10723     *
10724     * There are several possible results of this call:
10725     * - if the task is locked, then we will show the lock toast
10726     * - if there is a task behind the provided task, then that task is made visible and resumed as
10727     *   this task is moved to the back
10728     * - otherwise, if there are no other tasks in the stack:
10729     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10730     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10731     *       (depending on whether it is visible)
10732     *     - otherwise, we simply return home and hide this task
10733     *
10734     * @param token A reference to the activity we wish to move
10735     * @param nonRoot If false then this only works if the activity is the root
10736     *                of a task; if true it will work for any activity in a task.
10737     * @return Returns true if the move completed, false if not.
10738     */
10739    @Override
10740    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10741        enforceNotIsolatedCaller("moveActivityTaskToBack");
10742        synchronized(this) {
10743            final long origId = Binder.clearCallingIdentity();
10744            try {
10745                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10746                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10747                if (task != null) {
10748                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10749                }
10750            } finally {
10751                Binder.restoreCallingIdentity(origId);
10752            }
10753        }
10754        return false;
10755    }
10756
10757    @Override
10758    public void moveTaskBackwards(int task) {
10759        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10760                "moveTaskBackwards()");
10761
10762        synchronized(this) {
10763            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10764                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10765                return;
10766            }
10767            final long origId = Binder.clearCallingIdentity();
10768            moveTaskBackwardsLocked(task);
10769            Binder.restoreCallingIdentity(origId);
10770        }
10771    }
10772
10773    private final void moveTaskBackwardsLocked(int task) {
10774        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10775    }
10776
10777    @Override
10778    public int createStackOnDisplay(int displayId) throws RemoteException {
10779        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10780        synchronized (this) {
10781            final ActivityDisplay display =
10782                    mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
10783            if (display == null) {
10784                return INVALID_STACK_ID;
10785            }
10786            // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
10787            final ActivityStack stack = display.createStack(
10788                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
10789                    ON_TOP);
10790            return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
10791        }
10792    }
10793
10794    @Override
10795    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10796        synchronized (this) {
10797            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10798            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10799                return stack.mDisplayId;
10800            }
10801            return DEFAULT_DISPLAY;
10802        }
10803    }
10804
10805    @Override
10806    public void exitFreeformMode(IBinder token) throws RemoteException {
10807        synchronized (this) {
10808            long ident = Binder.clearCallingIdentity();
10809            try {
10810                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10811                if (r == null) {
10812                    throw new IllegalArgumentException(
10813                            "exitFreeformMode: No activity record matching token=" + token);
10814                }
10815
10816                final ActivityStack stack = r.getStack();
10817                if (stack == null || !stack.inFreeformWindowingMode()) {
10818                    throw new IllegalStateException(
10819                            "exitFreeformMode: You can only go fullscreen from freeform.");
10820                }
10821
10822                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
10823            } finally {
10824                Binder.restoreCallingIdentity(ident);
10825            }
10826        }
10827    }
10828
10829    @Override
10830    public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
10831        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
10832            setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
10833                    toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
10834            return;
10835        }
10836        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
10837        synchronized (this) {
10838            final long ident = Binder.clearCallingIdentity();
10839            try {
10840                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10841                if (task == null) {
10842                    Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
10843                    return;
10844                }
10845
10846                if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
10847                        + " to windowingMode=" + windowingMode + " toTop=" + toTop);
10848
10849                if (!task.isActivityTypeStandardOrUndefined()) {
10850                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
10851                            + " non-standard task " + taskId + " to windowing mode="
10852                            + windowingMode);
10853                }
10854
10855                final ActivityStack stack = task.getStack();
10856                if (toTop) {
10857                    stack.moveToFront("setTaskWindowingMode", task);
10858                }
10859                stack.setWindowingMode(windowingMode);
10860            } finally {
10861                Binder.restoreCallingIdentity(ident);
10862            }
10863        }
10864    }
10865
10866    /**
10867     * Moves the specified task to the primary-split-screen stack.
10868     *
10869     * @param taskId Id of task to move.
10870     * @param createMode The mode the primary split screen stack should be created in if it doesn't
10871     *                   exist already. See
10872     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
10873     *                   and
10874     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
10875     * @param toTop If the task and stack should be moved to the top.
10876     * @param animate Whether we should play an animation for the moving the task.
10877     * @param initialBounds If the primary stack gets created, it will use these bounds for the
10878     *                      stack. Pass {@code null} to use default bounds.
10879     * @param showRecents If the recents activity should be shown on the other side of the task
10880     *                    going into split-screen mode.
10881     */
10882    @Override
10883    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
10884            boolean animate, Rect initialBounds, boolean showRecents) {
10885        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10886                "setTaskWindowingModeSplitScreenPrimary()");
10887        synchronized (this) {
10888            long ident = Binder.clearCallingIdentity();
10889            try {
10890                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10891                if (task == null) {
10892                    Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
10893                    return false;
10894                }
10895                if (DEBUG_STACK) Slog.d(TAG_STACK,
10896                        "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
10897                        + " to createMode=" + createMode + " toTop=" + toTop);
10898                if (!task.isActivityTypeStandardOrUndefined()) {
10899                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
10900                            + " non-standard task " + taskId + " to split-screen windowing mode");
10901                }
10902
10903                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10904                final int windowingMode = task.getWindowingMode();
10905                final ActivityStack stack = task.getStack();
10906                if (toTop) {
10907                    stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
10908                }
10909                stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
10910                        false /* enteringSplitScreenMode */);
10911                return windowingMode != task.getWindowingMode();
10912            } finally {
10913                Binder.restoreCallingIdentity(ident);
10914            }
10915        }
10916    }
10917
10918    @Override
10919    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10920        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
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, "moveTaskToStack: No task for id=" + taskId);
10927                    return;
10928                }
10929
10930                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10931                        + " to stackId=" + stackId + " toTop=" + toTop);
10932
10933                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10934                if (stack == null) {
10935                    throw new IllegalStateException(
10936                            "moveTaskToStack: No stack for stackId=" + stackId);
10937                }
10938                if (!stack.isActivityTypeStandardOrUndefined()) {
10939                    throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
10940                            + taskId + " to stack " + stackId);
10941                }
10942                if (stack.inSplitScreenPrimaryWindowingMode()) {
10943                    mWindowManager.setDockedStackCreateState(
10944                            SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
10945                }
10946                task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
10947                        "moveTaskToStack");
10948            } finally {
10949                Binder.restoreCallingIdentity(ident);
10950            }
10951        }
10952    }
10953
10954    /**
10955     * Dismisses split-screen multi-window mode.
10956     * @param toTop If true the current primary split-screen stack will be placed or left on top.
10957     */
10958    @Override
10959    public void dismissSplitScreenMode(boolean toTop) {
10960        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
10961        final long ident = Binder.clearCallingIdentity();
10962        try {
10963            synchronized (this) {
10964                final ActivityStack stack =
10965                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
10966                if (stack == null) {
10967                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
10968                    return;
10969                }
10970
10971                if (toTop) {
10972                    // Caller wants the current split-screen primary stack to be the top stack after
10973                    // it goes fullscreen, so move it to the front.
10974                    stack.moveToFront("dismissSplitScreenMode");
10975                } else if (mStackSupervisor.isFocusedStack(stack)) {
10976                    // In this case the current split-screen primary stack shouldn't be the top
10977                    // stack after it goes fullscreen, but it current has focus, so we move the
10978                    // focus to the top-most split-screen secondary stack next to it.
10979                    final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
10980                            WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
10981                    if (otherStack != null) {
10982                        otherStack.moveToFront("dismissSplitScreenMode_other");
10983                    }
10984                }
10985
10986                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
10987            }
10988        } finally {
10989            Binder.restoreCallingIdentity(ident);
10990        }
10991    }
10992
10993    /**
10994     * Dismisses Pip
10995     * @param animate True if the dismissal should be animated.
10996     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
10997     *                          default animation duration should be used.
10998     */
10999    @Override
11000    public void dismissPip(boolean animate, int animationDuration) {
11001        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
11002        final long ident = Binder.clearCallingIdentity();
11003        try {
11004            synchronized (this) {
11005                final PinnedActivityStack stack =
11006                        mStackSupervisor.getDefaultDisplay().getPinnedStack();
11007                if (stack == null) {
11008                    Slog.w(TAG, "dismissPip: pinned stack not found.");
11009                    return;
11010                }
11011                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11012                    throw new IllegalArgumentException("Stack: " + stack
11013                            + " doesn't support animated resize.");
11014                }
11015                if (animate) {
11016                    stack.animateResizePinnedStack(null /* sourceHintBounds */,
11017                            null /* destBounds */, animationDuration, false /* fromFullscreen */);
11018                } else {
11019                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
11020                }
11021            }
11022        } finally {
11023            Binder.restoreCallingIdentity(ident);
11024        }
11025    }
11026
11027    /**
11028     * Moves the top activity in the input stackId to the pinned stack.
11029     *
11030     * @param stackId Id of stack to move the top activity to pinned stack.
11031     * @param bounds Bounds to use for pinned stack.
11032     *
11033     * @return True if the top activity of the input stack was successfully moved to the pinned
11034     *          stack.
11035     */
11036    @Override
11037    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
11038        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11039                "moveTopActivityToPinnedStack()");
11040        synchronized (this) {
11041            if (!mSupportsPictureInPicture) {
11042                throw new IllegalStateException("moveTopActivityToPinnedStack:"
11043                        + "Device doesn't support picture-in-picture mode");
11044            }
11045
11046            long ident = Binder.clearCallingIdentity();
11047            try {
11048                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
11049            } finally {
11050                Binder.restoreCallingIdentity(ident);
11051            }
11052        }
11053    }
11054
11055    @Override
11056    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
11057            boolean preserveWindows, boolean animate, int animationDuration) {
11058        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
11059        long ident = Binder.clearCallingIdentity();
11060        try {
11061            synchronized (this) {
11062                if (animate) {
11063                    final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
11064                    if (stack == null) {
11065                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11066                        return;
11067                    }
11068                    if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11069                        throw new IllegalArgumentException("Stack: " + stackId
11070                                + " doesn't support animated resize.");
11071                    }
11072                    stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11073                            animationDuration, false /* fromFullscreen */);
11074                } else {
11075                    final ActivityStack stack = mStackSupervisor.getStack(stackId);
11076                    if (stack == null) {
11077                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11078                        return;
11079                    }
11080                    mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11081                            null /* tempTaskInsetBounds */, preserveWindows,
11082                            allowResizeInDockedMode, !DEFER_RESUME);
11083                }
11084            }
11085        } finally {
11086            Binder.restoreCallingIdentity(ident);
11087        }
11088    }
11089
11090    @Override
11091    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
11092            Rect tempDockedTaskInsetBounds,
11093            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
11094        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
11095        long ident = Binder.clearCallingIdentity();
11096        try {
11097            synchronized (this) {
11098                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11099                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11100                        PRESERVE_WINDOWS);
11101            }
11102        } finally {
11103            Binder.restoreCallingIdentity(ident);
11104        }
11105    }
11106
11107    @Override
11108    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11109        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11110        final long ident = Binder.clearCallingIdentity();
11111        try {
11112            synchronized (this) {
11113                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11114            }
11115        } finally {
11116            Binder.restoreCallingIdentity(ident);
11117        }
11118    }
11119
11120    /**
11121     * Try to place task to provided position. The final position might be different depending on
11122     * current user and stacks state. The task will be moved to target stack if it's currently in
11123     * different stack.
11124     */
11125    @Override
11126    public void positionTaskInStack(int taskId, int stackId, int position) {
11127        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11128        synchronized (this) {
11129            long ident = Binder.clearCallingIdentity();
11130            try {
11131                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
11132                        + taskId + " in stackId=" + stackId + " at position=" + position);
11133                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11134                if (task == null) {
11135                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
11136                            + taskId);
11137                }
11138
11139                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11140
11141                if (stack == null) {
11142                    throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11143                            + stackId);
11144                }
11145                if (!stack.isActivityTypeStandardOrUndefined()) {
11146                    throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11147                            + " the position of task " + taskId + " in/to non-standard stack");
11148                }
11149
11150                // TODO: Have the callers of this API call a separate reparent method if that is
11151                // what they intended to do vs. having this method also do reparenting.
11152                if (task.getStack() == stack) {
11153                    // Change position in current stack.
11154                    stack.positionChildAt(task, position);
11155                } else {
11156                    // Reparent to new stack.
11157                    task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11158                            !DEFER_RESUME, "positionTaskInStack");
11159                }
11160            } finally {
11161                Binder.restoreCallingIdentity(ident);
11162            }
11163        }
11164    }
11165
11166    @Override
11167    public List<StackInfo> getAllStackInfos() {
11168        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11169        long ident = Binder.clearCallingIdentity();
11170        try {
11171            synchronized (this) {
11172                return mStackSupervisor.getAllStackInfosLocked();
11173            }
11174        } finally {
11175            Binder.restoreCallingIdentity(ident);
11176        }
11177    }
11178
11179    @Override
11180    public StackInfo getStackInfo(int windowingMode, int activityType) {
11181        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11182        long ident = Binder.clearCallingIdentity();
11183        try {
11184            synchronized (this) {
11185                return mStackSupervisor.getStackInfo(windowingMode, activityType);
11186            }
11187        } finally {
11188            Binder.restoreCallingIdentity(ident);
11189        }
11190    }
11191
11192    @Override
11193    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11194        synchronized(this) {
11195            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11196        }
11197    }
11198
11199    @Override
11200    public void updateDeviceOwner(String packageName) {
11201        final int callingUid = Binder.getCallingUid();
11202        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11203            throw new SecurityException("updateDeviceOwner called from non-system process");
11204        }
11205        synchronized (this) {
11206            mDeviceOwnerName = packageName;
11207        }
11208    }
11209
11210    @Override
11211    public void updateLockTaskPackages(int userId, String[] packages) {
11212        final int callingUid = Binder.getCallingUid();
11213        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11214            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11215                    "updateLockTaskPackages()");
11216        }
11217        synchronized (this) {
11218            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11219                    Arrays.toString(packages));
11220            mLockTaskController.updateLockTaskPackages(userId, packages);
11221        }
11222    }
11223
11224    @Override
11225    public void updateLockTaskFeatures(int userId, int flags) {
11226        final int callingUid = Binder.getCallingUid();
11227        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11228            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11229                    "updateLockTaskFeatures()");
11230        }
11231        synchronized (this) {
11232            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11233                    Integer.toHexString(flags));
11234            mLockTaskController.updateLockTaskFeatures(userId, flags);
11235        }
11236    }
11237
11238    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11239        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11240        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11241            return;
11242        }
11243
11244        final ActivityStack stack = mStackSupervisor.getFocusedStack();
11245        if (stack == null || task != stack.topTask()) {
11246            throw new IllegalArgumentException("Invalid task, not in foreground");
11247        }
11248
11249        // When a task is locked, dismiss the pinned stack if it exists
11250        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11251
11252        // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11253        // system or a specific app.
11254        // * System-initiated requests will only start the pinned mode (screen pinning)
11255        // * App-initiated requests
11256        //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
11257        //   - will start the pinned mode, otherwise
11258        final int callingUid = Binder.getCallingUid();
11259        long ident = Binder.clearCallingIdentity();
11260        try {
11261            mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11262        } finally {
11263            Binder.restoreCallingIdentity(ident);
11264        }
11265    }
11266
11267    @Override
11268    public void startLockTaskModeByToken(IBinder token) {
11269        synchronized (this) {
11270            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11271            if (r == null) {
11272                return;
11273            }
11274            startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11275        }
11276    }
11277
11278    @Override
11279    public void startSystemLockTaskMode(int taskId) throws RemoteException {
11280        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11281        // This makes inner call to look as if it was initiated by system.
11282        long ident = Binder.clearCallingIdentity();
11283        try {
11284            synchronized (this) {
11285                startLockTaskModeLocked(mStackSupervisor.anyTaskForIdLocked(taskId),
11286                        true /* isSystemCaller */);
11287            }
11288        } finally {
11289            Binder.restoreCallingIdentity(ident);
11290        }
11291    }
11292
11293    @Override
11294    public void stopLockTaskModeByToken(IBinder token) {
11295        synchronized (this) {
11296            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11297            if (r == null) {
11298                return;
11299            }
11300            stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11301        }
11302    }
11303
11304    /**
11305     * This API should be called by SystemUI only when user perform certain action to dismiss
11306     * lock task mode. We should only dismiss pinned lock task mode in this case.
11307     */
11308    @Override
11309    public void stopSystemLockTaskMode() throws RemoteException {
11310        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11311        stopLockTaskModeInternal(null, true /* isSystemCaller */);
11312    }
11313
11314    private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11315        final int callingUid = Binder.getCallingUid();
11316        long ident = Binder.clearCallingIdentity();
11317        try {
11318            synchronized (this) {
11319                mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11320            }
11321            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11322            // task and jumping straight into a call in the case of emergency call back.
11323            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11324            if (tm != null) {
11325                tm.showInCallScreen(false);
11326            }
11327        } finally {
11328            Binder.restoreCallingIdentity(ident);
11329        }
11330    }
11331
11332    @Override
11333    public boolean isInLockTaskMode() {
11334        return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11335    }
11336
11337    @Override
11338    public int getLockTaskModeState() {
11339        synchronized (this) {
11340            return mLockTaskController.getLockTaskModeState();
11341        }
11342    }
11343
11344    @Override
11345    public void showLockTaskEscapeMessage(IBinder token) {
11346        synchronized (this) {
11347            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11348            if (r == null) {
11349                return;
11350            }
11351            mLockTaskController.showLockTaskToast();
11352        }
11353    }
11354
11355    @Override
11356    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11357            throws RemoteException {
11358        synchronized (this) {
11359            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11360            if (r == null) {
11361                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11362                        + token);
11363                return;
11364            }
11365            final long origId = Binder.clearCallingIdentity();
11366            try {
11367                r.setDisablePreviewScreenshots(disable);
11368            } finally {
11369                Binder.restoreCallingIdentity(origId);
11370            }
11371        }
11372    }
11373
11374    // =========================================================
11375    // CONTENT PROVIDERS
11376    // =========================================================
11377
11378    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11379        List<ProviderInfo> providers = null;
11380        try {
11381            providers = AppGlobals.getPackageManager()
11382                    .queryContentProviders(app.processName, app.uid,
11383                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11384                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11385                    .getList();
11386        } catch (RemoteException ex) {
11387        }
11388        if (DEBUG_MU) Slog.v(TAG_MU,
11389                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11390        int userId = app.userId;
11391        if (providers != null) {
11392            int N = providers.size();
11393            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11394            for (int i=0; i<N; i++) {
11395                // TODO: keep logic in sync with installEncryptionUnawareProviders
11396                ProviderInfo cpi =
11397                    (ProviderInfo)providers.get(i);
11398                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11399                        cpi.name, cpi.flags);
11400                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11401                    // This is a singleton provider, but a user besides the
11402                    // default user is asking to initialize a process it runs
11403                    // in...  well, no, it doesn't actually run in this process,
11404                    // it runs in the process of the default user.  Get rid of it.
11405                    providers.remove(i);
11406                    N--;
11407                    i--;
11408                    continue;
11409                }
11410
11411                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11412                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11413                if (cpr == null) {
11414                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11415                    mProviderMap.putProviderByClass(comp, cpr);
11416                }
11417                if (DEBUG_MU) Slog.v(TAG_MU,
11418                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11419                app.pubProviders.put(cpi.name, cpr);
11420                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11421                    // Don't add this if it is a platform component that is marked
11422                    // to run in multiple processes, because this is actually
11423                    // part of the framework so doesn't make sense to track as a
11424                    // separate apk in the process.
11425                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11426                            mProcessStats);
11427                }
11428                notifyPackageUse(cpi.applicationInfo.packageName,
11429                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11430            }
11431        }
11432        return providers;
11433    }
11434
11435    /**
11436     * Check if the calling UID has a possible chance at accessing the provider
11437     * at the given authority and user.
11438     */
11439    public String checkContentProviderAccess(String authority, int userId) {
11440        if (userId == UserHandle.USER_ALL) {
11441            mContext.enforceCallingOrSelfPermission(
11442                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11443            userId = UserHandle.getCallingUserId();
11444        }
11445
11446        ProviderInfo cpi = null;
11447        try {
11448            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11449                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11450                            | PackageManager.MATCH_DISABLED_COMPONENTS
11451                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11452                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11453                    userId);
11454        } catch (RemoteException ignored) {
11455        }
11456        if (cpi == null) {
11457            return "Failed to find provider " + authority + " for user " + userId
11458                    + "; expected to find a valid ContentProvider for this authority";
11459        }
11460
11461        ProcessRecord r = null;
11462        synchronized (mPidsSelfLocked) {
11463            r = mPidsSelfLocked.get(Binder.getCallingPid());
11464        }
11465        if (r == null) {
11466            return "Failed to find PID " + Binder.getCallingPid();
11467        }
11468
11469        synchronized (this) {
11470            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11471        }
11472    }
11473
11474    /**
11475     * Check if {@link ProcessRecord} has a possible chance at accessing the
11476     * given {@link ProviderInfo}. Final permission checking is always done
11477     * in {@link ContentProvider}.
11478     */
11479    private final String checkContentProviderPermissionLocked(
11480            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11481        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11482        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11483        boolean checkedGrants = false;
11484        if (checkUser) {
11485            // Looking for cross-user grants before enforcing the typical cross-users permissions
11486            int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11487            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11488                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11489                    return null;
11490                }
11491                checkedGrants = true;
11492            }
11493            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11494                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11495            if (userId != tmpTargetUserId) {
11496                // When we actually went to determine the final targer user ID, this ended
11497                // up different than our initial check for the authority.  This is because
11498                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11499                // SELF.  So we need to re-check the grants again.
11500                checkedGrants = false;
11501            }
11502        }
11503        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11504                cpi.applicationInfo.uid, cpi.exported)
11505                == PackageManager.PERMISSION_GRANTED) {
11506            return null;
11507        }
11508        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11509                cpi.applicationInfo.uid, cpi.exported)
11510                == PackageManager.PERMISSION_GRANTED) {
11511            return null;
11512        }
11513
11514        PathPermission[] pps = cpi.pathPermissions;
11515        if (pps != null) {
11516            int i = pps.length;
11517            while (i > 0) {
11518                i--;
11519                PathPermission pp = pps[i];
11520                String pprperm = pp.getReadPermission();
11521                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11522                        cpi.applicationInfo.uid, cpi.exported)
11523                        == PackageManager.PERMISSION_GRANTED) {
11524                    return null;
11525                }
11526                String ppwperm = pp.getWritePermission();
11527                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11528                        cpi.applicationInfo.uid, cpi.exported)
11529                        == PackageManager.PERMISSION_GRANTED) {
11530                    return null;
11531                }
11532            }
11533        }
11534        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11535            return null;
11536        }
11537
11538        final String suffix;
11539        if (!cpi.exported) {
11540            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11541        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11542            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11543        } else {
11544            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11545        }
11546        final String msg = "Permission Denial: opening provider " + cpi.name
11547                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11548                + ", uid=" + callingUid + ")" + suffix;
11549        Slog.w(TAG, msg);
11550        return msg;
11551    }
11552
11553    /**
11554     * Returns if the ContentProvider has granted a uri to callingUid
11555     */
11556    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11557        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11558        if (perms != null) {
11559            for (int i=perms.size()-1; i>=0; i--) {
11560                GrantUri grantUri = perms.keyAt(i);
11561                if (grantUri.sourceUserId == userId || !checkUser) {
11562                    if (matchesProvider(grantUri.uri, cpi)) {
11563                        return true;
11564                    }
11565                }
11566            }
11567        }
11568        return false;
11569    }
11570
11571    /**
11572     * Returns true if the uri authority is one of the authorities specified in the provider.
11573     */
11574    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11575        String uriAuth = uri.getAuthority();
11576        String cpiAuth = cpi.authority;
11577        if (cpiAuth.indexOf(';') == -1) {
11578            return cpiAuth.equals(uriAuth);
11579        }
11580        String[] cpiAuths = cpiAuth.split(";");
11581        int length = cpiAuths.length;
11582        for (int i = 0; i < length; i++) {
11583            if (cpiAuths[i].equals(uriAuth)) return true;
11584        }
11585        return false;
11586    }
11587
11588    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11589            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11590        if (r != null) {
11591            for (int i=0; i<r.conProviders.size(); i++) {
11592                ContentProviderConnection conn = r.conProviders.get(i);
11593                if (conn.provider == cpr) {
11594                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11595                            "Adding provider requested by "
11596                            + r.processName + " from process "
11597                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11598                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11599                    if (stable) {
11600                        conn.stableCount++;
11601                        conn.numStableIncs++;
11602                    } else {
11603                        conn.unstableCount++;
11604                        conn.numUnstableIncs++;
11605                    }
11606                    return conn;
11607                }
11608            }
11609            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11610            if (stable) {
11611                conn.stableCount = 1;
11612                conn.numStableIncs = 1;
11613            } else {
11614                conn.unstableCount = 1;
11615                conn.numUnstableIncs = 1;
11616            }
11617            cpr.connections.add(conn);
11618            r.conProviders.add(conn);
11619            startAssociationLocked(r.uid, r.processName, r.curProcState,
11620                    cpr.uid, cpr.name, cpr.info.processName);
11621            return conn;
11622        }
11623        cpr.addExternalProcessHandleLocked(externalProcessToken);
11624        return null;
11625    }
11626
11627    boolean decProviderCountLocked(ContentProviderConnection conn,
11628            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11629        if (conn != null) {
11630            cpr = conn.provider;
11631            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11632                    "Removing provider requested by "
11633                    + conn.client.processName + " from process "
11634                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11635                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11636            if (stable) {
11637                conn.stableCount--;
11638            } else {
11639                conn.unstableCount--;
11640            }
11641            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11642                cpr.connections.remove(conn);
11643                conn.client.conProviders.remove(conn);
11644                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11645                    // The client is more important than last activity -- note the time this
11646                    // is happening, so we keep the old provider process around a bit as last
11647                    // activity to avoid thrashing it.
11648                    if (cpr.proc != null) {
11649                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11650                    }
11651                }
11652                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11653                return true;
11654            }
11655            return false;
11656        }
11657        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11658        return false;
11659    }
11660
11661    private void checkTime(long startTime, String where) {
11662        long now = SystemClock.uptimeMillis();
11663        if ((now-startTime) > 50) {
11664            // If we are taking more than 50ms, log about it.
11665            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11666        }
11667    }
11668
11669    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11670            PROC_SPACE_TERM,
11671            PROC_SPACE_TERM|PROC_PARENS,
11672            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11673    };
11674
11675    private final long[] mProcessStateStatsLongs = new long[1];
11676
11677    private boolean isProcessAliveLocked(ProcessRecord proc) {
11678        if (proc.pid <= 0) {
11679            if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
11680            return false;
11681        }
11682        if (proc.procStatFile == null) {
11683            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11684        }
11685        mProcessStateStatsLongs[0] = 0;
11686        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11687                mProcessStateStatsLongs, null)) {
11688            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11689            return false;
11690        }
11691        final long state = mProcessStateStatsLongs[0];
11692        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11693                + (char)state);
11694        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11695    }
11696
11697    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11698            String name, IBinder token, boolean stable, int userId) {
11699        ContentProviderRecord cpr;
11700        ContentProviderConnection conn = null;
11701        ProviderInfo cpi = null;
11702
11703        synchronized(this) {
11704            long startTime = SystemClock.uptimeMillis();
11705
11706            ProcessRecord r = null;
11707            if (caller != null) {
11708                r = getRecordForAppLocked(caller);
11709                if (r == null) {
11710                    throw new SecurityException(
11711                            "Unable to find app for caller " + caller
11712                          + " (pid=" + Binder.getCallingPid()
11713                          + ") when getting content provider " + name);
11714                }
11715            }
11716
11717            boolean checkCrossUser = true;
11718
11719            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11720
11721            // First check if this content provider has been published...
11722            cpr = mProviderMap.getProviderByName(name, userId);
11723            // If that didn't work, check if it exists for user 0 and then
11724            // verify that it's a singleton provider before using it.
11725            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11726                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11727                if (cpr != null) {
11728                    cpi = cpr.info;
11729                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11730                            cpi.name, cpi.flags)
11731                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11732                        userId = UserHandle.USER_SYSTEM;
11733                        checkCrossUser = false;
11734                    } else {
11735                        cpr = null;
11736                        cpi = null;
11737                    }
11738                }
11739            }
11740
11741            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11742            if (providerRunning) {
11743                cpi = cpr.info;
11744                String msg;
11745                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11746                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11747                        != null) {
11748                    throw new SecurityException(msg);
11749                }
11750                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11751
11752                if (r != null && cpr.canRunHere(r)) {
11753                    // This provider has been published or is in the process
11754                    // of being published...  but it is also allowed to run
11755                    // in the caller's process, so don't make a connection
11756                    // and just let the caller instantiate its own instance.
11757                    ContentProviderHolder holder = cpr.newHolder(null);
11758                    // don't give caller the provider object, it needs
11759                    // to make its own.
11760                    holder.provider = null;
11761                    return holder;
11762                }
11763                // Don't expose providers between normal apps and instant apps
11764                try {
11765                    if (AppGlobals.getPackageManager()
11766                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11767                        return null;
11768                    }
11769                } catch (RemoteException e) {
11770                }
11771
11772                final long origId = Binder.clearCallingIdentity();
11773
11774                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11775
11776                // In this case the provider instance already exists, so we can
11777                // return it right away.
11778                conn = incProviderCountLocked(r, cpr, token, stable);
11779                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11780                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11781                        // If this is a perceptible app accessing the provider,
11782                        // make sure to count it as being accessed and thus
11783                        // back up on the LRU list.  This is good because
11784                        // content providers are often expensive to start.
11785                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11786                        updateLruProcessLocked(cpr.proc, false, null);
11787                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11788                    }
11789                }
11790
11791                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11792                final int verifiedAdj = cpr.proc.verifiedAdj;
11793                boolean success = updateOomAdjLocked(cpr.proc, true);
11794                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11795                // if the process has been successfully adjusted.  So to reduce races with
11796                // it, we will check whether the process still exists.  Note that this doesn't
11797                // completely get rid of races with LMK killing the process, but should make
11798                // them much smaller.
11799                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11800                    success = false;
11801                }
11802                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11803                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11804                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11805                // NOTE: there is still a race here where a signal could be
11806                // pending on the process even though we managed to update its
11807                // adj level.  Not sure what to do about this, but at least
11808                // the race is now smaller.
11809                if (!success) {
11810                    // Uh oh...  it looks like the provider's process
11811                    // has been killed on us.  We need to wait for a new
11812                    // process to be started, and make sure its death
11813                    // doesn't kill our process.
11814                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11815                            + " is crashing; detaching " + r);
11816                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11817                    checkTime(startTime, "getContentProviderImpl: before appDied");
11818                    appDiedLocked(cpr.proc);
11819                    checkTime(startTime, "getContentProviderImpl: after appDied");
11820                    if (!lastRef) {
11821                        // This wasn't the last ref our process had on
11822                        // the provider...  we have now been killed, bail.
11823                        return null;
11824                    }
11825                    providerRunning = false;
11826                    conn = null;
11827                } else {
11828                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11829                }
11830
11831                Binder.restoreCallingIdentity(origId);
11832            }
11833
11834            if (!providerRunning) {
11835                try {
11836                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11837                    cpi = AppGlobals.getPackageManager().
11838                        resolveContentProvider(name,
11839                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11840                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11841                } catch (RemoteException ex) {
11842                }
11843                if (cpi == null) {
11844                    return null;
11845                }
11846                // If the provider is a singleton AND
11847                // (it's a call within the same user || the provider is a
11848                // privileged app)
11849                // Then allow connecting to the singleton provider
11850                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11851                        cpi.name, cpi.flags)
11852                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11853                if (singleton) {
11854                    userId = UserHandle.USER_SYSTEM;
11855                }
11856                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11857                checkTime(startTime, "getContentProviderImpl: got app info for user");
11858
11859                String msg;
11860                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11861                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11862                        != null) {
11863                    throw new SecurityException(msg);
11864                }
11865                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11866
11867                if (!mProcessesReady
11868                        && !cpi.processName.equals("system")) {
11869                    // If this content provider does not run in the system
11870                    // process, and the system is not yet ready to run other
11871                    // processes, then fail fast instead of hanging.
11872                    throw new IllegalArgumentException(
11873                            "Attempt to launch content provider before system ready");
11874                }
11875
11876                // Make sure that the user who owns this provider is running.  If not,
11877                // we don't want to allow it to run.
11878                if (!mUserController.isUserRunning(userId, 0)) {
11879                    Slog.w(TAG, "Unable to launch app "
11880                            + cpi.applicationInfo.packageName + "/"
11881                            + cpi.applicationInfo.uid + " for provider "
11882                            + name + ": user " + userId + " is stopped");
11883                    return null;
11884                }
11885
11886                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11887                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11888                cpr = mProviderMap.getProviderByClass(comp, userId);
11889                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11890                final boolean firstClass = cpr == null;
11891                if (firstClass) {
11892                    final long ident = Binder.clearCallingIdentity();
11893
11894                    // If permissions need a review before any of the app components can run,
11895                    // we return no provider and launch a review activity if the calling app
11896                    // is in the foreground.
11897                    if (mPermissionReviewRequired) {
11898                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11899                            return null;
11900                        }
11901                    }
11902
11903                    try {
11904                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11905                        ApplicationInfo ai =
11906                            AppGlobals.getPackageManager().
11907                                getApplicationInfo(
11908                                        cpi.applicationInfo.packageName,
11909                                        STOCK_PM_FLAGS, userId);
11910                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11911                        if (ai == null) {
11912                            Slog.w(TAG, "No package info for content provider "
11913                                    + cpi.name);
11914                            return null;
11915                        }
11916                        ai = getAppInfoForUser(ai, userId);
11917                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11918                    } catch (RemoteException ex) {
11919                        // pm is in same process, this will never happen.
11920                    } finally {
11921                        Binder.restoreCallingIdentity(ident);
11922                    }
11923                }
11924
11925                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11926
11927                if (r != null && cpr.canRunHere(r)) {
11928                    // If this is a multiprocess provider, then just return its
11929                    // info and allow the caller to instantiate it.  Only do
11930                    // this if the provider is the same user as the caller's
11931                    // process, or can run as root (so can be in any process).
11932                    return cpr.newHolder(null);
11933                }
11934
11935                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11936                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11937                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11938
11939                // This is single process, and our app is now connecting to it.
11940                // See if we are already in the process of launching this
11941                // provider.
11942                final int N = mLaunchingProviders.size();
11943                int i;
11944                for (i = 0; i < N; i++) {
11945                    if (mLaunchingProviders.get(i) == cpr) {
11946                        break;
11947                    }
11948                }
11949
11950                // If the provider is not already being launched, then get it
11951                // started.
11952                if (i >= N) {
11953                    final long origId = Binder.clearCallingIdentity();
11954
11955                    try {
11956                        // Content provider is now in use, its package can't be stopped.
11957                        try {
11958                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11959                            AppGlobals.getPackageManager().setPackageStoppedState(
11960                                    cpr.appInfo.packageName, false, userId);
11961                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11962                        } catch (RemoteException e) {
11963                        } catch (IllegalArgumentException e) {
11964                            Slog.w(TAG, "Failed trying to unstop package "
11965                                    + cpr.appInfo.packageName + ": " + e);
11966                        }
11967
11968                        // Use existing process if already started
11969                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11970                        ProcessRecord proc = getProcessRecordLocked(
11971                                cpi.processName, cpr.appInfo.uid, false);
11972                        if (proc != null && proc.thread != null && !proc.killed) {
11973                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11974                                    "Installing in existing process " + proc);
11975                            if (!proc.pubProviders.containsKey(cpi.name)) {
11976                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11977                                proc.pubProviders.put(cpi.name, cpr);
11978                                try {
11979                                    proc.thread.scheduleInstallProvider(cpi);
11980                                } catch (RemoteException e) {
11981                                }
11982                            }
11983                        } else {
11984                            checkTime(startTime, "getContentProviderImpl: before start process");
11985                            proc = startProcessLocked(cpi.processName,
11986                                    cpr.appInfo, false, 0, "content provider",
11987                                    new ComponentName(cpi.applicationInfo.packageName,
11988                                            cpi.name), false, false, false);
11989                            checkTime(startTime, "getContentProviderImpl: after start process");
11990                            if (proc == null) {
11991                                Slog.w(TAG, "Unable to launch app "
11992                                        + cpi.applicationInfo.packageName + "/"
11993                                        + cpi.applicationInfo.uid + " for provider "
11994                                        + name + ": process is bad");
11995                                return null;
11996                            }
11997                        }
11998                        cpr.launchingApp = proc;
11999                        mLaunchingProviders.add(cpr);
12000                    } finally {
12001                        Binder.restoreCallingIdentity(origId);
12002                    }
12003                }
12004
12005                checkTime(startTime, "getContentProviderImpl: updating data structures");
12006
12007                // Make sure the provider is published (the same provider class
12008                // may be published under multiple names).
12009                if (firstClass) {
12010                    mProviderMap.putProviderByClass(comp, cpr);
12011                }
12012
12013                mProviderMap.putProviderByName(name, cpr);
12014                conn = incProviderCountLocked(r, cpr, token, stable);
12015                if (conn != null) {
12016                    conn.waiting = true;
12017                }
12018            }
12019            checkTime(startTime, "getContentProviderImpl: done!");
12020
12021            grantEphemeralAccessLocked(userId, null /*intent*/,
12022                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
12023        }
12024
12025        // Wait for the provider to be published...
12026        synchronized (cpr) {
12027            while (cpr.provider == null) {
12028                if (cpr.launchingApp == null) {
12029                    Slog.w(TAG, "Unable to launch app "
12030                            + cpi.applicationInfo.packageName + "/"
12031                            + cpi.applicationInfo.uid + " for provider "
12032                            + name + ": launching app became null");
12033                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
12034                            UserHandle.getUserId(cpi.applicationInfo.uid),
12035                            cpi.applicationInfo.packageName,
12036                            cpi.applicationInfo.uid, name);
12037                    return null;
12038                }
12039                try {
12040                    if (DEBUG_MU) Slog.v(TAG_MU,
12041                            "Waiting to start provider " + cpr
12042                            + " launchingApp=" + cpr.launchingApp);
12043                    if (conn != null) {
12044                        conn.waiting = true;
12045                    }
12046                    cpr.wait();
12047                } catch (InterruptedException ex) {
12048                } finally {
12049                    if (conn != null) {
12050                        conn.waiting = false;
12051                    }
12052                }
12053            }
12054        }
12055        return cpr != null ? cpr.newHolder(conn) : null;
12056    }
12057
12058    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
12059            ProcessRecord r, final int userId) {
12060        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
12061                cpi.packageName, userId)) {
12062
12063            final boolean callerForeground = r == null || r.setSchedGroup
12064                    != ProcessList.SCHED_GROUP_BACKGROUND;
12065
12066            // Show a permission review UI only for starting from a foreground app
12067            if (!callerForeground) {
12068                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
12069                        + cpi.packageName + " requires a permissions review");
12070                return false;
12071            }
12072
12073            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
12074            intent.addFlags(FLAG_ACTIVITY_NEW_TASK
12075                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
12076            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
12077
12078            if (DEBUG_PERMISSIONS_REVIEW) {
12079                Slog.i(TAG, "u" + userId + " Launching permission review "
12080                        + "for package " + cpi.packageName);
12081            }
12082
12083            final UserHandle userHandle = new UserHandle(userId);
12084            mHandler.post(new Runnable() {
12085                @Override
12086                public void run() {
12087                    mContext.startActivityAsUser(intent, userHandle);
12088                }
12089            });
12090
12091            return false;
12092        }
12093
12094        return true;
12095    }
12096
12097    /**
12098     * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
12099     * PackageManager could be unavailable at construction time and therefore needs to be accessed
12100     * on demand.
12101     */
12102    IPackageManager getPackageManager() {
12103        return AppGlobals.getPackageManager();
12104    }
12105
12106    ActivityStartController getActivityStartController() {
12107        return mActivityStartController;
12108    }
12109
12110    PackageManagerInternal getPackageManagerInternalLocked() {
12111        if (mPackageManagerInt == null) {
12112            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12113        }
12114        return mPackageManagerInt;
12115    }
12116
12117    @Override
12118    public final ContentProviderHolder getContentProvider(
12119            IApplicationThread caller, String name, int userId, boolean stable) {
12120        enforceNotIsolatedCaller("getContentProvider");
12121        if (caller == null) {
12122            String msg = "null IApplicationThread when getting content provider "
12123                    + name;
12124            Slog.w(TAG, msg);
12125            throw new SecurityException(msg);
12126        }
12127        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
12128        // with cross-user grant.
12129        return getContentProviderImpl(caller, name, null, stable, userId);
12130    }
12131
12132    public ContentProviderHolder getContentProviderExternal(
12133            String name, int userId, IBinder token) {
12134        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12135            "Do not have permission in call getContentProviderExternal()");
12136        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12137                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
12138        return getContentProviderExternalUnchecked(name, token, userId);
12139    }
12140
12141    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12142            IBinder token, int userId) {
12143        return getContentProviderImpl(null, name, token, true, userId);
12144    }
12145
12146    /**
12147     * Drop a content provider from a ProcessRecord's bookkeeping
12148     */
12149    public void removeContentProvider(IBinder connection, boolean stable) {
12150        enforceNotIsolatedCaller("removeContentProvider");
12151        long ident = Binder.clearCallingIdentity();
12152        try {
12153            synchronized (this) {
12154                ContentProviderConnection conn;
12155                try {
12156                    conn = (ContentProviderConnection)connection;
12157                } catch (ClassCastException e) {
12158                    String msg ="removeContentProvider: " + connection
12159                            + " not a ContentProviderConnection";
12160                    Slog.w(TAG, msg);
12161                    throw new IllegalArgumentException(msg);
12162                }
12163                if (conn == null) {
12164                    throw new NullPointerException("connection is null");
12165                }
12166                if (decProviderCountLocked(conn, null, null, stable)) {
12167                    updateOomAdjLocked();
12168                }
12169            }
12170        } finally {
12171            Binder.restoreCallingIdentity(ident);
12172        }
12173    }
12174
12175    public void removeContentProviderExternal(String name, IBinder token) {
12176        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12177            "Do not have permission in call removeContentProviderExternal()");
12178        int userId = UserHandle.getCallingUserId();
12179        long ident = Binder.clearCallingIdentity();
12180        try {
12181            removeContentProviderExternalUnchecked(name, token, userId);
12182        } finally {
12183            Binder.restoreCallingIdentity(ident);
12184        }
12185    }
12186
12187    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12188        synchronized (this) {
12189            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12190            if(cpr == null) {
12191                //remove from mProvidersByClass
12192                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12193                return;
12194            }
12195
12196            //update content provider record entry info
12197            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12198            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12199            if (localCpr.hasExternalProcessHandles()) {
12200                if (localCpr.removeExternalProcessHandleLocked(token)) {
12201                    updateOomAdjLocked();
12202                } else {
12203                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12204                            + " with no external reference for token: "
12205                            + token + ".");
12206                }
12207            } else {
12208                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12209                        + " with no external references.");
12210            }
12211        }
12212    }
12213
12214    public final void publishContentProviders(IApplicationThread caller,
12215            List<ContentProviderHolder> providers) {
12216        if (providers == null) {
12217            return;
12218        }
12219
12220        enforceNotIsolatedCaller("publishContentProviders");
12221        synchronized (this) {
12222            final ProcessRecord r = getRecordForAppLocked(caller);
12223            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12224            if (r == null) {
12225                throw new SecurityException(
12226                        "Unable to find app for caller " + caller
12227                      + " (pid=" + Binder.getCallingPid()
12228                      + ") when publishing content providers");
12229            }
12230
12231            final long origId = Binder.clearCallingIdentity();
12232
12233            final int N = providers.size();
12234            for (int i = 0; i < N; i++) {
12235                ContentProviderHolder src = providers.get(i);
12236                if (src == null || src.info == null || src.provider == null) {
12237                    continue;
12238                }
12239                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12240                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12241                if (dst != null) {
12242                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12243                    mProviderMap.putProviderByClass(comp, dst);
12244                    String names[] = dst.info.authority.split(";");
12245                    for (int j = 0; j < names.length; j++) {
12246                        mProviderMap.putProviderByName(names[j], dst);
12247                    }
12248
12249                    int launchingCount = mLaunchingProviders.size();
12250                    int j;
12251                    boolean wasInLaunchingProviders = false;
12252                    for (j = 0; j < launchingCount; j++) {
12253                        if (mLaunchingProviders.get(j) == dst) {
12254                            mLaunchingProviders.remove(j);
12255                            wasInLaunchingProviders = true;
12256                            j--;
12257                            launchingCount--;
12258                        }
12259                    }
12260                    if (wasInLaunchingProviders) {
12261                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12262                    }
12263                    synchronized (dst) {
12264                        dst.provider = src.provider;
12265                        dst.proc = r;
12266                        dst.notifyAll();
12267                    }
12268                    updateOomAdjLocked(r, true);
12269                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12270                            src.info.authority);
12271                }
12272            }
12273
12274            Binder.restoreCallingIdentity(origId);
12275        }
12276    }
12277
12278    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12279        ContentProviderConnection conn;
12280        try {
12281            conn = (ContentProviderConnection)connection;
12282        } catch (ClassCastException e) {
12283            String msg ="refContentProvider: " + connection
12284                    + " not a ContentProviderConnection";
12285            Slog.w(TAG, msg);
12286            throw new IllegalArgumentException(msg);
12287        }
12288        if (conn == null) {
12289            throw new NullPointerException("connection is null");
12290        }
12291
12292        synchronized (this) {
12293            if (stable > 0) {
12294                conn.numStableIncs += stable;
12295            }
12296            stable = conn.stableCount + stable;
12297            if (stable < 0) {
12298                throw new IllegalStateException("stableCount < 0: " + stable);
12299            }
12300
12301            if (unstable > 0) {
12302                conn.numUnstableIncs += unstable;
12303            }
12304            unstable = conn.unstableCount + unstable;
12305            if (unstable < 0) {
12306                throw new IllegalStateException("unstableCount < 0: " + unstable);
12307            }
12308
12309            if ((stable+unstable) <= 0) {
12310                throw new IllegalStateException("ref counts can't go to zero here: stable="
12311                        + stable + " unstable=" + unstable);
12312            }
12313            conn.stableCount = stable;
12314            conn.unstableCount = unstable;
12315            return !conn.dead;
12316        }
12317    }
12318
12319    public void unstableProviderDied(IBinder connection) {
12320        ContentProviderConnection conn;
12321        try {
12322            conn = (ContentProviderConnection)connection;
12323        } catch (ClassCastException e) {
12324            String msg ="refContentProvider: " + connection
12325                    + " not a ContentProviderConnection";
12326            Slog.w(TAG, msg);
12327            throw new IllegalArgumentException(msg);
12328        }
12329        if (conn == null) {
12330            throw new NullPointerException("connection is null");
12331        }
12332
12333        // Safely retrieve the content provider associated with the connection.
12334        IContentProvider provider;
12335        synchronized (this) {
12336            provider = conn.provider.provider;
12337        }
12338
12339        if (provider == null) {
12340            // Um, yeah, we're way ahead of you.
12341            return;
12342        }
12343
12344        // Make sure the caller is being honest with us.
12345        if (provider.asBinder().pingBinder()) {
12346            // Er, no, still looks good to us.
12347            synchronized (this) {
12348                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12349                        + " says " + conn + " died, but we don't agree");
12350                return;
12351            }
12352        }
12353
12354        // Well look at that!  It's dead!
12355        synchronized (this) {
12356            if (conn.provider.provider != provider) {
12357                // But something changed...  good enough.
12358                return;
12359            }
12360
12361            ProcessRecord proc = conn.provider.proc;
12362            if (proc == null || proc.thread == null) {
12363                // Seems like the process is already cleaned up.
12364                return;
12365            }
12366
12367            // As far as we're concerned, this is just like receiving a
12368            // death notification...  just a bit prematurely.
12369            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12370                    + ") early provider death");
12371            final long ident = Binder.clearCallingIdentity();
12372            try {
12373                appDiedLocked(proc);
12374            } finally {
12375                Binder.restoreCallingIdentity(ident);
12376            }
12377        }
12378    }
12379
12380    @Override
12381    public void appNotRespondingViaProvider(IBinder connection) {
12382        enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12383
12384        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12385        if (conn == null) {
12386            Slog.w(TAG, "ContentProviderConnection is null");
12387            return;
12388        }
12389
12390        final ProcessRecord host = conn.provider.proc;
12391        if (host == null) {
12392            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12393            return;
12394        }
12395
12396        mHandler.post(new Runnable() {
12397            @Override
12398            public void run() {
12399                mAppErrors.appNotResponding(host, null, null, false,
12400                        "ContentProvider not responding");
12401            }
12402        });
12403    }
12404
12405    public final void installSystemProviders() {
12406        List<ProviderInfo> providers;
12407        synchronized (this) {
12408            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12409            providers = generateApplicationProvidersLocked(app);
12410            if (providers != null) {
12411                for (int i=providers.size()-1; i>=0; i--) {
12412                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12413                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12414                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12415                                + ": not system .apk");
12416                        providers.remove(i);
12417                    }
12418                }
12419            }
12420        }
12421        if (providers != null) {
12422            mSystemThread.installSystemProviders(providers);
12423        }
12424
12425        mConstants.start(mContext.getContentResolver());
12426        mCoreSettingsObserver = new CoreSettingsObserver(this);
12427        mFontScaleSettingObserver = new FontScaleSettingObserver();
12428        GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12429
12430        // Now that the settings provider is published we can consider sending
12431        // in a rescue party.
12432        RescueParty.onSettingsProviderPublished(mContext);
12433
12434        //mUsageStatsService.monitorPackages();
12435    }
12436
12437    void startPersistentApps(int matchFlags) {
12438        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12439
12440        synchronized (this) {
12441            try {
12442                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12443                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12444                for (ApplicationInfo app : apps) {
12445                    if (!"android".equals(app.packageName)) {
12446                        addAppLocked(app, null, false, null /* ABI override */);
12447                    }
12448                }
12449            } catch (RemoteException ex) {
12450            }
12451        }
12452    }
12453
12454    /**
12455     * When a user is unlocked, we need to install encryption-unaware providers
12456     * belonging to any running apps.
12457     */
12458    void installEncryptionUnawareProviders(int userId) {
12459        // We're only interested in providers that are encryption unaware, and
12460        // we don't care about uninstalled apps, since there's no way they're
12461        // running at this point.
12462        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12463
12464        synchronized (this) {
12465            final int NP = mProcessNames.getMap().size();
12466            for (int ip = 0; ip < NP; ip++) {
12467                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12468                final int NA = apps.size();
12469                for (int ia = 0; ia < NA; ia++) {
12470                    final ProcessRecord app = apps.valueAt(ia);
12471                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12472
12473                    final int NG = app.pkgList.size();
12474                    for (int ig = 0; ig < NG; ig++) {
12475                        try {
12476                            final String pkgName = app.pkgList.keyAt(ig);
12477                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12478                                    .getPackageInfo(pkgName, matchFlags, userId);
12479                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12480                                for (ProviderInfo pi : pkgInfo.providers) {
12481                                    // TODO: keep in sync with generateApplicationProvidersLocked
12482                                    final boolean processMatch = Objects.equals(pi.processName,
12483                                            app.processName) || pi.multiprocess;
12484                                    final boolean userMatch = isSingleton(pi.processName,
12485                                            pi.applicationInfo, pi.name, pi.flags)
12486                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12487                                    if (processMatch && userMatch) {
12488                                        Log.v(TAG, "Installing " + pi);
12489                                        app.thread.scheduleInstallProvider(pi);
12490                                    } else {
12491                                        Log.v(TAG, "Skipping " + pi);
12492                                    }
12493                                }
12494                            }
12495                        } catch (RemoteException ignored) {
12496                        }
12497                    }
12498                }
12499            }
12500        }
12501    }
12502
12503    /**
12504     * Allows apps to retrieve the MIME type of a URI.
12505     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12506     * users, then it does not need permission to access the ContentProvider.
12507     * Either, it needs cross-user uri grants.
12508     *
12509     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12510     *
12511     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12512     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12513     */
12514    public String getProviderMimeType(Uri uri, int userId) {
12515        enforceNotIsolatedCaller("getProviderMimeType");
12516        final String name = uri.getAuthority();
12517        int callingUid = Binder.getCallingUid();
12518        int callingPid = Binder.getCallingPid();
12519        long ident = 0;
12520        boolean clearedIdentity = false;
12521        userId = mUserController.unsafeConvertIncomingUser(userId);
12522        if (canClearIdentity(callingPid, callingUid, userId)) {
12523            clearedIdentity = true;
12524            ident = Binder.clearCallingIdentity();
12525        }
12526        ContentProviderHolder holder = null;
12527        try {
12528            holder = getContentProviderExternalUnchecked(name, null, userId);
12529            if (holder != null) {
12530                return holder.provider.getType(uri);
12531            }
12532        } catch (RemoteException e) {
12533            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12534            return null;
12535        } catch (Exception e) {
12536            Log.w(TAG, "Exception while determining type of " + uri, e);
12537            return null;
12538        } finally {
12539            // We need to clear the identity to call removeContentProviderExternalUnchecked
12540            if (!clearedIdentity) {
12541                ident = Binder.clearCallingIdentity();
12542            }
12543            try {
12544                if (holder != null) {
12545                    removeContentProviderExternalUnchecked(name, null, userId);
12546                }
12547            } finally {
12548                Binder.restoreCallingIdentity(ident);
12549            }
12550        }
12551
12552        return null;
12553    }
12554
12555    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12556        if (UserHandle.getUserId(callingUid) == userId) {
12557            return true;
12558        }
12559        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12560                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12561                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12562                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12563                return true;
12564        }
12565        return false;
12566    }
12567
12568    // =========================================================
12569    // GLOBAL MANAGEMENT
12570    // =========================================================
12571
12572    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12573            boolean isolated, int isolatedUid) {
12574        String proc = customProcess != null ? customProcess : info.processName;
12575        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12576        final int userId = UserHandle.getUserId(info.uid);
12577        int uid = info.uid;
12578        if (isolated) {
12579            if (isolatedUid == 0) {
12580                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12581                while (true) {
12582                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12583                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12584                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12585                    }
12586                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12587                    mNextIsolatedProcessUid++;
12588                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12589                        // No process for this uid, use it.
12590                        break;
12591                    }
12592                    stepsLeft--;
12593                    if (stepsLeft <= 0) {
12594                        return null;
12595                    }
12596                }
12597            } else {
12598                // Special case for startIsolatedProcess (internal only), where
12599                // the uid of the isolated process is specified by the caller.
12600                uid = isolatedUid;
12601            }
12602            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12603
12604            // Register the isolated UID with this application so BatteryStats knows to
12605            // attribute resource usage to the application.
12606            //
12607            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12608            // about the process state of the isolated UID *before* it is registered with the
12609            // owning application.
12610            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12611        }
12612        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12613        if (!mBooted && !mBooting
12614                && userId == UserHandle.USER_SYSTEM
12615                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12616            r.persistent = true;
12617            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12618        }
12619        if (isolated && isolatedUid != 0) {
12620            // Special case for startIsolatedProcess (internal only) - assume the process
12621            // is required by the system server to prevent it being killed.
12622            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
12623        }
12624        addProcessNameLocked(r);
12625        return r;
12626    }
12627
12628    private boolean uidOnBackgroundWhitelist(final int uid) {
12629        final int appId = UserHandle.getAppId(uid);
12630        final int[] whitelist = mBackgroundAppIdWhitelist;
12631        final int N = whitelist.length;
12632        for (int i = 0; i < N; i++) {
12633            if (appId == whitelist[i]) {
12634                return true;
12635            }
12636        }
12637        return false;
12638    }
12639
12640    @Override
12641    public void backgroundWhitelistUid(final int uid) {
12642        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12643            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12644        }
12645
12646        if (DEBUG_BACKGROUND_CHECK) {
12647            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12648        }
12649        synchronized (this) {
12650            final int N = mBackgroundAppIdWhitelist.length;
12651            int[] newList = new int[N+1];
12652            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12653            newList[N] = UserHandle.getAppId(uid);
12654            mBackgroundAppIdWhitelist = newList;
12655        }
12656    }
12657
12658    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12659            String abiOverride) {
12660        ProcessRecord app;
12661        if (!isolated) {
12662            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12663                    info.uid, true);
12664        } else {
12665            app = null;
12666        }
12667
12668        if (app == null) {
12669            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12670            updateLruProcessLocked(app, false, null);
12671            updateOomAdjLocked();
12672        }
12673
12674        // This package really, really can not be stopped.
12675        try {
12676            AppGlobals.getPackageManager().setPackageStoppedState(
12677                    info.packageName, false, UserHandle.getUserId(app.uid));
12678        } catch (RemoteException e) {
12679        } catch (IllegalArgumentException e) {
12680            Slog.w(TAG, "Failed trying to unstop package "
12681                    + info.packageName + ": " + e);
12682        }
12683
12684        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12685            app.persistent = true;
12686            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12687        }
12688        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12689            mPersistentStartingProcesses.add(app);
12690            startProcessLocked(app, "added application",
12691                    customProcess != null ? customProcess : app.processName, abiOverride);
12692        }
12693
12694        return app;
12695    }
12696
12697    public void unhandledBack() {
12698        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12699                "unhandledBack()");
12700
12701        synchronized(this) {
12702            final long origId = Binder.clearCallingIdentity();
12703            try {
12704                getFocusedStack().unhandledBackLocked();
12705            } finally {
12706                Binder.restoreCallingIdentity(origId);
12707            }
12708        }
12709    }
12710
12711    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12712        enforceNotIsolatedCaller("openContentUri");
12713        final int userId = UserHandle.getCallingUserId();
12714        final Uri uri = Uri.parse(uriString);
12715        String name = uri.getAuthority();
12716        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12717        ParcelFileDescriptor pfd = null;
12718        if (cph != null) {
12719            // We record the binder invoker's uid in thread-local storage before
12720            // going to the content provider to open the file.  Later, in the code
12721            // that handles all permissions checks, we look for this uid and use
12722            // that rather than the Activity Manager's own uid.  The effect is that
12723            // we do the check against the caller's permissions even though it looks
12724            // to the content provider like the Activity Manager itself is making
12725            // the request.
12726            Binder token = new Binder();
12727            sCallerIdentity.set(new Identity(
12728                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12729            try {
12730                pfd = cph.provider.openFile(null, uri, "r", null, token);
12731            } catch (FileNotFoundException e) {
12732                // do nothing; pfd will be returned null
12733            } finally {
12734                // Ensure that whatever happens, we clean up the identity state
12735                sCallerIdentity.remove();
12736                // Ensure we're done with the provider.
12737                removeContentProviderExternalUnchecked(name, null, userId);
12738            }
12739        } else {
12740            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12741        }
12742        return pfd;
12743    }
12744
12745    // Actually is sleeping or shutting down or whatever else in the future
12746    // is an inactive state.
12747    boolean isSleepingOrShuttingDownLocked() {
12748        return isSleepingLocked() || mShuttingDown;
12749    }
12750
12751    boolean isShuttingDownLocked() {
12752        return mShuttingDown;
12753    }
12754
12755    boolean isSleepingLocked() {
12756        return mSleeping;
12757    }
12758
12759    void onWakefulnessChanged(int wakefulness) {
12760        synchronized(this) {
12761            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12762            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12763            mWakefulness = wakefulness;
12764
12765            if (wasAwake != isAwake) {
12766                // Also update state in a special way for running foreground services UI.
12767                mServices.updateScreenStateLocked(isAwake);
12768                mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12769                        .sendToTarget();
12770            }
12771        }
12772    }
12773
12774    void finishRunningVoiceLocked() {
12775        if (mRunningVoice != null) {
12776            mRunningVoice = null;
12777            mVoiceWakeLock.release();
12778            updateSleepIfNeededLocked();
12779        }
12780    }
12781
12782    void startTimeTrackingFocusedActivityLocked() {
12783        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12784        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12785            mCurAppTimeTracker.start(resumedActivity.packageName);
12786        }
12787    }
12788
12789    void updateSleepIfNeededLocked() {
12790        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12791        final boolean wasSleeping = mSleeping;
12792
12793        if (!shouldSleep) {
12794            // If wasSleeping is true, we need to wake up activity manager state from when
12795            // we started sleeping. In either case, we need to apply the sleep tokens, which
12796            // will wake up stacks or put them to sleep as appropriate.
12797            if (wasSleeping) {
12798                mSleeping = false;
12799                startTimeTrackingFocusedActivityLocked();
12800                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12801                mStackSupervisor.comeOutOfSleepIfNeededLocked();
12802            }
12803            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12804            if (wasSleeping) {
12805                updateOomAdjLocked();
12806            }
12807        } else if (!mSleeping && shouldSleep) {
12808            mSleeping = true;
12809            if (mCurAppTimeTracker != null) {
12810                mCurAppTimeTracker.stop();
12811            }
12812            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12813            mStackSupervisor.goingToSleepLocked();
12814            updateOomAdjLocked();
12815        }
12816    }
12817
12818    /** Pokes the task persister. */
12819    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12820        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12821    }
12822
12823    /**
12824     * Notifies all listeners when the pinned stack animation starts.
12825     */
12826    @Override
12827    public void notifyPinnedStackAnimationStarted() {
12828        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12829    }
12830
12831    /**
12832     * Notifies all listeners when the pinned stack animation ends.
12833     */
12834    @Override
12835    public void notifyPinnedStackAnimationEnded() {
12836        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12837    }
12838
12839    @Override
12840    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12841        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12842    }
12843
12844    @Override
12845    public boolean shutdown(int timeout) {
12846        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12847                != PackageManager.PERMISSION_GRANTED) {
12848            throw new SecurityException("Requires permission "
12849                    + android.Manifest.permission.SHUTDOWN);
12850        }
12851
12852        // TODO: Where should the corresponding '1' (start) write go?
12853        StatsLog.write(StatsLog.DEVICE_ON_STATUS_CHANGED,
12854                StatsLog.DEVICE_ON_STATUS_CHANGED__STATE__OFF);
12855
12856        boolean timedout = false;
12857
12858        synchronized(this) {
12859            mShuttingDown = true;
12860            mStackSupervisor.prepareForShutdownLocked();
12861            updateEventDispatchingLocked();
12862            timedout = mStackSupervisor.shutdownLocked(timeout);
12863        }
12864
12865        mAppOpsService.shutdown();
12866        if (mUsageStatsService != null) {
12867            mUsageStatsService.prepareShutdown();
12868        }
12869        mBatteryStatsService.shutdown();
12870        synchronized (this) {
12871            mProcessStats.shutdownLocked();
12872            notifyTaskPersisterLocked(null, true);
12873        }
12874
12875        return timedout;
12876    }
12877
12878    public final void activitySlept(IBinder token) {
12879        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12880
12881        final long origId = Binder.clearCallingIdentity();
12882
12883        synchronized (this) {
12884            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12885            if (r != null) {
12886                mStackSupervisor.activitySleptLocked(r);
12887            }
12888        }
12889
12890        Binder.restoreCallingIdentity(origId);
12891    }
12892
12893    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12894        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12895        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12896        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12897            boolean wasRunningVoice = mRunningVoice != null;
12898            mRunningVoice = session;
12899            if (!wasRunningVoice) {
12900                mVoiceWakeLock.acquire();
12901                updateSleepIfNeededLocked();
12902            }
12903        }
12904    }
12905
12906    private void updateEventDispatchingLocked() {
12907        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12908    }
12909
12910    @Override
12911    public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12912        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12913                != PackageManager.PERMISSION_GRANTED) {
12914            throw new SecurityException("Requires permission "
12915                    + android.Manifest.permission.DEVICE_POWER);
12916        }
12917
12918        synchronized(this) {
12919            long ident = Binder.clearCallingIdentity();
12920            try {
12921                mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12922            } finally {
12923                Binder.restoreCallingIdentity(ident);
12924            }
12925        }
12926
12927        mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12928                .sendToTarget();
12929    }
12930
12931    @Override
12932    public void notifyLockedProfile(@UserIdInt int userId) {
12933        try {
12934            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12935                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12936            }
12937        } catch (RemoteException ex) {
12938            throw new SecurityException("Fail to check is caller a privileged app", ex);
12939        }
12940
12941        synchronized (this) {
12942            final long ident = Binder.clearCallingIdentity();
12943            try {
12944                if (mUserController.shouldConfirmCredentials(userId)) {
12945                    if (mKeyguardController.isKeyguardLocked()) {
12946                        // Showing launcher to avoid user entering credential twice.
12947                        final int currentUserId = mUserController.getCurrentUserId();
12948                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12949                    }
12950                    mStackSupervisor.lockAllProfileTasks(userId);
12951                }
12952            } finally {
12953                Binder.restoreCallingIdentity(ident);
12954            }
12955        }
12956    }
12957
12958    @Override
12959    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12960        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12961        synchronized (this) {
12962            final long ident = Binder.clearCallingIdentity();
12963            try {
12964                intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
12965                        FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
12966                        FLAG_ACTIVITY_TASK_ON_HOME);
12967                ActivityOptions activityOptions = options != null
12968                        ? new ActivityOptions(options)
12969                        : ActivityOptions.makeBasic();
12970                activityOptions.setLaunchTaskId(
12971                        mStackSupervisor.getHomeActivity().getTask().taskId);
12972                mContext.startActivityAsUser(intent, activityOptions.toBundle(),
12973                        UserHandle.CURRENT);
12974            } finally {
12975                Binder.restoreCallingIdentity(ident);
12976            }
12977        }
12978    }
12979
12980    @Override
12981    public void stopAppSwitches() {
12982        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12983                != PackageManager.PERMISSION_GRANTED) {
12984            throw new SecurityException("viewquires permission "
12985                    + android.Manifest.permission.STOP_APP_SWITCHES);
12986        }
12987
12988        synchronized(this) {
12989            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12990                    + APP_SWITCH_DELAY_TIME;
12991            mDidAppSwitch = false;
12992            mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
12993        }
12994    }
12995
12996    public void resumeAppSwitches() {
12997        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12998                != PackageManager.PERMISSION_GRANTED) {
12999            throw new SecurityException("Requires permission "
13000                    + android.Manifest.permission.STOP_APP_SWITCHES);
13001        }
13002
13003        synchronized(this) {
13004            // Note that we don't execute any pending app switches... we will
13005            // let those wait until either the timeout, or the next start
13006            // activity request.
13007            mAppSwitchesAllowedTime = 0;
13008        }
13009    }
13010
13011    boolean checkAllowAppSwitchUid(int uid) {
13012        ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
13013        if (types != null) {
13014            for (int i = types.size() - 1; i >= 0; i--) {
13015                if (types.valueAt(i).intValue() == uid) {
13016                    return true;
13017                }
13018            }
13019        }
13020        return false;
13021    }
13022
13023    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
13024            int callingPid, int callingUid, String name) {
13025        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
13026            return true;
13027        }
13028
13029        int perm = checkComponentPermission(
13030                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
13031                sourceUid, -1, true);
13032        if (perm == PackageManager.PERMISSION_GRANTED) {
13033            return true;
13034        }
13035        if (checkAllowAppSwitchUid(sourceUid)) {
13036            return true;
13037        }
13038
13039        // If the actual IPC caller is different from the logical source, then
13040        // also see if they are allowed to control app switches.
13041        if (callingUid != -1 && callingUid != sourceUid) {
13042            perm = checkComponentPermission(
13043                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
13044                    callingUid, -1, true);
13045            if (perm == PackageManager.PERMISSION_GRANTED) {
13046                return true;
13047            }
13048            if (checkAllowAppSwitchUid(callingUid)) {
13049                return true;
13050            }
13051        }
13052
13053        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
13054        return false;
13055    }
13056
13057    public void setDebugApp(String packageName, boolean waitForDebugger,
13058            boolean persistent) {
13059        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
13060                "setDebugApp()");
13061
13062        long ident = Binder.clearCallingIdentity();
13063        try {
13064            // Note that this is not really thread safe if there are multiple
13065            // callers into it at the same time, but that's not a situation we
13066            // care about.
13067            if (persistent) {
13068                final ContentResolver resolver = mContext.getContentResolver();
13069                Settings.Global.putString(
13070                    resolver, Settings.Global.DEBUG_APP,
13071                    packageName);
13072                Settings.Global.putInt(
13073                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13074                    waitForDebugger ? 1 : 0);
13075            }
13076
13077            synchronized (this) {
13078                if (!persistent) {
13079                    mOrigDebugApp = mDebugApp;
13080                    mOrigWaitForDebugger = mWaitForDebugger;
13081                }
13082                mDebugApp = packageName;
13083                mWaitForDebugger = waitForDebugger;
13084                mDebugTransient = !persistent;
13085                if (packageName != null) {
13086                    forceStopPackageLocked(packageName, -1, false, false, true, true,
13087                            false, UserHandle.USER_ALL, "set debug app");
13088                }
13089            }
13090        } finally {
13091            Binder.restoreCallingIdentity(ident);
13092        }
13093    }
13094
13095    /**
13096     * Set or remove an agent to be run whenever an app with the given process name starts.
13097     *
13098     * This method will not check whether the given process name matches a debuggable app. That
13099     * would require scanning all current packages, and a rescan when new packages are installed
13100     * or updated.
13101     *
13102     * Instead, do the check when an application is started and matched to a stored agent.
13103     *
13104     * @param packageName the process name of the app.
13105     * @param agent the agent string to be used, or null to remove any previously set agent.
13106     */
13107    @Override
13108    public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
13109        synchronized (this) {
13110            // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13111            // its own permission.
13112            if (checkCallingPermission(
13113                    android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
13114                        PackageManager.PERMISSION_GRANTED) {
13115                throw new SecurityException(
13116                        "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13117            }
13118
13119            if (agent == null) {
13120                if (mAppAgentMap != null) {
13121                    mAppAgentMap.remove(packageName);
13122                    if (mAppAgentMap.isEmpty()) {
13123                        mAppAgentMap = null;
13124                    }
13125                }
13126            } else {
13127                if (mAppAgentMap == null) {
13128                    mAppAgentMap = new HashMap<>();
13129                }
13130                if (mAppAgentMap.size() >= 100) {
13131                    // Limit the size of the map, to avoid OOMEs.
13132                    Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
13133                            + "/" + agent);
13134                    return;
13135                }
13136                mAppAgentMap.put(packageName, agent);
13137            }
13138        }
13139    }
13140
13141    void setTrackAllocationApp(ApplicationInfo app, String processName) {
13142        synchronized (this) {
13143            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13144            if (!isDebuggable) {
13145                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13146                    throw new SecurityException("Process not debuggable: " + app.packageName);
13147                }
13148            }
13149
13150            mTrackAllocationApp = processName;
13151        }
13152    }
13153
13154    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
13155        synchronized (this) {
13156            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13157            if (!isDebuggable) {
13158                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13159                    throw new SecurityException("Process not debuggable: " + app.packageName);
13160                }
13161            }
13162            mProfileApp = processName;
13163
13164            if (mProfilerInfo != null) {
13165                if (mProfilerInfo.profileFd != null) {
13166                    try {
13167                        mProfilerInfo.profileFd.close();
13168                    } catch (IOException e) {
13169                    }
13170                }
13171            }
13172            mProfilerInfo = new ProfilerInfo(profilerInfo);
13173            mProfileType = 0;
13174        }
13175    }
13176
13177    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
13178        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13179        if (!isDebuggable) {
13180            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13181                throw new SecurityException("Process not debuggable: " + app.packageName);
13182            }
13183        }
13184        mNativeDebuggingApp = processName;
13185    }
13186
13187    @Override
13188    public void setAlwaysFinish(boolean enabled) {
13189        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13190                "setAlwaysFinish()");
13191
13192        long ident = Binder.clearCallingIdentity();
13193        try {
13194            Settings.Global.putInt(
13195                    mContext.getContentResolver(),
13196                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13197
13198            synchronized (this) {
13199                mAlwaysFinishActivities = enabled;
13200            }
13201        } finally {
13202            Binder.restoreCallingIdentity(ident);
13203        }
13204    }
13205
13206    @Override
13207    public void setActivityController(IActivityController controller, boolean imAMonkey) {
13208        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13209                "setActivityController()");
13210        synchronized (this) {
13211            mController = controller;
13212            mControllerIsAMonkey = imAMonkey;
13213            Watchdog.getInstance().setActivityController(controller);
13214        }
13215    }
13216
13217    @Override
13218    public void setUserIsMonkey(boolean userIsMonkey) {
13219        synchronized (this) {
13220            synchronized (mPidsSelfLocked) {
13221                final int callingPid = Binder.getCallingPid();
13222                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13223                if (proc == null) {
13224                    throw new SecurityException("Unknown process: " + callingPid);
13225                }
13226                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13227                    throw new SecurityException("Only an instrumentation process "
13228                            + "with a UiAutomation can call setUserIsMonkey");
13229                }
13230            }
13231            mUserIsMonkey = userIsMonkey;
13232        }
13233    }
13234
13235    @Override
13236    public boolean isUserAMonkey() {
13237        synchronized (this) {
13238            // If there is a controller also implies the user is a monkey.
13239            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13240        }
13241    }
13242
13243    /**
13244     * @deprecated This method is only used by a few internal components and it will soon be
13245     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13246     * No new code should be calling it.
13247     */
13248    @Deprecated
13249    @Override
13250    public void requestBugReport(int bugreportType) {
13251        String extraOptions = null;
13252        switch (bugreportType) {
13253            case ActivityManager.BUGREPORT_OPTION_FULL:
13254                // Default options.
13255                break;
13256            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13257                extraOptions = "bugreportplus";
13258                break;
13259            case ActivityManager.BUGREPORT_OPTION_REMOTE:
13260                extraOptions = "bugreportremote";
13261                break;
13262            case ActivityManager.BUGREPORT_OPTION_WEAR:
13263                extraOptions = "bugreportwear";
13264                break;
13265            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13266                extraOptions = "bugreporttelephony";
13267                break;
13268            case ActivityManager.BUGREPORT_OPTION_WIFI:
13269                extraOptions = "bugreportwifi";
13270                break;
13271            default:
13272                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13273                        + bugreportType);
13274        }
13275        // Always log caller, even if it does not have permission to dump.
13276        String type = extraOptions == null ? "bugreport" : extraOptions;
13277        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13278
13279        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13280        if (extraOptions != null) {
13281            SystemProperties.set("dumpstate.options", extraOptions);
13282        }
13283        SystemProperties.set("ctl.start", "bugreport");
13284    }
13285
13286    /**
13287     * @deprecated This method is only used by a few internal components and it will soon be
13288     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13289     * No new code should be calling it.
13290     */
13291    @Deprecated
13292    private void requestBugReportWithDescription(String shareTitle, String shareDescription,
13293                                                 int bugreportType) {
13294        if (!TextUtils.isEmpty(shareTitle)) {
13295            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13296                String errorStr = "shareTitle should be less than " +
13297                        MAX_BUGREPORT_TITLE_SIZE + " characters";
13298                throw new IllegalArgumentException(errorStr);
13299            } else {
13300                if (!TextUtils.isEmpty(shareDescription)) {
13301                    int length;
13302                    try {
13303                        length = shareDescription.getBytes("UTF-8").length;
13304                    } catch (UnsupportedEncodingException e) {
13305                        String errorStr = "shareDescription: UnsupportedEncodingException";
13306                        throw new IllegalArgumentException(errorStr);
13307                    }
13308                    if (length > SystemProperties.PROP_VALUE_MAX) {
13309                        String errorStr = "shareTitle should be less than " +
13310                                SystemProperties.PROP_VALUE_MAX + " bytes";
13311                        throw new IllegalArgumentException(errorStr);
13312                    } else {
13313                        SystemProperties.set("dumpstate.options.description", shareDescription);
13314                    }
13315                }
13316                SystemProperties.set("dumpstate.options.title", shareTitle);
13317            }
13318        }
13319
13320        Slog.d(TAG, "Bugreport notification title " + shareTitle
13321                + " description " + shareDescription);
13322        requestBugReport(bugreportType);
13323    }
13324
13325    /**
13326     * @deprecated This method is only used by a few internal components and it will soon be
13327     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13328     * No new code should be calling it.
13329     */
13330    @Deprecated
13331    @Override
13332    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13333        requestBugReportWithDescription(shareTitle, shareDescription,
13334                ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13335    }
13336
13337    /**
13338     * @deprecated This method is only used by a few internal components and it will soon be
13339     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13340     * No new code should be calling it.
13341     */
13342    @Deprecated
13343    @Override
13344    public void requestWifiBugReport(String shareTitle, String shareDescription) {
13345        requestBugReportWithDescription(shareTitle, shareDescription,
13346                ActivityManager.BUGREPORT_OPTION_WIFI);
13347    }
13348
13349
13350    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13351        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13352    }
13353
13354    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13355        if (r != null && (r.instr != null || r.usingWrapper)) {
13356            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13357        }
13358        return KEY_DISPATCHING_TIMEOUT;
13359    }
13360
13361    @Override
13362    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13363        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13364                != PackageManager.PERMISSION_GRANTED) {
13365            throw new SecurityException("Requires permission "
13366                    + android.Manifest.permission.FILTER_EVENTS);
13367        }
13368        ProcessRecord proc;
13369        long timeout;
13370        synchronized (this) {
13371            synchronized (mPidsSelfLocked) {
13372                proc = mPidsSelfLocked.get(pid);
13373            }
13374            timeout = getInputDispatchingTimeoutLocked(proc);
13375        }
13376
13377        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13378            return -1;
13379        }
13380
13381        return timeout;
13382    }
13383
13384    /**
13385     * Handle input dispatching timeouts.
13386     * Returns whether input dispatching should be aborted or not.
13387     */
13388    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13389            final ActivityRecord activity, final ActivityRecord parent,
13390            final boolean aboveSystem, String reason) {
13391        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13392                != PackageManager.PERMISSION_GRANTED) {
13393            throw new SecurityException("Requires permission "
13394                    + android.Manifest.permission.FILTER_EVENTS);
13395        }
13396
13397        final String annotation;
13398        if (reason == null) {
13399            annotation = "Input dispatching timed out";
13400        } else {
13401            annotation = "Input dispatching timed out (" + reason + ")";
13402        }
13403
13404        if (proc != null) {
13405            synchronized (this) {
13406                if (proc.debugging) {
13407                    return false;
13408                }
13409
13410                if (proc.instr != null) {
13411                    Bundle info = new Bundle();
13412                    info.putString("shortMsg", "keyDispatchingTimedOut");
13413                    info.putString("longMsg", annotation);
13414                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13415                    return true;
13416                }
13417            }
13418            mHandler.post(new Runnable() {
13419                @Override
13420                public void run() {
13421                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13422                }
13423            });
13424        }
13425
13426        return true;
13427    }
13428
13429    @Override
13430    public Bundle getAssistContextExtras(int requestType) {
13431        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13432                null, null, true /* focused */, true /* newSessionId */,
13433                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13434        if (pae == null) {
13435            return null;
13436        }
13437        synchronized (pae) {
13438            while (!pae.haveResult) {
13439                try {
13440                    pae.wait();
13441                } catch (InterruptedException e) {
13442                }
13443            }
13444        }
13445        synchronized (this) {
13446            buildAssistBundleLocked(pae, pae.result);
13447            mPendingAssistExtras.remove(pae);
13448            mUiHandler.removeCallbacks(pae);
13449        }
13450        return pae.extras;
13451    }
13452
13453    @Override
13454    public boolean isAssistDataAllowedOnCurrentActivity() {
13455        int userId;
13456        synchronized (this) {
13457            final ActivityStack focusedStack = getFocusedStack();
13458            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
13459                return false;
13460            }
13461
13462            final ActivityRecord activity = focusedStack.getTopActivity();
13463            if (activity == null) {
13464                return false;
13465            }
13466            userId = activity.userId;
13467        }
13468        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13469                Context.DEVICE_POLICY_SERVICE);
13470        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13471    }
13472
13473    @Override
13474    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13475        long ident = Binder.clearCallingIdentity();
13476        try {
13477            synchronized (this) {
13478                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13479                ActivityRecord top = getFocusedStack().getTopActivity();
13480                if (top != caller) {
13481                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13482                            + " is not current top " + top);
13483                    return false;
13484                }
13485                if (!top.nowVisible) {
13486                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13487                            + " is not visible");
13488                    return false;
13489                }
13490            }
13491            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13492                    token);
13493        } finally {
13494            Binder.restoreCallingIdentity(ident);
13495        }
13496    }
13497
13498    @Override
13499    public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
13500            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13501        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13502                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13503                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13504    }
13505
13506    @Override
13507    public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
13508            IBinder activityToken, int flags) {
13509        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13510                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13511                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13512    }
13513
13514    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13515            IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13516            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13517            int flags) {
13518        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13519                "enqueueAssistContext()");
13520
13521        synchronized (this) {
13522            ActivityRecord activity = getFocusedStack().getTopActivity();
13523            if (activity == null) {
13524                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13525                return null;
13526            }
13527            if (activity.app == null || activity.app.thread == null) {
13528                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13529                return null;
13530            }
13531            if (focused) {
13532                if (activityToken != null) {
13533                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13534                    if (activity != caller) {
13535                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13536                                + " is not current top " + activity);
13537                        return null;
13538                    }
13539                }
13540            } else {
13541                activity = ActivityRecord.forTokenLocked(activityToken);
13542                if (activity == null) {
13543                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13544                            + " couldn't be found");
13545                    return null;
13546                }
13547                if (activity.app == null || activity.app.thread == null) {
13548                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13549                    return null;
13550                }
13551            }
13552
13553            PendingAssistExtras pae;
13554            Bundle extras = new Bundle();
13555            if (args != null) {
13556                extras.putAll(args);
13557            }
13558            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13559            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13560
13561            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13562                    userHandle);
13563            pae.isHome = activity.isActivityTypeHome();
13564
13565            // Increment the sessionId if necessary
13566            if (newSessionId) {
13567                mViSessionId++;
13568            }
13569            try {
13570                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13571                        mViSessionId, flags);
13572                mPendingAssistExtras.add(pae);
13573                mUiHandler.postDelayed(pae, timeout);
13574            } catch (RemoteException e) {
13575                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13576                return null;
13577            }
13578            return pae;
13579        }
13580    }
13581
13582    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13583        IAssistDataReceiver receiver;
13584        synchronized (this) {
13585            mPendingAssistExtras.remove(pae);
13586            receiver = pae.receiver;
13587        }
13588        if (receiver != null) {
13589            // Caller wants result sent back to them.
13590            Bundle sendBundle = new Bundle();
13591            // At least return the receiver extras
13592            sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13593            try {
13594                pae.receiver.onHandleAssistData(sendBundle);
13595            } catch (RemoteException e) {
13596            }
13597        }
13598    }
13599
13600    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13601        if (result != null) {
13602            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13603        }
13604        if (pae.hint != null) {
13605            pae.extras.putBoolean(pae.hint, true);
13606        }
13607    }
13608
13609    /** Called from an app when assist data is ready. */
13610    @Override
13611    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13612            AssistContent content, Uri referrer) {
13613        PendingAssistExtras pae = (PendingAssistExtras)token;
13614        synchronized (pae) {
13615            pae.result = extras;
13616            pae.structure = structure;
13617            pae.content = content;
13618            if (referrer != null) {
13619                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13620            }
13621            if (structure != null) {
13622                structure.setHomeActivity(pae.isHome);
13623            }
13624            pae.haveResult = true;
13625            pae.notifyAll();
13626            if (pae.intent == null && pae.receiver == null) {
13627                // Caller is just waiting for the result.
13628                return;
13629            }
13630        }
13631        // We are now ready to launch the assist activity.
13632        IAssistDataReceiver sendReceiver = null;
13633        Bundle sendBundle = null;
13634        synchronized (this) {
13635            buildAssistBundleLocked(pae, extras);
13636            boolean exists = mPendingAssistExtras.remove(pae);
13637            mUiHandler.removeCallbacks(pae);
13638            if (!exists) {
13639                // Timed out.
13640                return;
13641            }
13642            if ((sendReceiver=pae.receiver) != null) {
13643                // Caller wants result sent back to them.
13644                sendBundle = new Bundle();
13645                sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
13646                sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
13647                sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
13648                sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13649            }
13650        }
13651        if (sendReceiver != null) {
13652            try {
13653                sendReceiver.onHandleAssistData(sendBundle);
13654            } catch (RemoteException e) {
13655            }
13656            return;
13657        }
13658
13659        final long ident = Binder.clearCallingIdentity();
13660        try {
13661            if (TextUtils.equals(pae.intent.getAction(),
13662                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13663                pae.intent.putExtras(pae.extras);
13664                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13665            } else {
13666                pae.intent.replaceExtras(pae.extras);
13667                pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
13668                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
13669                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13670                closeSystemDialogs("assist");
13671
13672                try {
13673                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13674                } catch (ActivityNotFoundException e) {
13675                    Slog.w(TAG, "No activity to handle assist action.", e);
13676                }
13677            }
13678        } finally {
13679            Binder.restoreCallingIdentity(ident);
13680        }
13681    }
13682
13683    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13684            Bundle args) {
13685        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13686                true /* focused */, true /* newSessionId */, userHandle, args,
13687                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13688    }
13689
13690    public void registerProcessObserver(IProcessObserver observer) {
13691        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13692                "registerProcessObserver()");
13693        synchronized (this) {
13694            mProcessObservers.register(observer);
13695        }
13696    }
13697
13698    @Override
13699    public void unregisterProcessObserver(IProcessObserver observer) {
13700        synchronized (this) {
13701            mProcessObservers.unregister(observer);
13702        }
13703    }
13704
13705    @Override
13706    public int getUidProcessState(int uid, String callingPackage) {
13707        if (!hasUsageStatsPermission(callingPackage)) {
13708            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13709                    "getUidProcessState");
13710        }
13711
13712        synchronized (this) {
13713            UidRecord uidRec = mActiveUids.get(uid);
13714            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13715        }
13716    }
13717
13718    @Override
13719    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13720            String callingPackage) {
13721        if (!hasUsageStatsPermission(callingPackage)) {
13722            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13723                    "registerUidObserver");
13724        }
13725        synchronized (this) {
13726            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13727                    callingPackage, which, cutpoint));
13728        }
13729    }
13730
13731    @Override
13732    public void unregisterUidObserver(IUidObserver observer) {
13733        synchronized (this) {
13734            mUidObservers.unregister(observer);
13735        }
13736    }
13737
13738    @Override
13739    public boolean convertFromTranslucent(IBinder token) {
13740        final long origId = Binder.clearCallingIdentity();
13741        try {
13742            synchronized (this) {
13743                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13744                if (r == null) {
13745                    return false;
13746                }
13747                final boolean translucentChanged = r.changeWindowTranslucency(true);
13748                if (translucentChanged) {
13749                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13750                }
13751                mWindowManager.setAppFullscreen(token, true);
13752                return translucentChanged;
13753            }
13754        } finally {
13755            Binder.restoreCallingIdentity(origId);
13756        }
13757    }
13758
13759    @Override
13760    public boolean convertToTranslucent(IBinder token, Bundle options) {
13761        SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
13762        final long origId = Binder.clearCallingIdentity();
13763        try {
13764            synchronized (this) {
13765                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13766                if (r == null) {
13767                    return false;
13768                }
13769                final TaskRecord task = r.getTask();
13770                int index = task.mActivities.lastIndexOf(r);
13771                if (index > 0) {
13772                    ActivityRecord under = task.mActivities.get(index - 1);
13773                    under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
13774                }
13775                final boolean translucentChanged = r.changeWindowTranslucency(false);
13776                if (translucentChanged) {
13777                    r.getStack().convertActivityToTranslucent(r);
13778                }
13779                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13780                mWindowManager.setAppFullscreen(token, false);
13781                return translucentChanged;
13782            }
13783        } finally {
13784            Binder.restoreCallingIdentity(origId);
13785        }
13786    }
13787
13788    @Override
13789    public Bundle getActivityOptions(IBinder token) {
13790        final long origId = Binder.clearCallingIdentity();
13791        try {
13792            synchronized (this) {
13793                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13794                if (r != null) {
13795                    final ActivityOptions activityOptions = r.takeOptionsLocked();
13796                    return activityOptions == null ? null : activityOptions.toBundle();
13797                }
13798                return null;
13799            }
13800        } finally {
13801            Binder.restoreCallingIdentity(origId);
13802        }
13803    }
13804
13805    @Override
13806    public void setImmersive(IBinder token, boolean immersive) {
13807        synchronized(this) {
13808            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13809            if (r == null) {
13810                throw new IllegalArgumentException();
13811            }
13812            r.immersive = immersive;
13813
13814            // update associated state if we're frontmost
13815            if (r == mStackSupervisor.getResumedActivityLocked()) {
13816                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13817                applyUpdateLockStateLocked(r);
13818            }
13819        }
13820    }
13821
13822    @Override
13823    public boolean isImmersive(IBinder token) {
13824        synchronized (this) {
13825            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13826            if (r == null) {
13827                throw new IllegalArgumentException();
13828            }
13829            return r.immersive;
13830        }
13831    }
13832
13833    @Override
13834    public void setVrThread(int tid) {
13835        enforceSystemHasVrFeature();
13836        synchronized (this) {
13837            synchronized (mPidsSelfLocked) {
13838                final int pid = Binder.getCallingPid();
13839                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13840                mVrController.setVrThreadLocked(tid, pid, proc);
13841            }
13842        }
13843    }
13844
13845    @Override
13846    public void setPersistentVrThread(int tid) {
13847        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13848            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13849                    + Binder.getCallingPid()
13850                    + ", uid=" + Binder.getCallingUid()
13851                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13852            Slog.w(TAG, msg);
13853            throw new SecurityException(msg);
13854        }
13855        enforceSystemHasVrFeature();
13856        synchronized (this) {
13857            synchronized (mPidsSelfLocked) {
13858                final int pid = Binder.getCallingPid();
13859                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13860                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13861            }
13862        }
13863    }
13864
13865    /**
13866     * Schedule the given thread a normal scheduling priority.
13867     *
13868     * @param tid the tid of the thread to adjust the scheduling of.
13869     * @param suppressLogs {@code true} if any error logging should be disabled.
13870     *
13871     * @return {@code true} if this succeeded.
13872     */
13873    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13874        try {
13875            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13876            return true;
13877        } catch (IllegalArgumentException e) {
13878            if (!suppressLogs) {
13879                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13880            }
13881        } catch (SecurityException e) {
13882            if (!suppressLogs) {
13883                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13884            }
13885        }
13886        return false;
13887    }
13888
13889    /**
13890     * Schedule the given thread an FIFO scheduling priority.
13891     *
13892     * @param tid the tid of the thread to adjust the scheduling of.
13893     * @param suppressLogs {@code true} if any error logging should be disabled.
13894     *
13895     * @return {@code true} if this succeeded.
13896     */
13897    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13898        try {
13899            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13900            return true;
13901        } catch (IllegalArgumentException e) {
13902            if (!suppressLogs) {
13903                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13904            }
13905        } catch (SecurityException e) {
13906            if (!suppressLogs) {
13907                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13908            }
13909        }
13910        return false;
13911    }
13912
13913    /**
13914     * Check that we have the features required for VR-related API calls, and throw an exception if
13915     * not.
13916     */
13917    private void enforceSystemHasVrFeature() {
13918        if (!mContext.getPackageManager().hasSystemFeature(
13919                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
13920            throw new UnsupportedOperationException("VR mode not supported on this device!");
13921        }
13922    }
13923
13924    @Override
13925    public void setRenderThread(int tid) {
13926        synchronized (this) {
13927            ProcessRecord proc;
13928            int pid = Binder.getCallingPid();
13929            if (pid == Process.myPid()) {
13930                demoteSystemServerRenderThread(tid);
13931                return;
13932            }
13933            synchronized (mPidsSelfLocked) {
13934                proc = mPidsSelfLocked.get(pid);
13935                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13936                    // ensure the tid belongs to the process
13937                    if (!isThreadInProcess(pid, tid)) {
13938                        throw new IllegalArgumentException(
13939                            "Render thread does not belong to process");
13940                    }
13941                    proc.renderThreadTid = tid;
13942                    if (DEBUG_OOM_ADJ) {
13943                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13944                    }
13945                    // promote to FIFO now
13946                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13947                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13948                        if (mUseFifoUiScheduling) {
13949                            setThreadScheduler(proc.renderThreadTid,
13950                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13951                        } else {
13952                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13953                        }
13954                    }
13955                } else {
13956                    if (DEBUG_OOM_ADJ) {
13957                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13958                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13959                               mUseFifoUiScheduling);
13960                    }
13961                }
13962            }
13963        }
13964    }
13965
13966    /**
13967     * We only use RenderThread in system_server to store task snapshots to the disk, which should
13968     * happen in the background. Thus, demote render thread from system_server to a lower priority.
13969     *
13970     * @param tid the tid of the RenderThread
13971     */
13972    private void demoteSystemServerRenderThread(int tid) {
13973        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13974    }
13975
13976    @Override
13977    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13978        enforceSystemHasVrFeature();
13979
13980        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13981
13982        ActivityRecord r;
13983        synchronized (this) {
13984            r = ActivityRecord.isInStackLocked(token);
13985        }
13986
13987        if (r == null) {
13988            throw new IllegalArgumentException();
13989        }
13990
13991        int err;
13992        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13993                VrManagerInternal.NO_ERROR) {
13994            return err;
13995        }
13996
13997        synchronized(this) {
13998            r.requestedVrComponent = (enabled) ? packageName : null;
13999
14000            // Update associated state if this activity is currently focused
14001            if (r == mStackSupervisor.getResumedActivityLocked()) {
14002                applyUpdateVrModeLocked(r);
14003            }
14004            return 0;
14005        }
14006    }
14007
14008    @Override
14009    public boolean isVrModePackageEnabled(ComponentName packageName) {
14010        enforceSystemHasVrFeature();
14011
14012        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14013
14014        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
14015                VrManagerInternal.NO_ERROR;
14016    }
14017
14018    public boolean isTopActivityImmersive() {
14019        enforceNotIsolatedCaller("startActivity");
14020        synchronized (this) {
14021            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
14022            return (r != null) ? r.immersive : false;
14023        }
14024    }
14025
14026    /**
14027     * @return whether the system should disable UI modes incompatible with VR mode.
14028     */
14029    boolean shouldDisableNonVrUiLocked() {
14030        return mVrController.shouldDisableNonVrUiLocked();
14031    }
14032
14033    @Override
14034    public boolean isTopOfTask(IBinder token) {
14035        synchronized (this) {
14036            ActivityRecord r = ActivityRecord.isInStackLocked(token);
14037            if (r == null) {
14038                throw new IllegalArgumentException();
14039            }
14040            return r.getTask().getTopActivity() == r;
14041        }
14042    }
14043
14044    @Override
14045    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
14046        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
14047            String msg = "Permission Denial: setHasTopUi() from pid="
14048                    + Binder.getCallingPid()
14049                    + ", uid=" + Binder.getCallingUid()
14050                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
14051            Slog.w(TAG, msg);
14052            throw new SecurityException(msg);
14053        }
14054        final int pid = Binder.getCallingPid();
14055        final long origId = Binder.clearCallingIdentity();
14056        try {
14057            synchronized (this) {
14058                boolean changed = false;
14059                ProcessRecord pr;
14060                synchronized (mPidsSelfLocked) {
14061                    pr = mPidsSelfLocked.get(pid);
14062                    if (pr == null) {
14063                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
14064                        return;
14065                    }
14066                    if (pr.hasTopUi != hasTopUi) {
14067                        if (DEBUG_OOM_ADJ) {
14068                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
14069                        }
14070                        pr.hasTopUi = hasTopUi;
14071                        changed = true;
14072                    }
14073                }
14074                if (changed) {
14075                    updateOomAdjLocked(pr, true);
14076                }
14077            }
14078        } finally {
14079            Binder.restoreCallingIdentity(origId);
14080        }
14081    }
14082
14083    public final void enterSafeMode() {
14084        synchronized(this) {
14085            // It only makes sense to do this before the system is ready
14086            // and started launching other packages.
14087            if (!mSystemReady) {
14088                try {
14089                    AppGlobals.getPackageManager().enterSafeMode();
14090                } catch (RemoteException e) {
14091                }
14092            }
14093
14094            mSafeMode = true;
14095        }
14096    }
14097
14098    public final void showSafeModeOverlay() {
14099        View v = LayoutInflater.from(mContext).inflate(
14100                com.android.internal.R.layout.safe_mode, null);
14101        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
14102        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
14103        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
14104        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
14105        lp.gravity = Gravity.BOTTOM | Gravity.START;
14106        lp.format = v.getBackground().getOpacity();
14107        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
14108                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
14109        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
14110        ((WindowManager)mContext.getSystemService(
14111                Context.WINDOW_SERVICE)).addView(v, lp);
14112    }
14113
14114    @Override
14115    public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
14116            String sourcePkg, String tag) {
14117        if (workSource != null && workSource.isEmpty()) {
14118            workSource = null;
14119        }
14120
14121        if (sourceUid <= 0 && workSource == null) {
14122            // Try and derive a UID to attribute things to based on the caller.
14123            if (sender != null) {
14124                if (!(sender instanceof PendingIntentRecord)) {
14125                    return;
14126                }
14127
14128                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14129                final int callerUid = Binder.getCallingUid();
14130                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14131            } else {
14132                // TODO(narayan): Should we throw an exception in this case ? It means that we
14133                // haven't been able to derive a UID to attribute things to.
14134                return;
14135            }
14136        }
14137
14138        if (DEBUG_POWER) {
14139            Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
14140                    + ", workSource=" + workSource + ", tag=" + tag + "]");
14141        }
14142
14143        mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
14144    }
14145
14146    @Override
14147    public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14148            String tag) {
14149        if (workSource != null && workSource.isEmpty()) {
14150            workSource = null;
14151        }
14152
14153        if (sourceUid <= 0 && workSource == null) {
14154            // Try and derive a UID to attribute things to based on the caller.
14155            if (sender != null) {
14156                if (!(sender instanceof PendingIntentRecord)) {
14157                    return;
14158                }
14159
14160                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14161                final int callerUid = Binder.getCallingUid();
14162                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14163            } else {
14164                // TODO(narayan): Should we throw an exception in this case ? It means that we
14165                // haven't been able to derive a UID to attribute things to.
14166                return;
14167            }
14168        }
14169
14170        if (DEBUG_POWER) {
14171            Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14172                    ", tag=" + tag + "]");
14173        }
14174
14175        mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14176    }
14177
14178    @Override
14179    public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14180            String tag) {
14181        if (workSource != null && workSource.isEmpty()) {
14182            workSource = null;
14183        }
14184
14185        if (sourceUid <= 0 && workSource == null) {
14186            // Try and derive a UID to attribute things to based on the caller.
14187            if (sender != null) {
14188                if (!(sender instanceof PendingIntentRecord)) {
14189                    return;
14190                }
14191
14192                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14193                final int callerUid = Binder.getCallingUid();
14194                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14195            } else {
14196                // TODO(narayan): Should we throw an exception in this case ? It means that we
14197                // haven't been able to derive a UID to attribute things to.
14198                return;
14199            }
14200        }
14201
14202        if (DEBUG_POWER) {
14203            Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14204                    ", tag=" + tag + "]");
14205        }
14206
14207        mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
14208    }
14209
14210    public boolean killPids(int[] pids, String pReason, boolean secure) {
14211        if (Binder.getCallingUid() != SYSTEM_UID) {
14212            throw new SecurityException("killPids only available to the system");
14213        }
14214        String reason = (pReason == null) ? "Unknown" : pReason;
14215        // XXX Note: don't acquire main activity lock here, because the window
14216        // manager calls in with its locks held.
14217
14218        boolean killed = false;
14219        synchronized (mPidsSelfLocked) {
14220            int worstType = 0;
14221            for (int i=0; i<pids.length; i++) {
14222                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14223                if (proc != null) {
14224                    int type = proc.setAdj;
14225                    if (type > worstType) {
14226                        worstType = type;
14227                    }
14228                }
14229            }
14230
14231            // If the worst oom_adj is somewhere in the cached proc LRU range,
14232            // then constrain it so we will kill all cached procs.
14233            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14234                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14235                worstType = ProcessList.CACHED_APP_MIN_ADJ;
14236            }
14237
14238            // If this is not a secure call, don't let it kill processes that
14239            // are important.
14240            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14241                worstType = ProcessList.SERVICE_ADJ;
14242            }
14243
14244            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14245            for (int i=0; i<pids.length; i++) {
14246                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14247                if (proc == null) {
14248                    continue;
14249                }
14250                int adj = proc.setAdj;
14251                if (adj >= worstType && !proc.killedByAm) {
14252                    proc.kill(reason, true);
14253                    killed = true;
14254                }
14255            }
14256        }
14257        return killed;
14258    }
14259
14260    @Override
14261    public void killUid(int appId, int userId, String reason) {
14262        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14263        synchronized (this) {
14264            final long identity = Binder.clearCallingIdentity();
14265            try {
14266                killPackageProcessesLocked(null, appId, userId,
14267                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14268                        reason != null ? reason : "kill uid");
14269            } finally {
14270                Binder.restoreCallingIdentity(identity);
14271            }
14272        }
14273    }
14274
14275    @Override
14276    public boolean killProcessesBelowForeground(String reason) {
14277        if (Binder.getCallingUid() != SYSTEM_UID) {
14278            throw new SecurityException("killProcessesBelowForeground() only available to system");
14279        }
14280
14281        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14282    }
14283
14284    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14285        if (Binder.getCallingUid() != SYSTEM_UID) {
14286            throw new SecurityException("killProcessesBelowAdj() only available to system");
14287        }
14288
14289        boolean killed = false;
14290        synchronized (mPidsSelfLocked) {
14291            final int size = mPidsSelfLocked.size();
14292            for (int i = 0; i < size; i++) {
14293                final int pid = mPidsSelfLocked.keyAt(i);
14294                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14295                if (proc == null) continue;
14296
14297                final int adj = proc.setAdj;
14298                if (adj > belowAdj && !proc.killedByAm) {
14299                    proc.kill(reason, true);
14300                    killed = true;
14301                }
14302            }
14303        }
14304        return killed;
14305    }
14306
14307    @Override
14308    public void hang(final IBinder who, boolean allowRestart) {
14309        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14310                != PackageManager.PERMISSION_GRANTED) {
14311            throw new SecurityException("Requires permission "
14312                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14313        }
14314
14315        final IBinder.DeathRecipient death = new DeathRecipient() {
14316            @Override
14317            public void binderDied() {
14318                synchronized (this) {
14319                    notifyAll();
14320                }
14321            }
14322        };
14323
14324        try {
14325            who.linkToDeath(death, 0);
14326        } catch (RemoteException e) {
14327            Slog.w(TAG, "hang: given caller IBinder is already dead.");
14328            return;
14329        }
14330
14331        synchronized (this) {
14332            Watchdog.getInstance().setAllowRestart(allowRestart);
14333            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14334            synchronized (death) {
14335                while (who.isBinderAlive()) {
14336                    try {
14337                        death.wait();
14338                    } catch (InterruptedException e) {
14339                    }
14340                }
14341            }
14342            Watchdog.getInstance().setAllowRestart(true);
14343        }
14344    }
14345
14346    @Override
14347    public void restart() {
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        Log.i(TAG, "Sending shutdown broadcast...");
14355
14356        BroadcastReceiver br = new BroadcastReceiver() {
14357            @Override public void onReceive(Context context, Intent intent) {
14358                // Now the broadcast is done, finish up the low-level shutdown.
14359                Log.i(TAG, "Shutting down activity manager...");
14360                shutdown(10000);
14361                Log.i(TAG, "Shutdown complete, restarting!");
14362                killProcess(myPid());
14363                System.exit(10);
14364            }
14365        };
14366
14367        // First send the high-level shut down broadcast.
14368        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14369        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14370        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
14371        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
14372        mContext.sendOrderedBroadcastAsUser(intent,
14373                UserHandle.ALL, null, br, mHandler, 0, null, null);
14374        */
14375        br.onReceive(mContext, intent);
14376    }
14377
14378    private long getLowRamTimeSinceIdle(long now) {
14379        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
14380    }
14381
14382    @Override
14383    public void performIdleMaintenance() {
14384        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14385                != PackageManager.PERMISSION_GRANTED) {
14386            throw new SecurityException("Requires permission "
14387                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14388        }
14389
14390        synchronized (this) {
14391            final long now = SystemClock.uptimeMillis();
14392            final long timeSinceLastIdle = now - mLastIdleTime;
14393            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
14394            mLastIdleTime = now;
14395            mLowRamTimeSinceLastIdle = 0;
14396            if (mLowRamStartTime != 0) {
14397                mLowRamStartTime = now;
14398            }
14399
14400            StringBuilder sb = new StringBuilder(128);
14401            sb.append("Idle maintenance over ");
14402            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14403            sb.append(" low RAM for ");
14404            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14405            Slog.i(TAG, sb.toString());
14406
14407            // If at least 1/3 of our time since the last idle period has been spent
14408            // with RAM low, then we want to kill processes.
14409            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14410
14411            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14412                ProcessRecord proc = mLruProcesses.get(i);
14413                if (proc.notCachedSinceIdle) {
14414                    if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
14415                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14416                        if (doKilling && proc.initialIdlePss != 0
14417                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14418                            sb = new StringBuilder(128);
14419                            sb.append("Kill");
14420                            sb.append(proc.processName);
14421                            sb.append(" in idle maint: pss=");
14422                            sb.append(proc.lastPss);
14423                            sb.append(", swapPss=");
14424                            sb.append(proc.lastSwapPss);
14425                            sb.append(", initialPss=");
14426                            sb.append(proc.initialIdlePss);
14427                            sb.append(", period=");
14428                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14429                            sb.append(", lowRamPeriod=");
14430                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14431                            Slog.wtfQuiet(TAG, sb.toString());
14432                            proc.kill("idle maint (pss " + proc.lastPss
14433                                    + " from " + proc.initialIdlePss + ")", true);
14434                        }
14435                    }
14436                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14437                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14438                    proc.notCachedSinceIdle = true;
14439                    proc.initialIdlePss = 0;
14440                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
14441                            mTestPssMode, isSleepingLocked(), now);
14442                }
14443            }
14444
14445            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14446            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14447        }
14448    }
14449
14450    @Override
14451    public void sendIdleJobTrigger() {
14452        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14453                != PackageManager.PERMISSION_GRANTED) {
14454            throw new SecurityException("Requires permission "
14455                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14456        }
14457
14458        final long ident = Binder.clearCallingIdentity();
14459        try {
14460            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14461                    .setPackage("android")
14462                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14463            broadcastIntent(null, intent, null, null, 0, null, null, null,
14464                    OP_NONE, null, true, false, UserHandle.USER_ALL);
14465        } finally {
14466            Binder.restoreCallingIdentity(ident);
14467        }
14468    }
14469
14470    private void retrieveSettings() {
14471        final ContentResolver resolver = mContext.getContentResolver();
14472        final boolean freeformWindowManagement =
14473                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14474                        || Settings.Global.getInt(
14475                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14476
14477        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14478        final boolean supportsPictureInPicture = supportsMultiWindow &&
14479                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14480        final boolean supportsSplitScreenMultiWindow =
14481                ActivityManager.supportsSplitScreenMultiWindow(mContext);
14482        final boolean supportsMultiDisplay = mContext.getPackageManager()
14483                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14484        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14485        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14486        final boolean alwaysFinishActivities =
14487                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14488        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14489        final boolean forceResizable = Settings.Global.getInt(
14490                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14491        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14492                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14493        final boolean supportsLeanbackOnly =
14494                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14495
14496        // Transfer any global setting for forcing RTL layout, into a System Property
14497        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14498
14499        final Configuration configuration = new Configuration();
14500        Settings.System.getConfiguration(resolver, configuration);
14501        if (forceRtl) {
14502            // This will take care of setting the correct layout direction flags
14503            configuration.setLayoutDirection(configuration.locale);
14504        }
14505
14506        synchronized (this) {
14507            mDebugApp = mOrigDebugApp = debugApp;
14508            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14509            mAlwaysFinishActivities = alwaysFinishActivities;
14510            mSupportsLeanbackOnly = supportsLeanbackOnly;
14511            mForceResizableActivities = forceResizable;
14512            final boolean multiWindowFormEnabled = freeformWindowManagement
14513                    || supportsSplitScreenMultiWindow
14514                    || supportsPictureInPicture
14515                    || supportsMultiDisplay;
14516            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14517                mSupportsMultiWindow = true;
14518                mSupportsFreeformWindowManagement = freeformWindowManagement;
14519                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14520                mSupportsPictureInPicture = supportsPictureInPicture;
14521                mSupportsMultiDisplay = supportsMultiDisplay;
14522            } else {
14523                mSupportsMultiWindow = false;
14524                mSupportsFreeformWindowManagement = false;
14525                mSupportsSplitScreenMultiWindow = false;
14526                mSupportsPictureInPicture = false;
14527                mSupportsMultiDisplay = false;
14528            }
14529            mWindowManager.setForceResizableTasks(mForceResizableActivities);
14530            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14531            // This happens before any activities are started, so we can change global configuration
14532            // in-place.
14533            updateConfigurationLocked(configuration, null, true);
14534            final Configuration globalConfig = getGlobalConfiguration();
14535            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14536
14537            // Load resources only after the current configuration has been set.
14538            final Resources res = mContext.getResources();
14539            mThumbnailWidth = res.getDimensionPixelSize(
14540                    com.android.internal.R.dimen.thumbnail_width);
14541            mThumbnailHeight = res.getDimensionPixelSize(
14542                    com.android.internal.R.dimen.thumbnail_height);
14543            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14544                    com.android.internal.R.string.config_appsNotReportingCrashes));
14545            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14546                    com.android.internal.R.bool.config_customUserSwitchUi);
14547            mUserController.mMaxRunningUsers = res.getInteger(
14548                    com.android.internal.R.integer.config_multiuserMaxRunningUsers);
14549
14550            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14551                mFullscreenThumbnailScale = (float) res
14552                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14553                    (float) globalConfig.screenWidthDp;
14554            } else {
14555                mFullscreenThumbnailScale = res.getFraction(
14556                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14557            }
14558            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14559        }
14560    }
14561
14562    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14563        traceLog.traceBegin("PhaseActivityManagerReady");
14564        synchronized(this) {
14565            if (mSystemReady) {
14566                // If we're done calling all the receivers, run the next "boot phase" passed in
14567                // by the SystemServer
14568                if (goingCallback != null) {
14569                    goingCallback.run();
14570                }
14571                return;
14572            }
14573
14574            mLocalDeviceIdleController
14575                    = LocalServices.getService(DeviceIdleController.LocalService.class);
14576            mAssistUtils = new AssistUtils(mContext);
14577            mVrController.onSystemReady();
14578            // Make sure we have the current profile info, since it is needed for security checks.
14579            mUserController.onSystemReady();
14580            mRecentTasks.onSystemReadyLocked();
14581            mAppOpsService.systemReady();
14582            mSystemReady = true;
14583        }
14584
14585        try {
14586            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14587                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14588                    .getSerial();
14589        } catch (RemoteException e) {}
14590
14591        ArrayList<ProcessRecord> procsToKill = null;
14592        synchronized(mPidsSelfLocked) {
14593            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14594                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14595                if (!isAllowedWhileBooting(proc.info)){
14596                    if (procsToKill == null) {
14597                        procsToKill = new ArrayList<ProcessRecord>();
14598                    }
14599                    procsToKill.add(proc);
14600                }
14601            }
14602        }
14603
14604        synchronized(this) {
14605            if (procsToKill != null) {
14606                for (int i=procsToKill.size()-1; i>=0; i--) {
14607                    ProcessRecord proc = procsToKill.get(i);
14608                    Slog.i(TAG, "Removing system update proc: " + proc);
14609                    removeProcessLocked(proc, true, false, "system update done");
14610                }
14611            }
14612
14613            // Now that we have cleaned up any update processes, we
14614            // are ready to start launching real processes and know that
14615            // we won't trample on them any more.
14616            mProcessesReady = true;
14617        }
14618
14619        Slog.i(TAG, "System now ready");
14620        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14621            SystemClock.uptimeMillis());
14622
14623        synchronized(this) {
14624            // Make sure we have no pre-ready processes sitting around.
14625
14626            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14627                ResolveInfo ri = mContext.getPackageManager()
14628                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14629                                STOCK_PM_FLAGS);
14630                CharSequence errorMsg = null;
14631                if (ri != null) {
14632                    ActivityInfo ai = ri.activityInfo;
14633                    ApplicationInfo app = ai.applicationInfo;
14634                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14635                        mTopAction = Intent.ACTION_FACTORY_TEST;
14636                        mTopData = null;
14637                        mTopComponent = new ComponentName(app.packageName,
14638                                ai.name);
14639                    } else {
14640                        errorMsg = mContext.getResources().getText(
14641                                com.android.internal.R.string.factorytest_not_system);
14642                    }
14643                } else {
14644                    errorMsg = mContext.getResources().getText(
14645                            com.android.internal.R.string.factorytest_no_action);
14646                }
14647                if (errorMsg != null) {
14648                    mTopAction = null;
14649                    mTopData = null;
14650                    mTopComponent = null;
14651                    Message msg = Message.obtain();
14652                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14653                    msg.getData().putCharSequence("msg", errorMsg);
14654                    mUiHandler.sendMessage(msg);
14655                }
14656            }
14657        }
14658
14659        retrieveSettings();
14660        final int currentUserId = mUserController.getCurrentUserId();
14661        synchronized (this) {
14662            readGrantedUriPermissionsLocked();
14663        }
14664
14665        final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
14666        if (pmi != null) {
14667            pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
14668                    state -> updateForceBackgroundCheck(state.batterySaverEnabled));
14669            updateForceBackgroundCheck(
14670                    pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
14671        } else {
14672            Slog.wtf(TAG, "PowerManagerInternal not found.");
14673        }
14674
14675        if (goingCallback != null) goingCallback.run();
14676        traceLog.traceBegin("ActivityManagerStartApps");
14677        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14678                Integer.toString(currentUserId), currentUserId);
14679        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14680                Integer.toString(currentUserId), currentUserId);
14681        mSystemServiceManager.startUser(currentUserId);
14682
14683        synchronized (this) {
14684            // Only start up encryption-aware persistent apps; once user is
14685            // unlocked we'll come back around and start unaware apps
14686            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14687
14688            // Start up initial activity.
14689            mBooting = true;
14690            // Enable home activity for system user, so that the system can always boot. We don't
14691            // do this when the system user is not setup since the setup wizard should be the one
14692            // to handle home activity in this case.
14693            if (UserManager.isSplitSystemUser() &&
14694                    Settings.Secure.getInt(mContext.getContentResolver(),
14695                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14696                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14697                try {
14698                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14699                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14700                            UserHandle.USER_SYSTEM);
14701                } catch (RemoteException e) {
14702                    throw e.rethrowAsRuntimeException();
14703                }
14704            }
14705            startHomeActivityLocked(currentUserId, "systemReady");
14706
14707            try {
14708                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14709                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14710                            + " data partition or your device will be unstable.");
14711                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14712                }
14713            } catch (RemoteException e) {
14714            }
14715
14716            if (!Build.isBuildConsistent()) {
14717                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14718                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14719            }
14720
14721            long ident = Binder.clearCallingIdentity();
14722            try {
14723                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14724                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14725                        | Intent.FLAG_RECEIVER_FOREGROUND);
14726                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14727                broadcastIntentLocked(null, null, intent,
14728                        null, null, 0, null, null, null, OP_NONE,
14729                        null, false, false, MY_PID, SYSTEM_UID,
14730                        currentUserId);
14731                intent = new Intent(Intent.ACTION_USER_STARTING);
14732                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14733                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14734                broadcastIntentLocked(null, null, intent,
14735                        null, new IIntentReceiver.Stub() {
14736                            @Override
14737                            public void performReceive(Intent intent, int resultCode, String data,
14738                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14739                                    throws RemoteException {
14740                            }
14741                        }, 0, null, null,
14742                        new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
14743                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14744            } catch (Throwable t) {
14745                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14746            } finally {
14747                Binder.restoreCallingIdentity(ident);
14748            }
14749            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14750            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
14751
14752            BinderInternal.nSetBinderProxyCountEnabled(true);
14753            //STOPSHIP: Temporary BinderProxy Threshold for b/71353150
14754            BinderInternal.nSetBinderProxyCountWatermarks(1500, 1200);
14755            BinderInternal.setBinderProxyCountCallback(
14756                    new BinderInternal.BinderProxyLimitListener() {
14757                        @Override
14758                        public void onLimitReached(int uid) {
14759                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
14760                                    + Process.myUid());
14761                            if (uid == Process.SYSTEM_UID) {
14762                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
14763                            } else {
14764                                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
14765                                        "Too many Binders sent to SYSTEM");
14766                            }
14767                        }
14768                    }, mHandler);
14769
14770            traceLog.traceEnd(); // ActivityManagerStartApps
14771            traceLog.traceEnd(); // PhaseActivityManagerReady
14772        }
14773    }
14774
14775    private void updateForceBackgroundCheck(boolean enabled) {
14776        synchronized (this) {
14777            if (mForceBackgroundCheck != enabled) {
14778                mForceBackgroundCheck = enabled;
14779
14780                if (DEBUG_BACKGROUND_CHECK) {
14781                    Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
14782                }
14783
14784                if (mForceBackgroundCheck) {
14785                    // Stop background services for idle UIDs.
14786                    doStopUidForIdleUidsLocked();
14787                }
14788            }
14789        }
14790    }
14791
14792    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14793        synchronized (this) {
14794            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14795        }
14796    }
14797
14798    void skipCurrentReceiverLocked(ProcessRecord app) {
14799        for (BroadcastQueue queue : mBroadcastQueues) {
14800            queue.skipCurrentReceiverLocked(app);
14801        }
14802    }
14803
14804    /**
14805     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14806     * The application process will exit immediately after this call returns.
14807     * @param app object of the crashing app, null for the system server
14808     * @param crashInfo describing the exception
14809     */
14810    public void handleApplicationCrash(IBinder app,
14811            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14812        ProcessRecord r = findAppProcess(app, "Crash");
14813        final String processName = app == null ? "system_server"
14814                : (r == null ? "unknown" : r.processName);
14815
14816        handleApplicationCrashInner("crash", r, processName, crashInfo);
14817    }
14818
14819    /* Native crash reporting uses this inner version because it needs to be somewhat
14820     * decoupled from the AM-managed cleanup lifecycle
14821     */
14822    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14823            ApplicationErrorReport.CrashInfo crashInfo) {
14824        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14825                UserHandle.getUserId(Binder.getCallingUid()), processName,
14826                r == null ? -1 : r.info.flags,
14827                crashInfo.exceptionClassName,
14828                crashInfo.exceptionMessage,
14829                crashInfo.throwFileName,
14830                crashInfo.throwLineNumber);
14831
14832        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14833
14834        mAppErrors.crashApplication(r, crashInfo);
14835    }
14836
14837    public void handleApplicationStrictModeViolation(
14838            IBinder app,
14839            int violationMask,
14840            StrictMode.ViolationInfo info) {
14841        // We're okay if the ProcessRecord is missing; it probably means that
14842        // we're reporting a violation from the system process itself.
14843        final ProcessRecord r = findAppProcess(app, "StrictMode");
14844
14845        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14846            Integer stackFingerprint = info.hashCode();
14847            boolean logIt = true;
14848            synchronized (mAlreadyLoggedViolatedStacks) {
14849                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14850                    logIt = false;
14851                    // TODO: sub-sample into EventLog for these, with
14852                    // the info.durationMillis?  Then we'd get
14853                    // the relative pain numbers, without logging all
14854                    // the stack traces repeatedly.  We'd want to do
14855                    // likewise in the client code, which also does
14856                    // dup suppression, before the Binder call.
14857                } else {
14858                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14859                        mAlreadyLoggedViolatedStacks.clear();
14860                    }
14861                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14862                }
14863            }
14864            if (logIt) {
14865                logStrictModeViolationToDropBox(r, info);
14866            }
14867        }
14868
14869        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14870            AppErrorResult result = new AppErrorResult();
14871            synchronized (this) {
14872                final long origId = Binder.clearCallingIdentity();
14873
14874                Message msg = Message.obtain();
14875                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14876                HashMap<String, Object> data = new HashMap<String, Object>();
14877                data.put("result", result);
14878                data.put("app", r);
14879                data.put("violationMask", violationMask);
14880                data.put("info", info);
14881                msg.obj = data;
14882                mUiHandler.sendMessage(msg);
14883
14884                Binder.restoreCallingIdentity(origId);
14885            }
14886            int res = result.get();
14887            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14888        }
14889    }
14890
14891    // Depending on the policy in effect, there could be a bunch of
14892    // these in quick succession so we try to batch these together to
14893    // minimize disk writes, number of dropbox entries, and maximize
14894    // compression, by having more fewer, larger records.
14895    private void logStrictModeViolationToDropBox(
14896            ProcessRecord process,
14897            StrictMode.ViolationInfo info) {
14898        if (info == null) {
14899            return;
14900        }
14901        final boolean isSystemApp = process == null ||
14902                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14903                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14904        final String processName = process == null ? "unknown" : process.processName;
14905        final DropBoxManager dbox = (DropBoxManager)
14906                mContext.getSystemService(Context.DROPBOX_SERVICE);
14907
14908        // Exit early if the dropbox isn't configured to accept this report type.
14909        final String dropboxTag = processClass(process) + "_strictmode";
14910        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14911
14912        final StringBuilder sb = new StringBuilder(1024);
14913        synchronized (sb) {
14914            appendDropBoxProcessHeaders(process, processName, sb);
14915            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14916            sb.append("System-App: ").append(isSystemApp).append("\n");
14917            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14918            if (info.violationNumThisLoop != 0) {
14919                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14920            }
14921            if (info.numAnimationsRunning != 0) {
14922                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14923            }
14924            if (info.broadcastIntentAction != null) {
14925                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14926            }
14927            if (info.durationMillis != -1) {
14928                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14929            }
14930            if (info.numInstances != -1) {
14931                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14932            }
14933            if (info.tags != null) {
14934                for (String tag : info.tags) {
14935                    sb.append("Span-Tag: ").append(tag).append("\n");
14936                }
14937            }
14938            sb.append("\n");
14939            sb.append(info.getStackTrace());
14940            sb.append("\n");
14941            if (info.getViolationDetails() != null) {
14942                sb.append(info.getViolationDetails());
14943                sb.append("\n");
14944            }
14945        }
14946
14947        final String res = sb.toString();
14948        IoThread.getHandler().post(() -> {
14949            dbox.addText(dropboxTag, res);
14950        });
14951    }
14952
14953    /**
14954     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14955     * @param app object of the crashing app, null for the system server
14956     * @param tag reported by the caller
14957     * @param system whether this wtf is coming from the system
14958     * @param crashInfo describing the context of the error
14959     * @return true if the process should exit immediately (WTF is fatal)
14960     */
14961    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14962            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14963        final int callingUid = Binder.getCallingUid();
14964        final int callingPid = Binder.getCallingPid();
14965
14966        if (system) {
14967            // If this is coming from the system, we could very well have low-level
14968            // system locks held, so we want to do this all asynchronously.  And we
14969            // never want this to become fatal, so there is that too.
14970            mHandler.post(new Runnable() {
14971                @Override public void run() {
14972                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14973                }
14974            });
14975            return false;
14976        }
14977
14978        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14979                crashInfo);
14980
14981        final boolean isFatal = Build.IS_ENG || Settings.Global
14982                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14983        final boolean isSystem = (r == null) || r.persistent;
14984
14985        if (isFatal && !isSystem) {
14986            mAppErrors.crashApplication(r, crashInfo);
14987            return true;
14988        } else {
14989            return false;
14990        }
14991    }
14992
14993    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14994            final ApplicationErrorReport.CrashInfo crashInfo) {
14995        final ProcessRecord r = findAppProcess(app, "WTF");
14996        final String processName = app == null ? "system_server"
14997                : (r == null ? "unknown" : r.processName);
14998
14999        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
15000                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
15001
15002        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
15003
15004        return r;
15005    }
15006
15007    /**
15008     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
15009     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
15010     */
15011    private ProcessRecord findAppProcess(IBinder app, String reason) {
15012        if (app == null) {
15013            return null;
15014        }
15015
15016        synchronized (this) {
15017            final int NP = mProcessNames.getMap().size();
15018            for (int ip=0; ip<NP; ip++) {
15019                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
15020                final int NA = apps.size();
15021                for (int ia=0; ia<NA; ia++) {
15022                    ProcessRecord p = apps.valueAt(ia);
15023                    if (p.thread != null && p.thread.asBinder() == app) {
15024                        return p;
15025                    }
15026                }
15027            }
15028
15029            Slog.w(TAG, "Can't find mystery application for " + reason
15030                    + " from pid=" + Binder.getCallingPid()
15031                    + " uid=" + Binder.getCallingUid() + ": " + app);
15032            return null;
15033        }
15034    }
15035
15036    /**
15037     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
15038     * to append various headers to the dropbox log text.
15039     */
15040    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
15041            StringBuilder sb) {
15042        // Watchdog thread ends up invoking this function (with
15043        // a null ProcessRecord) to add the stack file to dropbox.
15044        // Do not acquire a lock on this (am) in such cases, as it
15045        // could cause a potential deadlock, if and when watchdog
15046        // is invoked due to unavailability of lock on am and it
15047        // would prevent watchdog from killing system_server.
15048        if (process == null) {
15049            sb.append("Process: ").append(processName).append("\n");
15050            return;
15051        }
15052        // Note: ProcessRecord 'process' is guarded by the service
15053        // instance.  (notably process.pkgList, which could otherwise change
15054        // concurrently during execution of this method)
15055        synchronized (this) {
15056            sb.append("Process: ").append(processName).append("\n");
15057            sb.append("PID: ").append(process.pid).append("\n");
15058            int flags = process.info.flags;
15059            IPackageManager pm = AppGlobals.getPackageManager();
15060            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
15061            for (int ip=0; ip<process.pkgList.size(); ip++) {
15062                String pkg = process.pkgList.keyAt(ip);
15063                sb.append("Package: ").append(pkg);
15064                try {
15065                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
15066                    if (pi != null) {
15067                        sb.append(" v").append(pi.getLongVersionCode());
15068                        if (pi.versionName != null) {
15069                            sb.append(" (").append(pi.versionName).append(")");
15070                        }
15071                    }
15072                } catch (RemoteException e) {
15073                    Slog.e(TAG, "Error getting package info: " + pkg, e);
15074                }
15075                sb.append("\n");
15076            }
15077            if (process.info.isInstantApp()) {
15078                sb.append("Instant-App: true\n");
15079            }
15080        }
15081    }
15082
15083    private static String processClass(ProcessRecord process) {
15084        if (process == null || process.pid == MY_PID) {
15085            return "system_server";
15086        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15087            return "system_app";
15088        } else {
15089            return "data_app";
15090        }
15091    }
15092
15093    private volatile long mWtfClusterStart;
15094    private volatile int mWtfClusterCount;
15095
15096    /**
15097     * Write a description of an error (crash, WTF, ANR) to the drop box.
15098     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
15099     * @param process which caused the error, null means the system server
15100     * @param activity which triggered the error, null if unknown
15101     * @param parent activity related to the error, null if unknown
15102     * @param subject line related to the error, null if absent
15103     * @param report in long form describing the error, null if absent
15104     * @param dataFile text file to include in the report, null if none
15105     * @param crashInfo giving an application stack trace, null if absent
15106     */
15107    public void addErrorToDropBox(String eventType,
15108            ProcessRecord process, String processName, ActivityRecord activity,
15109            ActivityRecord parent, String subject,
15110            final String report, final File dataFile,
15111            final ApplicationErrorReport.CrashInfo crashInfo) {
15112        // NOTE -- this must never acquire the ActivityManagerService lock,
15113        // otherwise the watchdog may be prevented from resetting the system.
15114
15115        // Bail early if not published yet
15116        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
15117        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
15118
15119        // Exit early if the dropbox isn't configured to accept this report type.
15120        final String dropboxTag = processClass(process) + "_" + eventType;
15121        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15122
15123        // Log to StatsLog before the rate-limiting.
15124        // The logging below is adapated from appendDropboxProcessHeaders.
15125        StatsLog.write(StatsLog.DROPBOX_ERROR_CHANGED,
15126                process != null ? process.uid : -1,
15127                dropboxTag,
15128                processName,
15129                process != null ? process.pid : -1,
15130                (process != null && process.info != null) ?
15131                        (process.info.isInstantApp() ? 1 : 0) : -1,
15132                activity != null ? activity.shortComponentName : null,
15133                activity != null ? activity.packageName : null,
15134                process != null ? (process.isInterestingToUserLocked() ? 1 : 0) : -1);
15135
15136        // Rate-limit how often we're willing to do the heavy lifting below to
15137        // collect and record logs; currently 5 logs per 10 second period.
15138        final long now = SystemClock.elapsedRealtime();
15139        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
15140            mWtfClusterStart = now;
15141            mWtfClusterCount = 1;
15142        } else {
15143            if (mWtfClusterCount++ >= 5) return;
15144        }
15145
15146        final StringBuilder sb = new StringBuilder(1024);
15147        appendDropBoxProcessHeaders(process, processName, sb);
15148        if (process != null) {
15149            sb.append("Foreground: ")
15150                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
15151                    .append("\n");
15152        }
15153        if (activity != null) {
15154            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15155        }
15156        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15157            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15158        }
15159        if (parent != null && parent != activity) {
15160            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15161        }
15162        if (subject != null) {
15163            sb.append("Subject: ").append(subject).append("\n");
15164        }
15165        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15166        if (Debug.isDebuggerConnected()) {
15167            sb.append("Debugger: Connected\n");
15168        }
15169        sb.append("\n");
15170
15171        // Do the rest in a worker thread to avoid blocking the caller on I/O
15172        // (After this point, we shouldn't access AMS internal data structures.)
15173        Thread worker = new Thread("Error dump: " + dropboxTag) {
15174            @Override
15175            public void run() {
15176                if (report != null) {
15177                    sb.append(report);
15178                }
15179
15180                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
15181                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
15182                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
15183                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
15184
15185                if (dataFile != null && maxDataFileSize > 0) {
15186                    try {
15187                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15188                                    "\n\n[[TRUNCATED]]"));
15189                    } catch (IOException e) {
15190                        Slog.e(TAG, "Error reading " + dataFile, e);
15191                    }
15192                }
15193                if (crashInfo != null && crashInfo.stackTrace != null) {
15194                    sb.append(crashInfo.stackTrace);
15195                }
15196
15197                if (lines > 0) {
15198                    sb.append("\n");
15199
15200                    // Merge several logcat streams, and take the last N lines
15201                    InputStreamReader input = null;
15202                    try {
15203                        java.lang.Process logcat = new ProcessBuilder(
15204                                "/system/bin/timeout", "-k", "15s", "10s",
15205                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
15206                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
15207                                        .redirectErrorStream(true).start();
15208
15209                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
15210                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
15211                        input = new InputStreamReader(logcat.getInputStream());
15212
15213                        int num;
15214                        char[] buf = new char[8192];
15215                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
15216                    } catch (IOException e) {
15217                        Slog.e(TAG, "Error running logcat", e);
15218                    } finally {
15219                        if (input != null) try { input.close(); } catch (IOException e) {}
15220                    }
15221                }
15222
15223                dbox.addText(dropboxTag, sb.toString());
15224            }
15225        };
15226
15227        if (process == null) {
15228            // If process is null, we are being called from some internal code
15229            // and may be about to die -- run this synchronously.
15230            final int oldMask = StrictMode.allowThreadDiskWritesMask();
15231            try {
15232                worker.run();
15233            } finally {
15234                StrictMode.setThreadPolicyMask(oldMask);
15235            }
15236        } else {
15237            worker.start();
15238        }
15239    }
15240
15241    @Override
15242    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15243        enforceNotIsolatedCaller("getProcessesInErrorState");
15244        // assume our apps are happy - lazy create the list
15245        List<ActivityManager.ProcessErrorStateInfo> errList = null;
15246
15247        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15248                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15249        int userId = UserHandle.getUserId(Binder.getCallingUid());
15250
15251        synchronized (this) {
15252
15253            // iterate across all processes
15254            for (int i=mLruProcesses.size()-1; i>=0; i--) {
15255                ProcessRecord app = mLruProcesses.get(i);
15256                if (!allUsers && app.userId != userId) {
15257                    continue;
15258                }
15259                if ((app.thread != null) && (app.crashing || app.notResponding)) {
15260                    // This one's in trouble, so we'll generate a report for it
15261                    // crashes are higher priority (in case there's a crash *and* an anr)
15262                    ActivityManager.ProcessErrorStateInfo report = null;
15263                    if (app.crashing) {
15264                        report = app.crashingReport;
15265                    } else if (app.notResponding) {
15266                        report = app.notRespondingReport;
15267                    }
15268
15269                    if (report != null) {
15270                        if (errList == null) {
15271                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15272                        }
15273                        errList.add(report);
15274                    } else {
15275                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
15276                                " crashing = " + app.crashing +
15277                                " notResponding = " + app.notResponding);
15278                    }
15279                }
15280            }
15281        }
15282
15283        return errList;
15284    }
15285
15286    static int procStateToImportance(int procState, int memAdj,
15287            ActivityManager.RunningAppProcessInfo currApp,
15288            int clientTargetSdk) {
15289        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15290                procState, clientTargetSdk);
15291        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15292            currApp.lru = memAdj;
15293        } else {
15294            currApp.lru = 0;
15295        }
15296        return imp;
15297    }
15298
15299    private void fillInProcMemInfo(ProcessRecord app,
15300            ActivityManager.RunningAppProcessInfo outInfo,
15301            int clientTargetSdk) {
15302        outInfo.pid = app.pid;
15303        outInfo.uid = app.info.uid;
15304        if (mHeavyWeightProcess == app) {
15305            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15306        }
15307        if (app.persistent) {
15308            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15309        }
15310        if (app.activities.size() > 0) {
15311            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15312        }
15313        outInfo.lastTrimLevel = app.trimMemoryLevel;
15314        int adj = app.curAdj;
15315        int procState = app.curProcState;
15316        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15317        outInfo.importanceReasonCode = app.adjTypeCode;
15318        outInfo.processState = app.curProcState;
15319    }
15320
15321    @Override
15322    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15323        enforceNotIsolatedCaller("getRunningAppProcesses");
15324
15325        final int callingUid = Binder.getCallingUid();
15326        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15327
15328        // Lazy instantiation of list
15329        List<ActivityManager.RunningAppProcessInfo> runList = null;
15330        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15331                callingUid) == PackageManager.PERMISSION_GRANTED;
15332        final int userId = UserHandle.getUserId(callingUid);
15333        final boolean allUids = isGetTasksAllowed(
15334                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
15335
15336        synchronized (this) {
15337            // Iterate across all processes
15338            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15339                ProcessRecord app = mLruProcesses.get(i);
15340                if ((!allUsers && app.userId != userId)
15341                        || (!allUids && app.uid != callingUid)) {
15342                    continue;
15343                }
15344                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15345                    // Generate process state info for running application
15346                    ActivityManager.RunningAppProcessInfo currApp =
15347                        new ActivityManager.RunningAppProcessInfo(app.processName,
15348                                app.pid, app.getPackageList());
15349                    fillInProcMemInfo(app, currApp, clientTargetSdk);
15350                    if (app.adjSource instanceof ProcessRecord) {
15351                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15352                        currApp.importanceReasonImportance =
15353                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
15354                                        app.adjSourceProcState);
15355                    } else if (app.adjSource instanceof ActivityRecord) {
15356                        ActivityRecord r = (ActivityRecord)app.adjSource;
15357                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15358                    }
15359                    if (app.adjTarget instanceof ComponentName) {
15360                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15361                    }
15362                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15363                    //        + " lru=" + currApp.lru);
15364                    if (runList == null) {
15365                        runList = new ArrayList<>();
15366                    }
15367                    runList.add(currApp);
15368                }
15369            }
15370        }
15371        return runList;
15372    }
15373
15374    @Override
15375    public List<ApplicationInfo> getRunningExternalApplications() {
15376        enforceNotIsolatedCaller("getRunningExternalApplications");
15377        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
15378        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
15379        if (runningApps != null && runningApps.size() > 0) {
15380            Set<String> extList = new HashSet<String>();
15381            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
15382                if (app.pkgList != null) {
15383                    for (String pkg : app.pkgList) {
15384                        extList.add(pkg);
15385                    }
15386                }
15387            }
15388            IPackageManager pm = AppGlobals.getPackageManager();
15389            for (String pkg : extList) {
15390                try {
15391                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
15392                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
15393                        retList.add(info);
15394                    }
15395                } catch (RemoteException e) {
15396                }
15397            }
15398        }
15399        return retList;
15400    }
15401
15402    @Override
15403    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15404        enforceNotIsolatedCaller("getMyMemoryState");
15405
15406        final int callingUid = Binder.getCallingUid();
15407        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15408
15409        synchronized (this) {
15410            ProcessRecord proc;
15411            synchronized (mPidsSelfLocked) {
15412                proc = mPidsSelfLocked.get(Binder.getCallingPid());
15413            }
15414            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15415        }
15416    }
15417
15418    @Override
15419    public int getMemoryTrimLevel() {
15420        enforceNotIsolatedCaller("getMyMemoryState");
15421        synchronized (this) {
15422            return mLastMemoryLevel;
15423        }
15424    }
15425
15426    @Override
15427    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15428            FileDescriptor err, String[] args, ShellCallback callback,
15429            ResultReceiver resultReceiver) {
15430        (new ActivityManagerShellCommand(this, false)).exec(
15431                this, in, out, err, args, callback, resultReceiver);
15432    }
15433
15434    SleepToken acquireSleepToken(String tag, int displayId) {
15435        synchronized (this) {
15436            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15437            updateSleepIfNeededLocked();
15438            return token;
15439        }
15440    }
15441
15442    @Override
15443    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15444        PriorityDump.dump(mPriorityDumper, fd, pw, args);
15445    }
15446
15447    /**
15448     * Wrapper function to print out debug data filtered by specified arguments.
15449    */
15450    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
15451        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15452
15453        boolean dumpAll = false;
15454        boolean dumpClient = false;
15455        boolean dumpCheckin = false;
15456        boolean dumpCheckinFormat = false;
15457        boolean dumpVisibleStacksOnly = false;
15458        boolean dumpFocusedStackOnly = false;
15459        String dumpPackage = null;
15460
15461        int opti = 0;
15462        while (opti < args.length) {
15463            String opt = args[opti];
15464            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15465                break;
15466            }
15467            opti++;
15468            if ("-a".equals(opt)) {
15469                dumpAll = true;
15470            } else if ("-c".equals(opt)) {
15471                dumpClient = true;
15472            } else if ("-v".equals(opt)) {
15473                dumpVisibleStacksOnly = true;
15474            } else if ("-f".equals(opt)) {
15475                dumpFocusedStackOnly = true;
15476            } else if ("-p".equals(opt)) {
15477                if (opti < args.length) {
15478                    dumpPackage = args[opti];
15479                    opti++;
15480                } else {
15481                    pw.println("Error: -p option requires package argument");
15482                    return;
15483                }
15484                dumpClient = true;
15485            } else if ("--checkin".equals(opt)) {
15486                dumpCheckin = dumpCheckinFormat = true;
15487            } else if ("-C".equals(opt)) {
15488                dumpCheckinFormat = true;
15489            } else if ("-h".equals(opt)) {
15490                ActivityManagerShellCommand.dumpHelp(pw, true);
15491                return;
15492            } else {
15493                pw.println("Unknown argument: " + opt + "; use -h for help");
15494            }
15495        }
15496
15497        long origId = Binder.clearCallingIdentity();
15498
15499        if (useProto) {
15500            final ProtoOutputStream proto = new ProtoOutputStream(fd);
15501            String cmd = opti < args.length ? args[opti] : "";
15502            opti++;
15503
15504            if ("activities".equals(cmd) || "a".equals(cmd)) {
15505                // output proto is ActivityStackSupervisorProto
15506                synchronized (this) {
15507                    writeActivitiesToProtoLocked(proto);
15508                }
15509            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15510                // output proto is BroadcastProto
15511                synchronized (this) {
15512                    writeBroadcastsToProtoLocked(proto);
15513                }
15514            } else if ("provider".equals(cmd)) {
15515                String[] newArgs;
15516                String name;
15517                if (opti >= args.length) {
15518                    name = null;
15519                    newArgs = EMPTY_STRING_ARRAY;
15520                } else {
15521                    name = args[opti];
15522                    opti++;
15523                    newArgs = new String[args.length - opti];
15524                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15525                            args.length - opti);
15526                }
15527                if (!dumpProviderProto(fd, pw, name, newArgs)) {
15528                    pw.println("No providers match: " + name);
15529                    pw.println("Use -h for help.");
15530                }
15531            } else if ("service".equals(cmd)) {
15532                mServices.writeToProto(proto);
15533            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15534                if (opti < args.length) {
15535                    dumpPackage = args[opti];
15536                    opti++;
15537                }
15538                // output proto is ProcessProto
15539                synchronized (this) {
15540                    writeProcessesToProtoLocked(proto, dumpPackage);
15541                }
15542            } else {
15543                // default option, dump everything, output is ActivityManagerServiceProto
15544                synchronized (this) {
15545                    long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
15546                    writeActivitiesToProtoLocked(proto);
15547                    proto.end(activityToken);
15548
15549                    long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
15550                    writeBroadcastsToProtoLocked(proto);
15551                    proto.end(broadcastToken);
15552
15553                    long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
15554                    mServices.writeToProto(proto);
15555                    proto.end(serviceToken);
15556
15557                    long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
15558                    writeProcessesToProtoLocked(proto, dumpPackage);
15559                    proto.end(processToken);
15560                }
15561            }
15562            proto.flush();
15563            Binder.restoreCallingIdentity(origId);
15564            return;
15565        }
15566
15567        int dumpAppId = getAppId(dumpPackage);
15568        boolean more = false;
15569        // Is the caller requesting to dump a particular piece of data?
15570        if (opti < args.length) {
15571            String cmd = args[opti];
15572            opti++;
15573            if ("activities".equals(cmd) || "a".equals(cmd)) {
15574                synchronized (this) {
15575                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15576                }
15577            } else if ("lastanr".equals(cmd)) {
15578                synchronized (this) {
15579                    dumpLastANRLocked(pw);
15580                }
15581            } else if ("starter".equals(cmd)) {
15582                synchronized (this) {
15583                    dumpActivityStarterLocked(pw, dumpPackage);
15584                }
15585            } else if ("containers".equals(cmd)) {
15586                synchronized (this) {
15587                    dumpActivityContainersLocked(pw);
15588                }
15589            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15590                synchronized (this) {
15591                    if (mRecentTasks != null) {
15592                        mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
15593                    }
15594                }
15595            } else if ("binder-proxies".equals(cmd)) {
15596                if (opti >= args.length) {
15597                    dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
15598                            "Counts of Binder Proxies held by SYSTEM");
15599                } else {
15600                    String uid = args[opti];
15601                    opti++;
15602                    // Ensure Binder Proxy Count is as up to date as possible
15603                    System.gc();
15604                    System.runFinalization();
15605                    System.gc();
15606                    pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
15607                }
15608            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15609                if (opti < args.length) {
15610                    dumpPackage = args[opti];
15611                    opti++;
15612                }
15613                synchronized (this) {
15614                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15615                }
15616            } else if ("broadcast-stats".equals(cmd)) {
15617                if (opti < args.length) {
15618                    dumpPackage = args[opti];
15619                    opti++;
15620                }
15621                synchronized (this) {
15622                    if (dumpCheckinFormat) {
15623                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15624                                dumpPackage);
15625                    } else {
15626                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15627                    }
15628                }
15629            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15630                if (opti < args.length) {
15631                    dumpPackage = args[opti];
15632                    opti++;
15633                }
15634                synchronized (this) {
15635                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15636                }
15637            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15638                if (opti < args.length) {
15639                    dumpPackage = args[opti];
15640                    opti++;
15641                }
15642                synchronized (this) {
15643                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
15644                }
15645            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15646                synchronized (this) {
15647                    dumpOomLocked(fd, pw, args, opti, true);
15648                }
15649            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15650                synchronized (this) {
15651                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15652                }
15653            } else if ("provider".equals(cmd)) {
15654                String[] newArgs;
15655                String name;
15656                if (opti >= args.length) {
15657                    name = null;
15658                    newArgs = EMPTY_STRING_ARRAY;
15659                } else {
15660                    name = args[opti];
15661                    opti++;
15662                    newArgs = new String[args.length - opti];
15663                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15664                }
15665                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15666                    pw.println("No providers match: " + name);
15667                    pw.println("Use -h for help.");
15668                }
15669            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15670                synchronized (this) {
15671                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15672                }
15673            } else if ("service".equals(cmd)) {
15674                String[] newArgs;
15675                String name;
15676                if (opti >= args.length) {
15677                    name = null;
15678                    newArgs = EMPTY_STRING_ARRAY;
15679                } else {
15680                    name = args[opti];
15681                    opti++;
15682                    newArgs = new String[args.length - opti];
15683                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15684                            args.length - opti);
15685                }
15686                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15687                    pw.println("No services match: " + name);
15688                    pw.println("Use -h for help.");
15689                }
15690            } else if ("package".equals(cmd)) {
15691                String[] newArgs;
15692                if (opti >= args.length) {
15693                    pw.println("package: no package name specified");
15694                    pw.println("Use -h for help.");
15695                } else {
15696                    dumpPackage = args[opti];
15697                    opti++;
15698                    newArgs = new String[args.length - opti];
15699                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15700                            args.length - opti);
15701                    args = newArgs;
15702                    opti = 0;
15703                    more = true;
15704                }
15705            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15706                synchronized (this) {
15707                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15708                }
15709            } else if ("settings".equals(cmd)) {
15710                synchronized (this) {
15711                    mConstants.dump(pw);
15712                }
15713            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15714                if (dumpClient) {
15715                    ActiveServices.ServiceDumper dumper;
15716                    synchronized (this) {
15717                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15718                                dumpPackage);
15719                    }
15720                    dumper.dumpWithClient();
15721                } else {
15722                    synchronized (this) {
15723                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15724                                dumpPackage).dumpLocked();
15725                    }
15726                }
15727            } else if ("locks".equals(cmd)) {
15728                LockGuard.dump(fd, pw, args);
15729            } else {
15730                // Dumping a single activity?
15731                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15732                        dumpFocusedStackOnly)) {
15733                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15734                    int res = shell.exec(this, null, fd, null, args, null,
15735                            new ResultReceiver(null));
15736                    if (res < 0) {
15737                        pw.println("Bad activity command, or no activities match: " + cmd);
15738                        pw.println("Use -h for help.");
15739                    }
15740                }
15741            }
15742            if (!more) {
15743                Binder.restoreCallingIdentity(origId);
15744                return;
15745            }
15746        }
15747
15748        // No piece of data specified, dump everything.
15749        if (dumpCheckinFormat) {
15750            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15751        } else if (dumpClient) {
15752            ActiveServices.ServiceDumper sdumper;
15753            synchronized (this) {
15754                mConstants.dump(pw);
15755                pw.println();
15756                if (dumpAll) {
15757                    pw.println("-------------------------------------------------------------------------------");
15758                }
15759                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15760                pw.println();
15761                if (dumpAll) {
15762                    pw.println("-------------------------------------------------------------------------------");
15763                }
15764                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15765                pw.println();
15766                if (dumpAll) {
15767                    pw.println("-------------------------------------------------------------------------------");
15768                }
15769                if (dumpAll || dumpPackage != null) {
15770                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15771                    pw.println();
15772                    if (dumpAll) {
15773                        pw.println("-------------------------------------------------------------------------------");
15774                    }
15775                }
15776                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15777                pw.println();
15778                if (dumpAll) {
15779                    pw.println("-------------------------------------------------------------------------------");
15780                }
15781                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15782                pw.println();
15783                if (dumpAll) {
15784                    pw.println("-------------------------------------------------------------------------------");
15785                }
15786                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15787                        dumpPackage);
15788            }
15789            sdumper.dumpWithClient();
15790            pw.println();
15791            synchronized (this) {
15792                if (dumpAll) {
15793                    pw.println("-------------------------------------------------------------------------------");
15794                }
15795                if (mRecentTasks != null) {
15796                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
15797                }
15798                pw.println();
15799                if (dumpAll) {
15800                    pw.println("-------------------------------------------------------------------------------");
15801                }
15802                dumpLastANRLocked(pw);
15803                pw.println();
15804                if (dumpAll) {
15805                    pw.println("-------------------------------------------------------------------------------");
15806                }
15807                dumpActivityStarterLocked(pw, dumpPackage);
15808                pw.println();
15809                if (dumpAll) {
15810                    pw.println("-------------------------------------------------------------------------------");
15811                }
15812                dumpActivityContainersLocked(pw);
15813                pw.println();
15814                if (dumpAll) {
15815                    pw.println("-------------------------------------------------------------------------------");
15816                }
15817                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15818                if (mAssociations.size() > 0) {
15819                    pw.println();
15820                    if (dumpAll) {
15821                        pw.println("-------------------------------------------------------------------------------");
15822                    }
15823                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15824                }
15825                pw.println();
15826                if (dumpAll) {
15827                    pw.println("-------------------------------------------------------------------------------");
15828                }
15829                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
15830            }
15831
15832        } else {
15833            synchronized (this) {
15834                mConstants.dump(pw);
15835                pw.println();
15836                if (dumpAll) {
15837                    pw.println("-------------------------------------------------------------------------------");
15838                }
15839                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15840                pw.println();
15841                if (dumpAll) {
15842                    pw.println("-------------------------------------------------------------------------------");
15843                }
15844                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15845                pw.println();
15846                if (dumpAll) {
15847                    pw.println("-------------------------------------------------------------------------------");
15848                }
15849                if (dumpAll || dumpPackage != null) {
15850                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15851                    pw.println();
15852                    if (dumpAll) {
15853                        pw.println("-------------------------------------------------------------------------------");
15854                    }
15855                }
15856                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15857                pw.println();
15858                if (dumpAll) {
15859                    pw.println("-------------------------------------------------------------------------------");
15860                }
15861                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15862                pw.println();
15863                if (dumpAll) {
15864                    pw.println("-------------------------------------------------------------------------------");
15865                }
15866                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15867                        .dumpLocked();
15868                pw.println();
15869                if (dumpAll) {
15870                    pw.println("-------------------------------------------------------------------------------");
15871                }
15872                if (mRecentTasks != null) {
15873                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
15874                }
15875                pw.println();
15876                if (dumpAll) {
15877                    pw.println("-------------------------------------------------------------------------------");
15878                }
15879                dumpLastANRLocked(pw);
15880                pw.println();
15881                if (dumpAll) {
15882                    pw.println("-------------------------------------------------------------------------------");
15883                }
15884                dumpActivityStarterLocked(pw, dumpPackage);
15885                pw.println();
15886                if (dumpAll) {
15887                    pw.println("-------------------------------------------------------------------------------");
15888                }
15889                dumpActivityContainersLocked(pw);
15890                pw.println();
15891                if (dumpAll) {
15892                    pw.println("-------------------------------------------------------------------------------");
15893                }
15894                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15895                if (mAssociations.size() > 0) {
15896                    pw.println();
15897                    if (dumpAll) {
15898                        pw.println("-------------------------------------------------------------------------------");
15899                    }
15900                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15901                }
15902                pw.println();
15903                if (dumpAll) {
15904                    pw.println("-------------------------------------------------------------------------------");
15905                }
15906                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
15907            }
15908        }
15909        Binder.restoreCallingIdentity(origId);
15910    }
15911
15912    private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
15913        // The output proto of "activity --proto activities" is ActivityStackSupervisorProto
15914        mStackSupervisor.writeToProto(proto);
15915    }
15916
15917    private void dumpLastANRLocked(PrintWriter pw) {
15918        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15919        if (mLastANRState == null) {
15920            pw.println("  <no ANR has occurred since boot>");
15921        } else {
15922            pw.println(mLastANRState);
15923        }
15924    }
15925
15926    private void dumpActivityContainersLocked(PrintWriter pw) {
15927        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
15928        mStackSupervisor.dumpChildrenNames(pw, " ");
15929        pw.println(" ");
15930    }
15931
15932    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15933        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15934        mActivityStartController.dump(pw, "", dumpPackage);
15935    }
15936
15937    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15938            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15939        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15940                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15941    }
15942
15943    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15944            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15945        pw.println(header);
15946
15947        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15948                dumpPackage);
15949        boolean needSep = printedAnything;
15950
15951        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15952                mStackSupervisor.getResumedActivityLocked(),
15953                dumpPackage, needSep, "  ResumedActivity: ");
15954        if (printed) {
15955            printedAnything = true;
15956            needSep = false;
15957        }
15958
15959        if (dumpPackage == null) {
15960            if (needSep) {
15961                pw.println();
15962            }
15963            printedAnything = true;
15964            mStackSupervisor.dump(pw, "  ");
15965        }
15966
15967        if (!printedAnything) {
15968            pw.println("  (nothing)");
15969        }
15970    }
15971
15972    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15973            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15974        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15975
15976        int dumpUid = 0;
15977        if (dumpPackage != null) {
15978            IPackageManager pm = AppGlobals.getPackageManager();
15979            try {
15980                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15981            } catch (RemoteException e) {
15982            }
15983        }
15984
15985        boolean printedAnything = false;
15986
15987        final long now = SystemClock.uptimeMillis();
15988
15989        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15990            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15991                    = mAssociations.valueAt(i1);
15992            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15993                SparseArray<ArrayMap<String, Association>> sourceUids
15994                        = targetComponents.valueAt(i2);
15995                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15996                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15997                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15998                        Association ass = sourceProcesses.valueAt(i4);
15999                        if (dumpPackage != null) {
16000                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
16001                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
16002                                continue;
16003                            }
16004                        }
16005                        printedAnything = true;
16006                        pw.print("  ");
16007                        pw.print(ass.mTargetProcess);
16008                        pw.print("/");
16009                        UserHandle.formatUid(pw, ass.mTargetUid);
16010                        pw.print(" <- ");
16011                        pw.print(ass.mSourceProcess);
16012                        pw.print("/");
16013                        UserHandle.formatUid(pw, ass.mSourceUid);
16014                        pw.println();
16015                        pw.print("    via ");
16016                        pw.print(ass.mTargetComponent.flattenToShortString());
16017                        pw.println();
16018                        pw.print("    ");
16019                        long dur = ass.mTime;
16020                        if (ass.mNesting > 0) {
16021                            dur += now - ass.mStartTime;
16022                        }
16023                        TimeUtils.formatDuration(dur, pw);
16024                        pw.print(" (");
16025                        pw.print(ass.mCount);
16026                        pw.print(" times)");
16027                        pw.print("  ");
16028                        for (int i=0; i<ass.mStateTimes.length; i++) {
16029                            long amt = ass.mStateTimes[i];
16030                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16031                                amt += now - ass.mLastStateUptime;
16032                            }
16033                            if (amt != 0) {
16034                                pw.print(" ");
16035                                pw.print(ProcessList.makeProcStateString(
16036                                            i + ActivityManager.MIN_PROCESS_STATE));
16037                                pw.print("=");
16038                                TimeUtils.formatDuration(amt, pw);
16039                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16040                                    pw.print("*");
16041                                }
16042                            }
16043                        }
16044                        pw.println();
16045                        if (ass.mNesting > 0) {
16046                            pw.print("    Currently active: ");
16047                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
16048                            pw.println();
16049                        }
16050                    }
16051                }
16052            }
16053
16054        }
16055
16056        if (!printedAnything) {
16057            pw.println("  (nothing)");
16058        }
16059    }
16060
16061    private int getAppId(String dumpPackage) {
16062        if (dumpPackage != null) {
16063            try {
16064                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
16065                        dumpPackage, 0);
16066                return UserHandle.getAppId(info.uid);
16067            } catch (NameNotFoundException e) {
16068                e.printStackTrace();
16069            }
16070        }
16071        return -1;
16072    }
16073
16074    boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
16075                String header, boolean needSep) {
16076        boolean printed = false;
16077        for (int i=0; i<uids.size(); i++) {
16078            UidRecord uidRec = uids.valueAt(i);
16079            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
16080                continue;
16081            }
16082            if (!printed) {
16083                printed = true;
16084                if (needSep) {
16085                    pw.println();
16086                }
16087                pw.print("  ");
16088                pw.println(header);
16089                needSep = true;
16090            }
16091            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
16092            pw.print(": "); pw.println(uidRec);
16093        }
16094        return printed;
16095    }
16096
16097    boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
16098        if(counts != null) {
16099            pw.println(header);
16100            for (int i = 0; i < counts.size(); i++) {
16101                final int uid = counts.keyAt(i);
16102                final int binderCount = counts.valueAt(i);
16103                pw.print("    UID ");
16104                pw.print(uid);
16105                pw.print(", binder count = ");
16106                pw.print(binderCount);
16107                pw.print(", package(s)= ");
16108                final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
16109                if (pkgNames != null) {
16110                    for (int j = 0; j < pkgNames.length; j++) {
16111                        pw.print(pkgNames[j]);
16112                        pw.print("; ");
16113                    }
16114                } else {
16115                    pw.print("NO PACKAGE NAME FOUND");
16116                }
16117                pw.println();
16118            }
16119            pw.println();
16120            return true;
16121        }
16122        return false;
16123    }
16124
16125    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16126            int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
16127        boolean needSep = false;
16128        int numPers = 0;
16129
16130        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
16131
16132        if (dumpAll) {
16133            final int NP = mProcessNames.getMap().size();
16134            for (int ip=0; ip<NP; ip++) {
16135                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16136                final int NA = procs.size();
16137                for (int ia=0; ia<NA; ia++) {
16138                    ProcessRecord r = procs.valueAt(ia);
16139                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16140                        continue;
16141                    }
16142                    if (!needSep) {
16143                        pw.println("  All known processes:");
16144                        needSep = true;
16145                    }
16146                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
16147                        pw.print(" UID "); pw.print(procs.keyAt(ia));
16148                        pw.print(" "); pw.println(r);
16149                    r.dump(pw, "    ");
16150                    if (r.persistent) {
16151                        numPers++;
16152                    }
16153                }
16154            }
16155        }
16156
16157        if (mIsolatedProcesses.size() > 0) {
16158            boolean printed = false;
16159            for (int i=0; i<mIsolatedProcesses.size(); i++) {
16160                ProcessRecord r = mIsolatedProcesses.valueAt(i);
16161                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16162                    continue;
16163                }
16164                if (!printed) {
16165                    if (needSep) {
16166                        pw.println();
16167                    }
16168                    pw.println("  Isolated process list (sorted by uid):");
16169                    printed = true;
16170                    needSep = true;
16171                }
16172                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
16173                pw.println(r);
16174            }
16175        }
16176
16177        if (mActiveInstrumentation.size() > 0) {
16178            boolean printed = false;
16179            for (int i=0; i<mActiveInstrumentation.size(); i++) {
16180                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16181                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16182                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16183                    continue;
16184                }
16185                if (!printed) {
16186                    if (needSep) {
16187                        pw.println();
16188                    }
16189                    pw.println("  Active instrumentation:");
16190                    printed = true;
16191                    needSep = true;
16192                }
16193                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
16194                pw.println(ai);
16195                ai.dump(pw, "      ");
16196            }
16197        }
16198
16199        if (mActiveUids.size() > 0) {
16200            if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16201                needSep = true;
16202            }
16203        }
16204        if (dumpAll) {
16205            if (mValidateUids.size() > 0) {
16206                if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16207                        needSep)) {
16208                    needSep = true;
16209                }
16210            }
16211        }
16212
16213        if (mLruProcesses.size() > 0) {
16214            if (needSep) {
16215                pw.println();
16216            }
16217            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16218                    pw.print(" total, non-act at ");
16219                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16220                    pw.print(", non-svc at ");
16221                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16222                    pw.println("):");
16223            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
16224            needSep = true;
16225        }
16226
16227        if (dumpAll || dumpPackage != null) {
16228            synchronized (mPidsSelfLocked) {
16229                boolean printed = false;
16230                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16231                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16232                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16233                        continue;
16234                    }
16235                    if (!printed) {
16236                        if (needSep) pw.println();
16237                        needSep = true;
16238                        pw.println("  PID mappings:");
16239                        printed = true;
16240                    }
16241                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16242                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16243                }
16244            }
16245        }
16246
16247        if (mImportantProcesses.size() > 0) {
16248            synchronized (mPidsSelfLocked) {
16249                boolean printed = false;
16250                for (int i = 0; i< mImportantProcesses.size(); i++) {
16251                    ProcessRecord r = mPidsSelfLocked.get(
16252                            mImportantProcesses.valueAt(i).pid);
16253                    if (dumpPackage != null && (r == null
16254                            || !r.pkgList.containsKey(dumpPackage))) {
16255                        continue;
16256                    }
16257                    if (!printed) {
16258                        if (needSep) pw.println();
16259                        needSep = true;
16260                        pw.println("  Foreground Processes:");
16261                        printed = true;
16262                    }
16263                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
16264                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16265                }
16266            }
16267        }
16268
16269        if (mPersistentStartingProcesses.size() > 0) {
16270            if (needSep) pw.println();
16271            needSep = true;
16272            pw.println("  Persisent processes that are starting:");
16273            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
16274                    "Starting Norm", "Restarting PERS", dumpPackage);
16275        }
16276
16277        if (mRemovedProcesses.size() > 0) {
16278            if (needSep) pw.println();
16279            needSep = true;
16280            pw.println("  Processes that are being removed:");
16281            dumpProcessList(pw, this, mRemovedProcesses, "    ",
16282                    "Removed Norm", "Removed PERS", dumpPackage);
16283        }
16284
16285        if (mProcessesOnHold.size() > 0) {
16286            if (needSep) pw.println();
16287            needSep = true;
16288            pw.println("  Processes that are on old until the system is ready:");
16289            dumpProcessList(pw, this, mProcessesOnHold, "    ",
16290                    "OnHold Norm", "OnHold PERS", dumpPackage);
16291        }
16292
16293        needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16294
16295        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16296
16297        if (dumpPackage == null) {
16298            pw.println();
16299            needSep = false;
16300            mUserController.dump(pw, dumpAll);
16301        }
16302        if (mHomeProcess != null && (dumpPackage == null
16303                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16304            if (needSep) {
16305                pw.println();
16306                needSep = false;
16307            }
16308            pw.println("  mHomeProcess: " + mHomeProcess);
16309        }
16310        if (mPreviousProcess != null && (dumpPackage == null
16311                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16312            if (needSep) {
16313                pw.println();
16314                needSep = false;
16315            }
16316            pw.println("  mPreviousProcess: " + mPreviousProcess);
16317        }
16318        if (dumpAll && (mPreviousProcess == null || dumpPackage == null
16319                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16320            StringBuilder sb = new StringBuilder(128);
16321            sb.append("  mPreviousProcessVisibleTime: ");
16322            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
16323            pw.println(sb);
16324        }
16325        if (mHeavyWeightProcess != null && (dumpPackage == null
16326                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16327            if (needSep) {
16328                pw.println();
16329                needSep = false;
16330            }
16331            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16332        }
16333        if (dumpAll && mPendingStarts.size() > 0) {
16334            if (needSep) pw.println();
16335            needSep = true;
16336            pw.println("  mPendingStarts: ");
16337            for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
16338                pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
16339            }
16340        }
16341        if (dumpPackage == null) {
16342            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
16343            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
16344        }
16345        if (dumpAll) {
16346            if (dumpPackage == null) {
16347                pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
16348            }
16349            if (mCompatModePackages.getPackages().size() > 0) {
16350                boolean printed = false;
16351                for (Map.Entry<String, Integer> entry
16352                        : mCompatModePackages.getPackages().entrySet()) {
16353                    String pkg = entry.getKey();
16354                    int mode = entry.getValue();
16355                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
16356                        continue;
16357                    }
16358                    if (!printed) {
16359                        pw.println("  mScreenCompatPackages:");
16360                        printed = true;
16361                    }
16362                    pw.print("    "); pw.print(pkg); pw.print(": ");
16363                            pw.print(mode); pw.println();
16364                }
16365            }
16366            final int NI = mUidObservers.getRegisteredCallbackCount();
16367            boolean printed = false;
16368            for (int i=0; i<NI; i++) {
16369                final UidObserverRegistration reg = (UidObserverRegistration)
16370                        mUidObservers.getRegisteredCallbackCookie(i);
16371                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16372                    if (!printed) {
16373                        pw.println("  mUidObservers:");
16374                        printed = true;
16375                    }
16376                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
16377                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
16378                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
16379                        pw.print(" IDLE");
16380                    }
16381                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
16382                        pw.print(" ACT" );
16383                    }
16384                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
16385                        pw.print(" GONE");
16386                    }
16387                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
16388                        pw.print(" STATE");
16389                        pw.print(" (cut="); pw.print(reg.cutpoint);
16390                        pw.print(")");
16391                    }
16392                    pw.println();
16393                    if (reg.lastProcStates != null) {
16394                        final int NJ = reg.lastProcStates.size();
16395                        for (int j=0; j<NJ; j++) {
16396                            pw.print("      Last ");
16397                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
16398                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
16399                        }
16400                    }
16401                }
16402            }
16403            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
16404            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
16405            if (mPendingTempWhitelist.size() > 0) {
16406                pw.println("  mPendingTempWhitelist:");
16407                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
16408                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
16409                    pw.print("    ");
16410                    UserHandle.formatUid(pw, ptw.targetUid);
16411                    pw.print(": ");
16412                    TimeUtils.formatDuration(ptw.duration, pw);
16413                    pw.print(" ");
16414                    pw.println(ptw.tag);
16415                }
16416            }
16417        }
16418        if (dumpPackage == null) {
16419            pw.println("  mWakefulness="
16420                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
16421            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
16422            pw.println("  mSleeping=" + mSleeping);
16423            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
16424            if (mRunningVoice != null) {
16425                pw.println("  mRunningVoice=" + mRunningVoice);
16426                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
16427            }
16428            pw.println("  mVrController=" + mVrController);
16429        }
16430        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16431                || mOrigWaitForDebugger) {
16432            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16433                    || dumpPackage.equals(mOrigDebugApp)) {
16434                if (needSep) {
16435                    pw.println();
16436                    needSep = false;
16437                }
16438                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
16439                        + " mDebugTransient=" + mDebugTransient
16440                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
16441            }
16442        }
16443        if (mCurAppTimeTracker != null) {
16444            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
16445        }
16446        if (mMemWatchProcesses.getMap().size() > 0) {
16447            pw.println("  Mem watch processes:");
16448            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
16449                    = mMemWatchProcesses.getMap();
16450            for (int i=0; i<procs.size(); i++) {
16451                final String proc = procs.keyAt(i);
16452                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16453                for (int j=0; j<uids.size(); j++) {
16454                    if (needSep) {
16455                        pw.println();
16456                        needSep = false;
16457                    }
16458                    StringBuilder sb = new StringBuilder();
16459                    sb.append("    ").append(proc).append('/');
16460                    UserHandle.formatUid(sb, uids.keyAt(j));
16461                    Pair<Long, String> val = uids.valueAt(j);
16462                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
16463                    if (val.second != null) {
16464                        sb.append(", report to ").append(val.second);
16465                    }
16466                    pw.println(sb.toString());
16467                }
16468            }
16469            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
16470            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
16471            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
16472                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
16473        }
16474        if (mTrackAllocationApp != null) {
16475            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16476                if (needSep) {
16477                    pw.println();
16478                    needSep = false;
16479                }
16480                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
16481            }
16482        }
16483        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16484                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16485            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16486                if (needSep) {
16487                    pw.println();
16488                    needSep = false;
16489                }
16490                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16491                if (mProfilerInfo != null) {
16492                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16493                            mProfilerInfo.profileFd);
16494                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16495                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16496                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16497                    pw.println("  mProfileType=" + mProfileType);
16498                }
16499            }
16500        }
16501        if (mNativeDebuggingApp != null) {
16502            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16503                if (needSep) {
16504                    pw.println();
16505                    needSep = false;
16506                }
16507                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16508            }
16509        }
16510        if (mAllowAppSwitchUids.size() > 0) {
16511            boolean printed = false;
16512            for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
16513                ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
16514                for (int j = 0; j < types.size(); j++) {
16515                    if (dumpPackage == null ||
16516                            UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
16517                        if (needSep) {
16518                            pw.println();
16519                            needSep = false;
16520                        }
16521                        if (!printed) {
16522                            pw.println("  mAllowAppSwitchUids:");
16523                            printed = true;
16524                        }
16525                        pw.print("    User ");
16526                        pw.print(mAllowAppSwitchUids.keyAt(i));
16527                        pw.print(": Type ");
16528                        pw.print(types.keyAt(j));
16529                        pw.print(" = ");
16530                        UserHandle.formatUid(pw, types.valueAt(j).intValue());
16531                        pw.println();
16532                    }
16533                }
16534            }
16535        }
16536        if (dumpPackage == null) {
16537            if (mAlwaysFinishActivities) {
16538                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16539            }
16540            if (mController != null) {
16541                pw.println("  mController=" + mController
16542                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16543            }
16544            if (dumpAll) {
16545                pw.println("  Total persistent processes: " + numPers);
16546                pw.println("  mProcessesReady=" + mProcessesReady
16547                        + " mSystemReady=" + mSystemReady
16548                        + " mBooted=" + mBooted
16549                        + " mFactoryTest=" + mFactoryTest);
16550                pw.println("  mBooting=" + mBooting
16551                        + " mCallFinishBooting=" + mCallFinishBooting
16552                        + " mBootAnimationComplete=" + mBootAnimationComplete);
16553                pw.print("  mLastPowerCheckUptime=");
16554                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16555                        pw.println("");
16556                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16557                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16558                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16559                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16560                        + " (" + mLruProcesses.size() + " total)"
16561                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16562                        + " mNumServiceProcs=" + mNumServiceProcs
16563                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16564                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16565                        + " mLastMemoryLevel=" + mLastMemoryLevel
16566                        + " mLastNumProcesses=" + mLastNumProcesses);
16567                long now = SystemClock.uptimeMillis();
16568                pw.print("  mLastIdleTime=");
16569                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
16570                        pw.print(" mLowRamSinceLastIdle=");
16571                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16572                        pw.println();
16573            }
16574        }
16575        pw.println("  mForceBackgroundCheck=" + mForceBackgroundCheck);
16576    }
16577
16578    void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
16579        int numPers = 0;
16580
16581        final int NP = mProcessNames.getMap().size();
16582        for (int ip=0; ip<NP; ip++) {
16583            SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16584            final int NA = procs.size();
16585            for (int ia = 0; ia<NA; ia++) {
16586                ProcessRecord r = procs.valueAt(ia);
16587                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16588                    continue;
16589                }
16590                r.writeToProto(proto, ProcessesProto.PROCS);
16591                if (r.persistent) {
16592                    numPers++;
16593                }
16594            }
16595        }
16596
16597        for (int i=0; i<mIsolatedProcesses.size(); i++) {
16598            ProcessRecord r = mIsolatedProcesses.valueAt(i);
16599            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16600                continue;
16601            }
16602            r.writeToProto(proto, ProcessesProto.ISOLATED_PROCS);
16603        }
16604
16605        for (int i=0; i<mActiveInstrumentation.size(); i++) {
16606            ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16607            if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16608                    && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16609                continue;
16610            }
16611            ai.writeToProto(proto, ProcessesProto.ACTIVE_INSTRUMENTATIONS);
16612        }
16613
16614        int whichAppId = getAppId(dumpPackage);
16615        for (int i=0; i<mActiveUids.size(); i++) {
16616            UidRecord uidRec = mActiveUids.valueAt(i);
16617            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16618                continue;
16619            }
16620            uidRec.writeToProto(proto, ProcessesProto.ACTIVE_UIDS);
16621        }
16622
16623        for (int i=0; i<mValidateUids.size(); i++) {
16624            UidRecord uidRec = mValidateUids.valueAt(i);
16625            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16626                continue;
16627            }
16628            uidRec.writeToProto(proto, ProcessesProto.VALIDATE_UIDS);
16629        }
16630
16631        if (mLruProcesses.size() > 0) {
16632            long lruToken = proto.start(ProcessesProto.LRU_PROCS);
16633            int total = mLruProcesses.size();
16634            proto.write(ProcessesProto.LruProcesses.SIZE, total);
16635            proto.write(ProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
16636            proto.write(ProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
16637            writeProcessOomListToProto(proto, ProcessesProto.LruProcesses.LIST, this,
16638                    mLruProcesses,false, dumpPackage);
16639            proto.end(lruToken);
16640        }
16641
16642        if (dumpPackage != null) {
16643            synchronized (mPidsSelfLocked) {
16644                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16645                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16646                    if (!r.pkgList.containsKey(dumpPackage)) {
16647                        continue;
16648                    }
16649                    r.writeToProto(proto, ProcessesProto.PIDS_SELF_LOCKED);
16650                }
16651            }
16652        }
16653
16654        if (mImportantProcesses.size() > 0) {
16655            synchronized (mPidsSelfLocked) {
16656                for (int i=0; i<mImportantProcesses.size(); i++) {
16657                    ImportanceToken it = mImportantProcesses.valueAt(i);
16658                    ProcessRecord r = mPidsSelfLocked.get(it.pid);
16659                    if (dumpPackage != null && (r == null
16660                            || !r.pkgList.containsKey(dumpPackage))) {
16661                        continue;
16662                    }
16663                    it.writeToProto(proto, ProcessesProto.IMPORTANT_PROCS);
16664                }
16665            }
16666        }
16667
16668        for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
16669            ProcessRecord r = mPersistentStartingProcesses.get(i);
16670            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16671                continue;
16672            }
16673            r.writeToProto(proto, ProcessesProto.PERSISTENT_STARTING_PROCS);
16674        }
16675
16676        for (int i=0; i<mRemovedProcesses.size(); i++) {
16677            ProcessRecord r = mRemovedProcesses.get(i);
16678            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16679                continue;
16680            }
16681            r.writeToProto(proto, ProcessesProto.REMOVED_PROCS);
16682        }
16683
16684        for (int i=0; i<mProcessesOnHold.size(); i++) {
16685            ProcessRecord r = mProcessesOnHold.get(i);
16686            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16687                continue;
16688            }
16689            r.writeToProto(proto, ProcessesProto.ON_HOLD_PROCS);
16690        }
16691
16692        writeProcessesToGcToProto(proto, ProcessesProto.GC_PROCS, dumpPackage);
16693        mAppErrors.writeToProto(proto, ProcessesProto.APP_ERRORS, dumpPackage);
16694
16695        if (dumpPackage == null) {
16696            mUserController.writeToProto(proto, ProcessesProto.USER_CONTROLLER);
16697            getGlobalConfiguration().writeToProto(proto, ProcessesProto.GLOBAL_CONFIGURATION);
16698            proto.write(ProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
16699        }
16700
16701        if (mHomeProcess != null && (dumpPackage == null
16702                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16703            mHomeProcess.writeToProto(proto, ProcessesProto.HOME_PROC);
16704        }
16705
16706        if (mPreviousProcess != null && (dumpPackage == null
16707                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16708            mPreviousProcess.writeToProto(proto, ProcessesProto.PREVIOUS_PROC);
16709            proto.write(ProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
16710        }
16711
16712        if (mHeavyWeightProcess != null && (dumpPackage == null
16713                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16714            mHeavyWeightProcess.writeToProto(proto, ProcessesProto.HEAVY_WEIGHT_PROC);
16715        }
16716
16717        for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
16718            String pkg = entry.getKey();
16719            int mode = entry.getValue();
16720            if (dumpPackage == null || dumpPackage.equals(pkg)) {
16721                long compatToken = proto.start(ProcessesProto.SCREEN_COMPAT_PACKAGES);
16722                proto.write(ProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
16723                proto.write(ProcessesProto.ScreenCompatPackage.MODE, mode);
16724                proto.end(compatToken);
16725            }
16726        }
16727
16728        final int NI = mUidObservers.getRegisteredCallbackCount();
16729        for (int i=0; i<NI; i++) {
16730            final UidObserverRegistration reg = (UidObserverRegistration)
16731                    mUidObservers.getRegisteredCallbackCookie(i);
16732            if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16733                reg.writeToProto(proto, ProcessesProto.UID_OBSERVERS);
16734            }
16735        }
16736
16737        for (int v : mDeviceIdleWhitelist) {
16738            proto.write(ProcessesProto.DEVICE_IDLE_WHITELIST, v);
16739        }
16740
16741        for (int v : mDeviceIdleTempWhitelist) {
16742            proto.write(ProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
16743        }
16744
16745        if (mPendingTempWhitelist.size() > 0) {
16746            for (int i=0; i < mPendingTempWhitelist.size(); i++) {
16747                mPendingTempWhitelist.valueAt(i).writeToProto(proto,
16748                        ProcessesProto.PENDING_TEMP_WHITELIST);
16749            }
16750        }
16751
16752        if (dumpPackage == null) {
16753            final long sleepToken = proto.start(ProcessesProto.SLEEP_STATUS);
16754            proto.write(ProcessesProto.SleepStatus.WAKEFULNESS,
16755                    PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
16756            for (SleepToken st : mStackSupervisor.mSleepTokens) {
16757                proto.write(ProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
16758            }
16759            proto.write(ProcessesProto.SleepStatus.SLEEPING, mSleeping);
16760            proto.write(ProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
16761            proto.write(ProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
16762            proto.end(sleepToken);
16763
16764            if (mRunningVoice != null) {
16765                final long vrToken = proto.start(ProcessesProto.RUNNING_VOICE);
16766                proto.write(ProcessesProto.VoiceProto.SESSION, mRunningVoice.toString());
16767                mVoiceWakeLock.writeToProto(proto, ProcessesProto.VoiceProto.WAKELOCK);
16768                proto.end(vrToken);
16769            }
16770
16771            mVrController.writeToProto(proto, ProcessesProto.VR_CONTROLLER);
16772        }
16773
16774        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16775                || mOrigWaitForDebugger) {
16776            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16777                    || dumpPackage.equals(mOrigDebugApp)) {
16778                final long debugAppToken = proto.start(ProcessesProto.DEBUG);
16779                proto.write(ProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
16780                proto.write(ProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
16781                proto.write(ProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
16782                proto.write(ProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
16783                proto.end(debugAppToken);
16784            }
16785        }
16786
16787        if (mCurAppTimeTracker != null) {
16788            mCurAppTimeTracker.writeToProto(proto, ProcessesProto.CURRENT_TRACKER, true);
16789        }
16790
16791        if (mMemWatchProcesses.getMap().size() > 0) {
16792            final long token = proto.start(ProcessesProto.MEM_WATCH_PROCESSES);
16793            ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
16794            for (int i=0; i<procs.size(); i++) {
16795                final String proc = procs.keyAt(i);
16796                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16797                final long ptoken = proto.start(ProcessesProto.MemWatchProcess.PROCS);
16798                proto.write(ProcessesProto.MemWatchProcess.Process.NAME, proc);
16799                for (int j=0; j<uids.size(); j++) {
16800                    final long utoken = proto.start(ProcessesProto.MemWatchProcess.Process.MEM_STATS);
16801                    Pair<Long, String> val = uids.valueAt(j);
16802                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
16803                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
16804                            DebugUtils.sizeValueToString(val.first, new StringBuilder()));
16805                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
16806                    proto.end(utoken);
16807                }
16808                proto.end(ptoken);
16809            }
16810
16811            final long dtoken = proto.start(ProcessesProto.MemWatchProcess.DUMP);
16812            proto.write(ProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
16813            proto.write(ProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
16814            proto.write(ProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
16815            proto.write(ProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
16816            proto.end(dtoken);
16817
16818            proto.end(token);
16819        }
16820
16821        if (mTrackAllocationApp != null) {
16822            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16823                proto.write(ProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
16824            }
16825        }
16826
16827        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16828                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16829            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16830                final long token = proto.start(ProcessesProto.PROFILE);
16831                proto.write(ProcessesProto.Profile.APP_NAME, mProfileApp);
16832                mProfileProc.writeToProto(proto,ProcessesProto.Profile.PROC);
16833                if (mProfilerInfo != null) {
16834                    mProfilerInfo.writeToProto(proto, ProcessesProto.Profile.INFO);
16835                    proto.write(ProcessesProto.Profile.TYPE, mProfileType);
16836                }
16837                proto.end(token);
16838            }
16839        }
16840
16841        if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16842            proto.write(ProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
16843        }
16844
16845        if (dumpPackage == null) {
16846            proto.write(ProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
16847            if (mController != null) {
16848                final long token = proto.start(ProcessesProto.CONTROLLER);
16849                proto.write(ProcessesProto.Controller.CONTROLLER, mController.toString());
16850                proto.write(ProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
16851                proto.end(token);
16852            }
16853            proto.write(ProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
16854            proto.write(ProcessesProto.PROCESSES_READY, mProcessesReady);
16855            proto.write(ProcessesProto.SYSTEM_READY, mSystemReady);
16856            proto.write(ProcessesProto.BOOTED, mBooted);
16857            proto.write(ProcessesProto.FACTORY_TEST, mFactoryTest);
16858            proto.write(ProcessesProto.BOOTING, mBooting);
16859            proto.write(ProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
16860            proto.write(ProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
16861            proto.write(ProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
16862            mStackSupervisor.mGoingToSleep.writeToProto(proto, ProcessesProto.GOING_TO_SLEEP);
16863            mStackSupervisor.mLaunchingActivity.writeToProto(proto, ProcessesProto.LAUNCHING_ACTIVITY);
16864            proto.write(ProcessesProto.ADJ_SEQ, mAdjSeq);
16865            proto.write(ProcessesProto.LRU_SEQ, mLruSeq);
16866            proto.write(ProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
16867            proto.write(ProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
16868            proto.write(ProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
16869            proto.write(ProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
16870            proto.write(ProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
16871            proto.write(ProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
16872            long now = SystemClock.uptimeMillis();
16873            ProtoUtils.toDuration(proto, ProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
16874            proto.write(ProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
16875        }
16876
16877    }
16878
16879    void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
16880        if (mProcessesToGc.size() > 0) {
16881            long now = SystemClock.uptimeMillis();
16882            for (int i=0; i<mProcessesToGc.size(); i++) {
16883                ProcessRecord r = mProcessesToGc.get(i);
16884                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16885                    continue;
16886                }
16887                final long token = proto.start(fieldId);
16888                r.writeToProto(proto, ProcessToGcProto.PROC);
16889                proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
16890                proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
16891                proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
16892                proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
16893                proto.end(token);
16894            }
16895        }
16896    }
16897
16898    boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
16899        if (mProcessesToGc.size() > 0) {
16900            boolean printed = false;
16901            long now = SystemClock.uptimeMillis();
16902            for (int i=0; i<mProcessesToGc.size(); i++) {
16903                ProcessRecord proc = mProcessesToGc.get(i);
16904                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16905                    continue;
16906                }
16907                if (!printed) {
16908                    if (needSep) pw.println();
16909                    needSep = true;
16910                    pw.println("  Processes that are waiting to GC:");
16911                    printed = true;
16912                }
16913                pw.print("    Process "); pw.println(proc);
16914                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16915                        pw.print(", last gced=");
16916                        pw.print(now-proc.lastRequestedGc);
16917                        pw.print(" ms ago, last lowMem=");
16918                        pw.print(now-proc.lastLowMemory);
16919                        pw.println(" ms ago");
16920
16921            }
16922        }
16923        return needSep;
16924    }
16925
16926    void printOomLevel(PrintWriter pw, String name, int adj) {
16927        pw.print("    ");
16928        if (adj >= 0) {
16929            pw.print(' ');
16930            if (adj < 10) pw.print(' ');
16931        } else {
16932            if (adj > -10) pw.print(' ');
16933        }
16934        pw.print(adj);
16935        pw.print(": ");
16936        pw.print(name);
16937        pw.print(" (");
16938        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16939        pw.println(")");
16940    }
16941
16942    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16943            int opti, boolean dumpAll) {
16944        boolean needSep = false;
16945
16946        if (mLruProcesses.size() > 0) {
16947            if (needSep) pw.println();
16948            needSep = true;
16949            pw.println("  OOM levels:");
16950            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16951            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16952            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16953            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16954            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16955            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16956            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16957            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16958            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16959            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16960            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16961            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16962            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16963            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16964
16965            if (needSep) pw.println();
16966            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16967                    pw.print(" total, non-act at ");
16968                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16969                    pw.print(", non-svc at ");
16970                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16971                    pw.println("):");
16972            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16973            needSep = true;
16974        }
16975
16976        dumpProcessesToGc(pw, needSep, null);
16977
16978        pw.println();
16979        pw.println("  mHomeProcess: " + mHomeProcess);
16980        pw.println("  mPreviousProcess: " + mPreviousProcess);
16981        if (mHeavyWeightProcess != null) {
16982            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16983        }
16984
16985        return true;
16986    }
16987
16988    /**
16989     * There are three ways to call this:
16990     *  - no provider specified: dump all the providers
16991     *  - a flattened component name that matched an existing provider was specified as the
16992     *    first arg: dump that one provider
16993     *  - the first arg isn't the flattened component name of an existing provider:
16994     *    dump all providers whose component contains the first arg as a substring
16995     */
16996    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16997            int opti, boolean dumpAll) {
16998        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16999    }
17000
17001    /**
17002     * Similar to the dumpProvider, but only dumps the first matching provider.
17003     * The provider is responsible for dumping as proto.
17004     */
17005    protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
17006            String[] args) {
17007        return mProviderMap.dumpProviderProto(fd, pw, name, args);
17008    }
17009
17010    static class ItemMatcher {
17011        ArrayList<ComponentName> components;
17012        ArrayList<String> strings;
17013        ArrayList<Integer> objects;
17014        boolean all;
17015
17016        ItemMatcher() {
17017            all = true;
17018        }
17019
17020        void build(String name) {
17021            ComponentName componentName = ComponentName.unflattenFromString(name);
17022            if (componentName != null) {
17023                if (components == null) {
17024                    components = new ArrayList<ComponentName>();
17025                }
17026                components.add(componentName);
17027                all = false;
17028            } else {
17029                int objectId = 0;
17030                // Not a '/' separated full component name; maybe an object ID?
17031                try {
17032                    objectId = Integer.parseInt(name, 16);
17033                    if (objects == null) {
17034                        objects = new ArrayList<Integer>();
17035                    }
17036                    objects.add(objectId);
17037                    all = false;
17038                } catch (RuntimeException e) {
17039                    // Not an integer; just do string match.
17040                    if (strings == null) {
17041                        strings = new ArrayList<String>();
17042                    }
17043                    strings.add(name);
17044                    all = false;
17045                }
17046            }
17047        }
17048
17049        int build(String[] args, int opti) {
17050            for (; opti<args.length; opti++) {
17051                String name = args[opti];
17052                if ("--".equals(name)) {
17053                    return opti+1;
17054                }
17055                build(name);
17056            }
17057            return opti;
17058        }
17059
17060        boolean match(Object object, ComponentName comp) {
17061            if (all) {
17062                return true;
17063            }
17064            if (components != null) {
17065                for (int i=0; i<components.size(); i++) {
17066                    if (components.get(i).equals(comp)) {
17067                        return true;
17068                    }
17069                }
17070            }
17071            if (objects != null) {
17072                for (int i=0; i<objects.size(); i++) {
17073                    if (System.identityHashCode(object) == objects.get(i)) {
17074                        return true;
17075                    }
17076                }
17077            }
17078            if (strings != null) {
17079                String flat = comp.flattenToString();
17080                for (int i=0; i<strings.size(); i++) {
17081                    if (flat.contains(strings.get(i))) {
17082                        return true;
17083                    }
17084                }
17085            }
17086            return false;
17087        }
17088    }
17089
17090    /**
17091     * There are three things that cmd can be:
17092     *  - a flattened component name that matches an existing activity
17093     *  - the cmd arg isn't the flattened component name of an existing activity:
17094     *    dump all activity whose component contains the cmd as a substring
17095     *  - A hex number of the ActivityRecord object instance.
17096     *
17097     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
17098     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
17099     */
17100    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17101            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
17102        ArrayList<ActivityRecord> activities;
17103
17104        synchronized (this) {
17105            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
17106                    dumpFocusedStackOnly);
17107        }
17108
17109        if (activities.size() <= 0) {
17110            return false;
17111        }
17112
17113        String[] newArgs = new String[args.length - opti];
17114        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
17115
17116        TaskRecord lastTask = null;
17117        boolean needSep = false;
17118        for (int i=activities.size()-1; i>=0; i--) {
17119            ActivityRecord r = activities.get(i);
17120            if (needSep) {
17121                pw.println();
17122            }
17123            needSep = true;
17124            synchronized (this) {
17125                final TaskRecord task = r.getTask();
17126                if (lastTask != task) {
17127                    lastTask = task;
17128                    pw.print("TASK "); pw.print(lastTask.affinity);
17129                            pw.print(" id="); pw.print(lastTask.taskId);
17130                            pw.print(" userId="); pw.println(lastTask.userId);
17131                    if (dumpAll) {
17132                        lastTask.dump(pw, "  ");
17133                    }
17134                }
17135            }
17136            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
17137        }
17138        return true;
17139    }
17140
17141    /**
17142     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
17143     * there is a thread associated with the activity.
17144     */
17145    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
17146            final ActivityRecord r, String[] args, boolean dumpAll) {
17147        String innerPrefix = prefix + "  ";
17148        synchronized (this) {
17149            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
17150                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
17151                    pw.print(" pid=");
17152                    if (r.app != null) pw.println(r.app.pid);
17153                    else pw.println("(not running)");
17154            if (dumpAll) {
17155                r.dump(pw, innerPrefix);
17156            }
17157        }
17158        if (r.app != null && r.app.thread != null) {
17159            // flush anything that is already in the PrintWriter since the thread is going
17160            // to write to the file descriptor directly
17161            pw.flush();
17162            try {
17163                TransferPipe tp = new TransferPipe();
17164                try {
17165                    r.app.thread.dumpActivity(tp.getWriteFd(),
17166                            r.appToken, innerPrefix, args);
17167                    tp.go(fd);
17168                } finally {
17169                    tp.kill();
17170                }
17171            } catch (IOException e) {
17172                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
17173            } catch (RemoteException e) {
17174                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
17175            }
17176        }
17177    }
17178
17179    void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
17180        if (mRegisteredReceivers.size() > 0) {
17181            Iterator it = mRegisteredReceivers.values().iterator();
17182            while (it.hasNext()) {
17183                ReceiverList r = (ReceiverList)it.next();
17184                r.writeToProto(proto, BroadcastProto.RECEIVER_LIST);
17185            }
17186        }
17187        mReceiverResolver.writeToProto(proto, BroadcastProto.RECEIVER_RESOLVER);
17188        for (BroadcastQueue q : mBroadcastQueues) {
17189            q.writeToProto(proto, BroadcastProto.BROADCAST_QUEUE);
17190        }
17191        for (int user=0; user<mStickyBroadcasts.size(); user++) {
17192            long token = proto.start(BroadcastProto.STICKY_BROADCASTS);
17193            proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
17194            for (Map.Entry<String, ArrayList<Intent>> ent
17195                    : mStickyBroadcasts.valueAt(user).entrySet()) {
17196                long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
17197                proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
17198                for (Intent intent : ent.getValue()) {
17199                    intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
17200                            false, true, true, false);
17201                }
17202                proto.end(actionToken);
17203            }
17204            proto.end(token);
17205        }
17206
17207        long handlerToken = proto.start(BroadcastProto.HANDLER);
17208        proto.write(BroadcastProto.MainHandler.HANDLER, mHandler.toString());
17209        mHandler.getLooper().writeToProto(proto, BroadcastProto.MainHandler.LOOPER);
17210        proto.end(handlerToken);
17211    }
17212
17213    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17214            int opti, boolean dumpAll, String dumpPackage) {
17215        boolean needSep = false;
17216        boolean onlyHistory = false;
17217        boolean printedAnything = false;
17218
17219        if ("history".equals(dumpPackage)) {
17220            if (opti < args.length && "-s".equals(args[opti])) {
17221                dumpAll = false;
17222            }
17223            onlyHistory = true;
17224            dumpPackage = null;
17225        }
17226
17227        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
17228        if (!onlyHistory && dumpAll) {
17229            if (mRegisteredReceivers.size() > 0) {
17230                boolean printed = false;
17231                Iterator it = mRegisteredReceivers.values().iterator();
17232                while (it.hasNext()) {
17233                    ReceiverList r = (ReceiverList)it.next();
17234                    if (dumpPackage != null && (r.app == null ||
17235                            !dumpPackage.equals(r.app.info.packageName))) {
17236                        continue;
17237                    }
17238                    if (!printed) {
17239                        pw.println("  Registered Receivers:");
17240                        needSep = true;
17241                        printed = true;
17242                        printedAnything = true;
17243                    }
17244                    pw.print("  * "); pw.println(r);
17245                    r.dump(pw, "    ");
17246                }
17247            }
17248
17249            if (mReceiverResolver.dump(pw, needSep ?
17250                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
17251                    "    ", dumpPackage, false, false)) {
17252                needSep = true;
17253                printedAnything = true;
17254            }
17255        }
17256
17257        for (BroadcastQueue q : mBroadcastQueues) {
17258            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17259            printedAnything |= needSep;
17260        }
17261
17262        needSep = true;
17263
17264        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17265            for (int user=0; user<mStickyBroadcasts.size(); user++) {
17266                if (needSep) {
17267                    pw.println();
17268                }
17269                needSep = true;
17270                printedAnything = true;
17271                pw.print("  Sticky broadcasts for user ");
17272                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
17273                StringBuilder sb = new StringBuilder(128);
17274                for (Map.Entry<String, ArrayList<Intent>> ent
17275                        : mStickyBroadcasts.valueAt(user).entrySet()) {
17276                    pw.print("  * Sticky action "); pw.print(ent.getKey());
17277                    if (dumpAll) {
17278                        pw.println(":");
17279                        ArrayList<Intent> intents = ent.getValue();
17280                        final int N = intents.size();
17281                        for (int i=0; i<N; i++) {
17282                            sb.setLength(0);
17283                            sb.append("    Intent: ");
17284                            intents.get(i).toShortString(sb, false, true, false, false);
17285                            pw.println(sb.toString());
17286                            Bundle bundle = intents.get(i).getExtras();
17287                            if (bundle != null) {
17288                                pw.print("      ");
17289                                pw.println(bundle.toString());
17290                            }
17291                        }
17292                    } else {
17293                        pw.println("");
17294                    }
17295                }
17296            }
17297        }
17298
17299        if (!onlyHistory && dumpAll) {
17300            pw.println();
17301            for (BroadcastQueue queue : mBroadcastQueues) {
17302                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
17303                        + queue.mBroadcastsScheduled);
17304            }
17305            pw.println("  mHandler:");
17306            mHandler.dump(new PrintWriterPrinter(pw), "    ");
17307            needSep = true;
17308            printedAnything = true;
17309        }
17310
17311        if (!printedAnything) {
17312            pw.println("  (nothing)");
17313        }
17314    }
17315
17316    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17317            int opti, boolean dumpAll, String dumpPackage) {
17318        if (mCurBroadcastStats == null) {
17319            return;
17320        }
17321
17322        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
17323        final long now = SystemClock.elapsedRealtime();
17324        if (mLastBroadcastStats != null) {
17325            pw.print("  Last stats (from ");
17326            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
17327            pw.print(" to ");
17328            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
17329            pw.print(", ");
17330            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
17331                    - mLastBroadcastStats.mStartUptime, pw);
17332            pw.println(" uptime):");
17333            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17334                pw.println("    (nothing)");
17335            }
17336            pw.println();
17337        }
17338        pw.print("  Current stats (from ");
17339        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
17340        pw.print(" to now, ");
17341        TimeUtils.formatDuration(SystemClock.uptimeMillis()
17342                - mCurBroadcastStats.mStartUptime, pw);
17343        pw.println(" uptime):");
17344        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17345            pw.println("    (nothing)");
17346        }
17347    }
17348
17349    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17350            int opti, boolean fullCheckin, String dumpPackage) {
17351        if (mCurBroadcastStats == null) {
17352            return;
17353        }
17354
17355        if (mLastBroadcastStats != null) {
17356            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17357            if (fullCheckin) {
17358                mLastBroadcastStats = null;
17359                return;
17360            }
17361        }
17362        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17363        if (fullCheckin) {
17364            mCurBroadcastStats = null;
17365        }
17366    }
17367
17368    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17369            int opti, boolean dumpAll, String dumpPackage) {
17370        boolean needSep;
17371        boolean printedAnything = false;
17372
17373        ItemMatcher matcher = new ItemMatcher();
17374        matcher.build(args, opti);
17375
17376        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
17377
17378        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
17379        printedAnything |= needSep;
17380
17381        if (mLaunchingProviders.size() > 0) {
17382            boolean printed = false;
17383            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
17384                ContentProviderRecord r = mLaunchingProviders.get(i);
17385                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
17386                    continue;
17387                }
17388                if (!printed) {
17389                    if (needSep) pw.println();
17390                    needSep = true;
17391                    pw.println("  Launching content providers:");
17392                    printed = true;
17393                    printedAnything = true;
17394                }
17395                pw.print("  Launching #"); pw.print(i); pw.print(": ");
17396                        pw.println(r);
17397            }
17398        }
17399
17400        if (!printedAnything) {
17401            pw.println("  (nothing)");
17402        }
17403    }
17404
17405    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17406            int opti, boolean dumpAll, String dumpPackage) {
17407        boolean needSep = false;
17408        boolean printedAnything = false;
17409
17410        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
17411
17412        if (mGrantedUriPermissions.size() > 0) {
17413            boolean printed = false;
17414            int dumpUid = -2;
17415            if (dumpPackage != null) {
17416                try {
17417                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
17418                            MATCH_ANY_USER, 0);
17419                } catch (NameNotFoundException e) {
17420                    dumpUid = -1;
17421                }
17422            }
17423            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
17424                int uid = mGrantedUriPermissions.keyAt(i);
17425                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
17426                    continue;
17427                }
17428                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
17429                if (!printed) {
17430                    if (needSep) pw.println();
17431                    needSep = true;
17432                    pw.println("  Granted Uri Permissions:");
17433                    printed = true;
17434                    printedAnything = true;
17435                }
17436                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
17437                for (UriPermission perm : perms.values()) {
17438                    pw.print("    "); pw.println(perm);
17439                    if (dumpAll) {
17440                        perm.dump(pw, "      ");
17441                    }
17442                }
17443            }
17444        }
17445
17446        if (!printedAnything) {
17447            pw.println("  (nothing)");
17448        }
17449    }
17450
17451    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17452            int opti, boolean dumpAll, String dumpPackage) {
17453        boolean printed = false;
17454
17455        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
17456
17457        if (mIntentSenderRecords.size() > 0) {
17458            // Organize these by package name, so they are easier to read.
17459            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
17460            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
17461            final Iterator<WeakReference<PendingIntentRecord>> it
17462                    = mIntentSenderRecords.values().iterator();
17463            while (it.hasNext()) {
17464                WeakReference<PendingIntentRecord> ref = it.next();
17465                PendingIntentRecord rec = ref != null ? ref.get() : null;
17466                if (rec == null) {
17467                    weakRefs.add(ref);
17468                    continue;
17469                }
17470                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
17471                    continue;
17472                }
17473                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
17474                if (list == null) {
17475                    list = new ArrayList<>();
17476                    byPackage.put(rec.key.packageName, list);
17477                }
17478                list.add(rec);
17479            }
17480            for (int i = 0; i < byPackage.size(); i++) {
17481                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
17482                printed = true;
17483                pw.print("  * "); pw.print(byPackage.keyAt(i));
17484                pw.print(": "); pw.print(intents.size()); pw.println(" items");
17485                for (int j = 0; j < intents.size(); j++) {
17486                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
17487                    if (dumpAll) {
17488                        intents.get(j).dump(pw, "      ");
17489                    }
17490                }
17491            }
17492            if (weakRefs.size() > 0) {
17493                printed = true;
17494                pw.println("  * WEAK REFS:");
17495                for (int i = 0; i < weakRefs.size(); i++) {
17496                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
17497                }
17498            }
17499        }
17500
17501        if (!printed) {
17502            pw.println("  (nothing)");
17503        }
17504    }
17505
17506    private static final int dumpProcessList(PrintWriter pw,
17507            ActivityManagerService service, List list,
17508            String prefix, String normalLabel, String persistentLabel,
17509            String dumpPackage) {
17510        int numPers = 0;
17511        final int N = list.size()-1;
17512        for (int i=N; i>=0; i--) {
17513            ProcessRecord r = (ProcessRecord)list.get(i);
17514            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17515                continue;
17516            }
17517            pw.println(String.format("%s%s #%2d: %s",
17518                    prefix, (r.persistent ? persistentLabel : normalLabel),
17519                    i, r.toString()));
17520            if (r.persistent) {
17521                numPers++;
17522            }
17523        }
17524        return numPers;
17525    }
17526
17527    private static final ArrayList<Pair<ProcessRecord, Integer>>
17528        sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
17529        ArrayList<Pair<ProcessRecord, Integer>> list
17530                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
17531        for (int i=0; i<origList.size(); i++) {
17532            ProcessRecord r = origList.get(i);
17533            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17534                continue;
17535            }
17536            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
17537        }
17538
17539        Comparator<Pair<ProcessRecord, Integer>> comparator
17540                = new Comparator<Pair<ProcessRecord, Integer>>() {
17541            @Override
17542            public int compare(Pair<ProcessRecord, Integer> object1,
17543                    Pair<ProcessRecord, Integer> object2) {
17544                if (object1.first.setAdj != object2.first.setAdj) {
17545                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
17546                }
17547                if (object1.first.setProcState != object2.first.setProcState) {
17548                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
17549                }
17550                if (object1.second.intValue() != object2.second.intValue()) {
17551                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
17552                }
17553                return 0;
17554            }
17555        };
17556
17557        Collections.sort(list, comparator);
17558        return list;
17559    }
17560
17561    private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
17562            ActivityManagerService service, List<ProcessRecord> origList,
17563            boolean inclDetails, String dumpPackage) {
17564        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17565        if (list.isEmpty()) return false;
17566
17567        final long curUptime = SystemClock.uptimeMillis();
17568
17569        for (int i = list.size() - 1; i >= 0; i--) {
17570            ProcessRecord r = list.get(i).first;
17571            long token = proto.start(fieldId);
17572            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17573            proto.write(ProcessOomProto.PERSISTENT, r.persistent);
17574            proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
17575            proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
17576            int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
17577            switch (r.setSchedGroup) {
17578                case ProcessList.SCHED_GROUP_BACKGROUND:
17579                    schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
17580                    break;
17581                case ProcessList.SCHED_GROUP_DEFAULT:
17582                    schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
17583                    break;
17584                case ProcessList.SCHED_GROUP_TOP_APP:
17585                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
17586                    break;
17587                case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
17588                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
17589                    break;
17590            }
17591            if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
17592                proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
17593            }
17594            if (r.foregroundActivities) {
17595                proto.write(ProcessOomProto.ACTIVITIES, true);
17596            } else if (r.foregroundServices) {
17597                proto.write(ProcessOomProto.SERVICES, true);
17598            }
17599            proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
17600            proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
17601            r.writeToProto(proto, ProcessOomProto.PROC);
17602            proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
17603            if (r.adjSource != null || r.adjTarget != null) {
17604                if (r.adjTarget instanceof  ComponentName) {
17605                    ComponentName cn = (ComponentName) r.adjTarget;
17606                    cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
17607                } else if (r.adjTarget != null) {
17608                    proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
17609                }
17610                if (r.adjSource instanceof ProcessRecord) {
17611                    ProcessRecord p = (ProcessRecord) r.adjSource;
17612                    p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
17613                } else if (r.adjSource != null) {
17614                    proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
17615                }
17616            }
17617            if (inclDetails) {
17618                long detailToken = proto.start(ProcessOomProto.DETAIL);
17619                proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
17620                proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
17621                proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
17622                proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
17623                proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
17624                proto.write(ProcessOomProto.Detail.CURRENT_STATE,
17625                        ProcessList.makeProcStateProtoEnum(r.curProcState));
17626                proto.write(ProcessOomProto.Detail.SET_STATE,
17627                        ProcessList.makeProcStateProtoEnum(r.setProcState));
17628                proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
17629                        r.lastPss*1024, new StringBuilder()));
17630                proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
17631                        r.lastSwapPss*1024, new StringBuilder()));
17632                proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
17633                        r.lastCachedPss*1024, new StringBuilder()));
17634                proto.write(ProcessOomProto.Detail.CACHED, r.cached);
17635                proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
17636                proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
17637
17638                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
17639                    if (r.lastCpuTime != 0) {
17640                        long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17641                        long timeUsed = r.curCpuTime - r.lastCpuTime;
17642                        long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
17643                        proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
17644                        proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
17645                        proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
17646                                (100.0*timeUsed)/uptimeSince);
17647                        proto.end(cpuTimeToken);
17648                    }
17649                }
17650                proto.end(detailToken);
17651            }
17652            proto.end(token);
17653        }
17654
17655        return true;
17656    }
17657
17658    private static final boolean dumpProcessOomList(PrintWriter pw,
17659            ActivityManagerService service, List<ProcessRecord> origList,
17660            String prefix, String normalLabel, String persistentLabel,
17661            boolean inclDetails, String dumpPackage) {
17662
17663        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17664        if (list.isEmpty()) return false;
17665
17666        final long curUptime = SystemClock.uptimeMillis();
17667        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17668
17669        for (int i=list.size()-1; i>=0; i--) {
17670            ProcessRecord r = list.get(i).first;
17671            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17672            char schedGroup;
17673            switch (r.setSchedGroup) {
17674                case ProcessList.SCHED_GROUP_BACKGROUND:
17675                    schedGroup = 'B';
17676                    break;
17677                case ProcessList.SCHED_GROUP_DEFAULT:
17678                    schedGroup = 'F';
17679                    break;
17680                case ProcessList.SCHED_GROUP_TOP_APP:
17681                    schedGroup = 'T';
17682                    break;
17683                default:
17684                    schedGroup = '?';
17685                    break;
17686            }
17687            char foreground;
17688            if (r.foregroundActivities) {
17689                foreground = 'A';
17690            } else if (r.foregroundServices) {
17691                foreground = 'S';
17692            } else {
17693                foreground = ' ';
17694            }
17695            String procState = ProcessList.makeProcStateString(r.curProcState);
17696            pw.print(prefix);
17697            pw.print(r.persistent ? persistentLabel : normalLabel);
17698            pw.print(" #");
17699            int num = (origList.size()-1)-list.get(i).second;
17700            if (num < 10) pw.print(' ');
17701            pw.print(num);
17702            pw.print(": ");
17703            pw.print(oomAdj);
17704            pw.print(' ');
17705            pw.print(schedGroup);
17706            pw.print('/');
17707            pw.print(foreground);
17708            pw.print('/');
17709            pw.print(procState);
17710            pw.print(" trm:");
17711            if (r.trimMemoryLevel < 10) pw.print(' ');
17712            pw.print(r.trimMemoryLevel);
17713            pw.print(' ');
17714            pw.print(r.toShortString());
17715            pw.print(" (");
17716            pw.print(r.adjType);
17717            pw.println(')');
17718            if (r.adjSource != null || r.adjTarget != null) {
17719                pw.print(prefix);
17720                pw.print("    ");
17721                if (r.adjTarget instanceof ComponentName) {
17722                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
17723                } else if (r.adjTarget != null) {
17724                    pw.print(r.adjTarget.toString());
17725                } else {
17726                    pw.print("{null}");
17727                }
17728                pw.print("<=");
17729                if (r.adjSource instanceof ProcessRecord) {
17730                    pw.print("Proc{");
17731                    pw.print(((ProcessRecord)r.adjSource).toShortString());
17732                    pw.println("}");
17733                } else if (r.adjSource != null) {
17734                    pw.println(r.adjSource.toString());
17735                } else {
17736                    pw.println("{null}");
17737                }
17738            }
17739            if (inclDetails) {
17740                pw.print(prefix);
17741                pw.print("    ");
17742                pw.print("oom: max="); pw.print(r.maxAdj);
17743                pw.print(" curRaw="); pw.print(r.curRawAdj);
17744                pw.print(" setRaw="); pw.print(r.setRawAdj);
17745                pw.print(" cur="); pw.print(r.curAdj);
17746                pw.print(" set="); pw.println(r.setAdj);
17747                pw.print(prefix);
17748                pw.print("    ");
17749                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
17750                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
17751                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
17752                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
17753                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
17754                pw.println();
17755                pw.print(prefix);
17756                pw.print("    ");
17757                pw.print("cached="); pw.print(r.cached);
17758                pw.print(" empty="); pw.print(r.empty);
17759                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
17760
17761                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
17762                    if (r.lastCpuTime != 0) {
17763                        long timeUsed = r.curCpuTime - r.lastCpuTime;
17764                        pw.print(prefix);
17765                        pw.print("    ");
17766                        pw.print("run cpu over ");
17767                        TimeUtils.formatDuration(uptimeSince, pw);
17768                        pw.print(" used ");
17769                        TimeUtils.formatDuration(timeUsed, pw);
17770                        pw.print(" (");
17771                        pw.print((timeUsed*100)/uptimeSince);
17772                        pw.println("%)");
17773                    }
17774                }
17775            }
17776        }
17777        return true;
17778    }
17779
17780    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
17781            String[] args) {
17782        ArrayList<ProcessRecord> procs;
17783        synchronized (this) {
17784            if (args != null && args.length > start
17785                    && args[start].charAt(0) != '-') {
17786                procs = new ArrayList<ProcessRecord>();
17787                int pid = -1;
17788                try {
17789                    pid = Integer.parseInt(args[start]);
17790                } catch (NumberFormatException e) {
17791                }
17792                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17793                    ProcessRecord proc = mLruProcesses.get(i);
17794                    if (proc.pid > 0 && proc.pid == pid) {
17795                        procs.add(proc);
17796                    } else if (allPkgs && proc.pkgList != null
17797                            && proc.pkgList.containsKey(args[start])) {
17798                        procs.add(proc);
17799                    } else if (proc.processName.equals(args[start])) {
17800                        procs.add(proc);
17801                    }
17802                }
17803                if (procs.size() <= 0) {
17804                    return null;
17805                }
17806            } else {
17807                procs = new ArrayList<ProcessRecord>(mLruProcesses);
17808            }
17809        }
17810        return procs;
17811    }
17812
17813    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
17814            PrintWriter pw, String[] args) {
17815        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
17816        if (procs == null) {
17817            pw.println("No process found for: " + args[0]);
17818            return;
17819        }
17820
17821        long uptime = SystemClock.uptimeMillis();
17822        long realtime = SystemClock.elapsedRealtime();
17823        pw.println("Applications Graphics Acceleration Info:");
17824        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17825
17826        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17827            ProcessRecord r = procs.get(i);
17828            if (r.thread != null) {
17829                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
17830                pw.flush();
17831                try {
17832                    TransferPipe tp = new TransferPipe();
17833                    try {
17834                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
17835                        tp.go(fd);
17836                    } finally {
17837                        tp.kill();
17838                    }
17839                } catch (IOException e) {
17840                    pw.println("Failure while dumping the app: " + r);
17841                    pw.flush();
17842                } catch (RemoteException e) {
17843                    pw.println("Got a RemoteException while dumping the app " + r);
17844                    pw.flush();
17845                }
17846            }
17847        }
17848    }
17849
17850    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
17851        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
17852        if (procs == null) {
17853            pw.println("No process found for: " + args[0]);
17854            return;
17855        }
17856
17857        pw.println("Applications Database Info:");
17858
17859        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17860            ProcessRecord r = procs.get(i);
17861            if (r.thread != null) {
17862                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
17863                pw.flush();
17864                try {
17865                    TransferPipe tp = new TransferPipe();
17866                    try {
17867                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
17868                        tp.go(fd);
17869                    } finally {
17870                        tp.kill();
17871                    }
17872                } catch (IOException e) {
17873                    pw.println("Failure while dumping the app: " + r);
17874                    pw.flush();
17875                } catch (RemoteException e) {
17876                    pw.println("Got a RemoteException while dumping the app " + r);
17877                    pw.flush();
17878                }
17879            }
17880        }
17881    }
17882
17883    final static class MemItem {
17884        final boolean isProc;
17885        final String label;
17886        final String shortLabel;
17887        final long pss;
17888        final long swapPss;
17889        final int id;
17890        final boolean hasActivities;
17891        ArrayList<MemItem> subitems;
17892
17893        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
17894                boolean _hasActivities) {
17895            isProc = true;
17896            label = _label;
17897            shortLabel = _shortLabel;
17898            pss = _pss;
17899            swapPss = _swapPss;
17900            id = _id;
17901            hasActivities = _hasActivities;
17902        }
17903
17904        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
17905            isProc = false;
17906            label = _label;
17907            shortLabel = _shortLabel;
17908            pss = _pss;
17909            swapPss = _swapPss;
17910            id = _id;
17911            hasActivities = false;
17912        }
17913    }
17914
17915    private static void sortMemItems(List<MemItem> items) {
17916        Collections.sort(items, new Comparator<MemItem>() {
17917            @Override
17918            public int compare(MemItem lhs, MemItem rhs) {
17919                if (lhs.pss < rhs.pss) {
17920                    return 1;
17921                } else if (lhs.pss > rhs.pss) {
17922                    return -1;
17923                }
17924                return 0;
17925            }
17926        });
17927    }
17928
17929    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
17930            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
17931        if (sort && !isCompact) {
17932            sortMemItems(items);
17933        }
17934
17935        for (int i=0; i<items.size(); i++) {
17936            MemItem mi = items.get(i);
17937            if (!isCompact) {
17938                if (dumpSwapPss) {
17939                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
17940                            mi.label, stringifyKBSize(mi.swapPss));
17941                } else {
17942                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
17943                }
17944            } else if (mi.isProc) {
17945                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
17946                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
17947                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
17948                pw.println(mi.hasActivities ? ",a" : ",e");
17949            } else {
17950                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
17951                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
17952            }
17953            if (mi.subitems != null) {
17954                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
17955                        true, isCompact, dumpSwapPss);
17956            }
17957        }
17958    }
17959
17960    static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
17961            ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
17962        if (sort) {
17963            sortMemItems(items);
17964        }
17965
17966        for (int i=0; i<items.size(); i++) {
17967            MemItem mi = items.get(i);
17968            final long token = proto.start(fieldId);
17969
17970            proto.write(MemInfoProto.MemItem.TAG, tag);
17971            proto.write(MemInfoProto.MemItem.LABEL, mi.shortLabel);
17972            proto.write(MemInfoProto.MemItem.IS_PROC, mi.isProc);
17973            proto.write(MemInfoProto.MemItem.ID, mi.id);
17974            proto.write(MemInfoProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
17975            proto.write(MemInfoProto.MemItem.PSS_KB, mi.pss);
17976            if (dumpSwapPss) {
17977                proto.write(MemInfoProto.MemItem.SWAP_PSS_KB, mi.swapPss);
17978            }
17979            if (mi.subitems != null) {
17980                dumpMemItems(proto, MemInfoProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
17981                        true, dumpSwapPss);
17982            }
17983            proto.end(token);
17984        }
17985    }
17986
17987    // These are in KB.
17988    static final long[] DUMP_MEM_BUCKETS = new long[] {
17989        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
17990        120*1024, 160*1024, 200*1024,
17991        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
17992        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
17993    };
17994
17995    static final void appendMemBucket(StringBuilder out, long memKB, String label,
17996            boolean stackLike) {
17997        int start = label.lastIndexOf('.');
17998        if (start >= 0) start++;
17999        else start = 0;
18000        int end = label.length();
18001        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
18002            if (DUMP_MEM_BUCKETS[i] >= memKB) {
18003                long bucket = DUMP_MEM_BUCKETS[i]/1024;
18004                out.append(bucket);
18005                out.append(stackLike ? "MB." : "MB ");
18006                out.append(label, start, end);
18007                return;
18008            }
18009        }
18010        out.append(memKB/1024);
18011        out.append(stackLike ? "MB." : "MB ");
18012        out.append(label, start, end);
18013    }
18014
18015    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
18016            ProcessList.NATIVE_ADJ,
18017            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
18018            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
18019            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
18020            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
18021            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
18022            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
18023    };
18024    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
18025            "Native",
18026            "System", "Persistent", "Persistent Service", "Foreground",
18027            "Visible", "Perceptible",
18028            "Heavy Weight", "Backup",
18029            "A Services", "Home",
18030            "Previous", "B Services", "Cached"
18031    };
18032    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
18033            "native",
18034            "sys", "pers", "persvc", "fore",
18035            "vis", "percept",
18036            "heavy", "backup",
18037            "servicea", "home",
18038            "prev", "serviceb", "cached"
18039    };
18040
18041    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
18042            long realtime, boolean isCheckinRequest, boolean isCompact) {
18043        if (isCompact) {
18044            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
18045        }
18046        if (isCheckinRequest || isCompact) {
18047            // short checkin version
18048            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
18049        } else {
18050            pw.println("Applications Memory Usage (in Kilobytes):");
18051            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18052        }
18053    }
18054
18055    private static final int KSM_SHARED = 0;
18056    private static final int KSM_SHARING = 1;
18057    private static final int KSM_UNSHARED = 2;
18058    private static final int KSM_VOLATILE = 3;
18059
18060    private final long[] getKsmInfo() {
18061        long[] longOut = new long[4];
18062        final int[] SINGLE_LONG_FORMAT = new int[] {
18063            PROC_SPACE_TERM| PROC_OUT_LONG
18064        };
18065        long[] longTmp = new long[1];
18066        readProcFile("/sys/kernel/mm/ksm/pages_shared",
18067                SINGLE_LONG_FORMAT, null, longTmp, null);
18068        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18069        longTmp[0] = 0;
18070        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
18071                SINGLE_LONG_FORMAT, null, longTmp, null);
18072        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18073        longTmp[0] = 0;
18074        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
18075                SINGLE_LONG_FORMAT, null, longTmp, null);
18076        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18077        longTmp[0] = 0;
18078        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
18079                SINGLE_LONG_FORMAT, null, longTmp, null);
18080        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18081        return longOut;
18082    }
18083
18084    private static String stringifySize(long size, int order) {
18085        Locale locale = Locale.US;
18086        switch (order) {
18087            case 1:
18088                return String.format(locale, "%,13d", size);
18089            case 1024:
18090                return String.format(locale, "%,9dK", size / 1024);
18091            case 1024 * 1024:
18092                return String.format(locale, "%,5dM", size / 1024 / 1024);
18093            case 1024 * 1024 * 1024:
18094                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
18095            default:
18096                throw new IllegalArgumentException("Invalid size order");
18097        }
18098    }
18099
18100    private static String stringifyKBSize(long size) {
18101        return stringifySize(size * 1024, 1024);
18102    }
18103
18104    // Update this version number if you change the 'compact' format.
18105    private static final int MEMINFO_COMPACT_VERSION = 1;
18106
18107    private static class MemoryUsageDumpOptions {
18108        boolean dumpDetails;
18109        boolean dumpFullDetails;
18110        boolean dumpDalvik;
18111        boolean dumpSummaryOnly;
18112        boolean dumpUnreachable;
18113        boolean oomOnly;
18114        boolean isCompact;
18115        boolean localOnly;
18116        boolean packages;
18117        boolean isCheckinRequest;
18118        boolean dumpSwapPss;
18119        boolean dumpProto;
18120    }
18121
18122    final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18123            String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
18124        MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
18125        opts.dumpDetails = false;
18126        opts.dumpFullDetails = false;
18127        opts.dumpDalvik = false;
18128        opts.dumpSummaryOnly = false;
18129        opts.dumpUnreachable = false;
18130        opts.oomOnly = false;
18131        opts.isCompact = false;
18132        opts.localOnly = false;
18133        opts.packages = false;
18134        opts.isCheckinRequest = false;
18135        opts.dumpSwapPss = false;
18136        opts.dumpProto = asProto;
18137
18138        int opti = 0;
18139        while (opti < args.length) {
18140            String opt = args[opti];
18141            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18142                break;
18143            }
18144            opti++;
18145            if ("-a".equals(opt)) {
18146                opts.dumpDetails = true;
18147                opts.dumpFullDetails = true;
18148                opts.dumpDalvik = true;
18149                opts.dumpSwapPss = true;
18150            } else if ("-d".equals(opt)) {
18151                opts.dumpDalvik = true;
18152            } else if ("-c".equals(opt)) {
18153                opts.isCompact = true;
18154            } else if ("-s".equals(opt)) {
18155                opts.dumpDetails = true;
18156                opts.dumpSummaryOnly = true;
18157            } else if ("-S".equals(opt)) {
18158                opts.dumpSwapPss = true;
18159            } else if ("--unreachable".equals(opt)) {
18160                opts.dumpUnreachable = true;
18161            } else if ("--oom".equals(opt)) {
18162                opts.oomOnly = true;
18163            } else if ("--local".equals(opt)) {
18164                opts.localOnly = true;
18165            } else if ("--package".equals(opt)) {
18166                opts.packages = true;
18167            } else if ("--checkin".equals(opt)) {
18168                opts.isCheckinRequest = true;
18169            } else if ("--proto".equals(opt)) {
18170                opts.dumpProto = true;
18171
18172            } else if ("-h".equals(opt)) {
18173                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
18174                pw.println("  -a: include all available information for each process.");
18175                pw.println("  -d: include dalvik details.");
18176                pw.println("  -c: dump in a compact machine-parseable representation.");
18177                pw.println("  -s: dump only summary of application memory usage.");
18178                pw.println("  -S: dump also SwapPss.");
18179                pw.println("  --oom: only show processes organized by oom adj.");
18180                pw.println("  --local: only collect details locally, don't call process.");
18181                pw.println("  --package: interpret process arg as package, dumping all");
18182                pw.println("             processes that have loaded that package.");
18183                pw.println("  --checkin: dump data for a checkin");
18184                pw.println("  --proto: dump data to proto");
18185                pw.println("If [process] is specified it can be the name or ");
18186                pw.println("pid of a specific process to dump.");
18187                return;
18188            } else {
18189                pw.println("Unknown argument: " + opt + "; use -h for help");
18190            }
18191        }
18192
18193        String[] innerArgs = new String[args.length-opti];
18194        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18195
18196        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18197        if (opts.dumpProto) {
18198            dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18199        } else {
18200            dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
18201        }
18202    }
18203
18204    private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18205            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18206            ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
18207        long uptime = SystemClock.uptimeMillis();
18208        long realtime = SystemClock.elapsedRealtime();
18209        final long[] tmpLong = new long[1];
18210
18211        if (procs == null) {
18212            // No Java processes.  Maybe they want to print a native process.
18213            String proc = "N/A";
18214            if (innerArgs.length > 0) {
18215                proc = innerArgs[0];
18216                if (proc.charAt(0) != '-') {
18217                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18218                            = new ArrayList<ProcessCpuTracker.Stats>();
18219                    updateCpuStatsNow();
18220                    int findPid = -1;
18221                    try {
18222                        findPid = Integer.parseInt(innerArgs[0]);
18223                    } catch (NumberFormatException e) {
18224                    }
18225                    synchronized (mProcessCpuTracker) {
18226                        final int N = mProcessCpuTracker.countStats();
18227                        for (int i=0; i<N; i++) {
18228                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18229                            if (st.pid == findPid || (st.baseName != null
18230                                    && st.baseName.equals(innerArgs[0]))) {
18231                                nativeProcs.add(st);
18232                            }
18233                        }
18234                    }
18235                    if (nativeProcs.size() > 0) {
18236                        dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
18237                                opts.isCheckinRequest, opts.isCompact);
18238                        Debug.MemoryInfo mi = null;
18239                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18240                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18241                            final int pid = r.pid;
18242                            if (!opts.isCheckinRequest && opts.dumpDetails) {
18243                                pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
18244                            }
18245                            if (mi == null) {
18246                                mi = new Debug.MemoryInfo();
18247                            }
18248                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18249                                Debug.getMemoryInfo(pid, mi);
18250                            } else {
18251                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18252                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18253                            }
18254                            ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
18255                                    opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18256                                    pid, r.baseName, 0, 0, 0, 0, 0, 0);
18257                            if (opts.isCheckinRequest) {
18258                                pw.println();
18259                            }
18260                        }
18261                        return;
18262                    }
18263                }
18264            }
18265            pw.println("No process found for: " + proc);
18266            return;
18267        }
18268
18269        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18270            opts.dumpDetails = true;
18271        }
18272
18273        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
18274
18275        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18276        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18277        long nativePss = 0;
18278        long nativeSwapPss = 0;
18279        long dalvikPss = 0;
18280        long dalvikSwapPss = 0;
18281        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18282                EmptyArray.LONG;
18283        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18284                EmptyArray.LONG;
18285        long otherPss = 0;
18286        long otherSwapPss = 0;
18287        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18288        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18289
18290        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18291        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18292        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18293                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18294
18295        long totalPss = 0;
18296        long totalSwapPss = 0;
18297        long cachedPss = 0;
18298        long cachedSwapPss = 0;
18299        boolean hasSwapPss = false;
18300
18301        Debug.MemoryInfo mi = null;
18302        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18303            final ProcessRecord r = procs.get(i);
18304            final IApplicationThread thread;
18305            final int pid;
18306            final int oomAdj;
18307            final boolean hasActivities;
18308            synchronized (this) {
18309                thread = r.thread;
18310                pid = r.pid;
18311                oomAdj = r.getSetAdjWithServices();
18312                hasActivities = r.activities.size() > 0;
18313            }
18314            if (thread != null) {
18315                if (!opts.isCheckinRequest && opts.dumpDetails) {
18316                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
18317                }
18318                if (mi == null) {
18319                    mi = new Debug.MemoryInfo();
18320                }
18321                final int reportType;
18322                final long startTime;
18323                final long endTime;
18324                if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18325                    reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18326                    startTime = SystemClock.currentThreadTimeMillis();
18327                    Debug.getMemoryInfo(pid, mi);
18328                    endTime = SystemClock.currentThreadTimeMillis();
18329                    hasSwapPss = mi.hasSwappedOutPss;
18330                } else {
18331                    reportType = ProcessStats.ADD_PSS_EXTERNAL;
18332                    startTime = SystemClock.currentThreadTimeMillis();
18333                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18334                    endTime = SystemClock.currentThreadTimeMillis();
18335                    mi.dalvikPrivateDirty = (int)tmpLong[0];
18336                }
18337                if (opts.dumpDetails) {
18338                    if (opts.localOnly) {
18339                        ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
18340                                opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
18341                        if (opts.isCheckinRequest) {
18342                            pw.println();
18343                        }
18344                    } else {
18345                        pw.flush();
18346                        try {
18347                            TransferPipe tp = new TransferPipe();
18348                            try {
18349                                thread.dumpMemInfo(tp.getWriteFd(),
18350                                        mi, opts.isCheckinRequest, opts.dumpFullDetails,
18351                                        opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
18352                                tp.go(fd);
18353                            } finally {
18354                                tp.kill();
18355                            }
18356                        } catch (IOException e) {
18357                            if (!opts.isCheckinRequest) {
18358                                pw.println("Got IoException! " + e);
18359                                pw.flush();
18360                            }
18361                        } catch (RemoteException e) {
18362                            if (!opts.isCheckinRequest) {
18363                                pw.println("Got RemoteException! " + e);
18364                                pw.flush();
18365                            }
18366                        }
18367                    }
18368                }
18369
18370                final long myTotalPss = mi.getTotalPss();
18371                final long myTotalUss = mi.getTotalUss();
18372                final long myTotalRss = mi.getTotalRss();
18373                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18374
18375                synchronized (this) {
18376                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18377                        // Record this for posterity if the process has been stable.
18378                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
18379                                reportType, endTime-startTime, r.pkgList);
18380                    }
18381                }
18382
18383                if (!opts.isCheckinRequest && mi != null) {
18384                    totalPss += myTotalPss;
18385                    totalSwapPss += myTotalSwapPss;
18386                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
18387                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
18388                            myTotalSwapPss, pid, hasActivities);
18389                    procMems.add(pssItem);
18390                    procMemsMap.put(pid, pssItem);
18391
18392                    nativePss += mi.nativePss;
18393                    nativeSwapPss += mi.nativeSwappedOutPss;
18394                    dalvikPss += mi.dalvikPss;
18395                    dalvikSwapPss += mi.dalvikSwappedOutPss;
18396                    for (int j=0; j<dalvikSubitemPss.length; j++) {
18397                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18398                        dalvikSubitemSwapPss[j] +=
18399                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18400                    }
18401                    otherPss += mi.otherPss;
18402                    otherSwapPss += mi.otherSwappedOutPss;
18403                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18404                        long mem = mi.getOtherPss(j);
18405                        miscPss[j] += mem;
18406                        otherPss -= mem;
18407                        mem = mi.getOtherSwappedOutPss(j);
18408                        miscSwapPss[j] += mem;
18409                        otherSwapPss -= mem;
18410                    }
18411
18412                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18413                        cachedPss += myTotalPss;
18414                        cachedSwapPss += myTotalSwapPss;
18415                    }
18416
18417                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
18418                        if (oomIndex == (oomPss.length - 1)
18419                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
18420                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
18421                            oomPss[oomIndex] += myTotalPss;
18422                            oomSwapPss[oomIndex] += myTotalSwapPss;
18423                            if (oomProcs[oomIndex] == null) {
18424                                oomProcs[oomIndex] = new ArrayList<MemItem>();
18425                            }
18426                            oomProcs[oomIndex].add(pssItem);
18427                            break;
18428                        }
18429                    }
18430                }
18431            }
18432        }
18433
18434        long nativeProcTotalPss = 0;
18435
18436        if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
18437            // If we are showing aggregations, also look for native processes to
18438            // include so that our aggregations are more accurate.
18439            updateCpuStatsNow();
18440            mi = null;
18441            synchronized (mProcessCpuTracker) {
18442                final int N = mProcessCpuTracker.countStats();
18443                for (int i=0; i<N; i++) {
18444                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18445                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
18446                        if (mi == null) {
18447                            mi = new Debug.MemoryInfo();
18448                        }
18449                        if (!brief && !opts.oomOnly) {
18450                            Debug.getMemoryInfo(st.pid, mi);
18451                        } else {
18452                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
18453                            mi.nativePrivateDirty = (int)tmpLong[0];
18454                        }
18455
18456                        final long myTotalPss = mi.getTotalPss();
18457                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18458                        totalPss += myTotalPss;
18459                        nativeProcTotalPss += myTotalPss;
18460
18461                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
18462                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
18463                        procMems.add(pssItem);
18464
18465                        nativePss += mi.nativePss;
18466                        nativeSwapPss += mi.nativeSwappedOutPss;
18467                        dalvikPss += mi.dalvikPss;
18468                        dalvikSwapPss += mi.dalvikSwappedOutPss;
18469                        for (int j=0; j<dalvikSubitemPss.length; j++) {
18470                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18471                            dalvikSubitemSwapPss[j] +=
18472                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18473                        }
18474                        otherPss += mi.otherPss;
18475                        otherSwapPss += mi.otherSwappedOutPss;
18476                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18477                            long mem = mi.getOtherPss(j);
18478                            miscPss[j] += mem;
18479                            otherPss -= mem;
18480                            mem = mi.getOtherSwappedOutPss(j);
18481                            miscSwapPss[j] += mem;
18482                            otherSwapPss -= mem;
18483                        }
18484                        oomPss[0] += myTotalPss;
18485                        oomSwapPss[0] += myTotalSwapPss;
18486                        if (oomProcs[0] == null) {
18487                            oomProcs[0] = new ArrayList<MemItem>();
18488                        }
18489                        oomProcs[0].add(pssItem);
18490                    }
18491                }
18492            }
18493
18494            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
18495
18496            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
18497            final int dalvikId = -2;
18498            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
18499            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
18500            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18501                String label = Debug.MemoryInfo.getOtherLabel(j);
18502                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
18503            }
18504            if (dalvikSubitemPss.length > 0) {
18505                // Add dalvik subitems.
18506                for (MemItem memItem : catMems) {
18507                    int memItemStart = 0, memItemEnd = 0;
18508                    if (memItem.id == dalvikId) {
18509                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
18510                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
18511                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
18512                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
18513                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
18514                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
18515                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
18516                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
18517                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
18518                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
18519                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
18520                    } else {
18521                        continue;  // No subitems, continue.
18522                    }
18523                    memItem.subitems = new ArrayList<MemItem>();
18524                    for (int j=memItemStart; j<=memItemEnd; j++) {
18525                        final String name = Debug.MemoryInfo.getOtherLabel(
18526                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
18527                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
18528                                dalvikSubitemSwapPss[j], j));
18529                    }
18530                }
18531            }
18532
18533            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
18534            for (int j=0; j<oomPss.length; j++) {
18535                if (oomPss[j] != 0) {
18536                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
18537                            : DUMP_MEM_OOM_LABEL[j];
18538                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
18539                            DUMP_MEM_OOM_ADJ[j]);
18540                    item.subitems = oomProcs[j];
18541                    oomMems.add(item);
18542                }
18543            }
18544
18545            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
18546            if (!brief && !opts.oomOnly && !opts.isCompact) {
18547                pw.println();
18548                pw.println("Total PSS by process:");
18549                dumpMemItems(pw, "  ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
18550                pw.println();
18551            }
18552            if (!opts.isCompact) {
18553                pw.println("Total PSS by OOM adjustment:");
18554            }
18555            dumpMemItems(pw, "  ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
18556            if (!brief && !opts.oomOnly) {
18557                PrintWriter out = categoryPw != null ? categoryPw : pw;
18558                if (!opts.isCompact) {
18559                    out.println();
18560                    out.println("Total PSS by category:");
18561                }
18562                dumpMemItems(out, "  ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
18563            }
18564            if (!opts.isCompact) {
18565                pw.println();
18566            }
18567            MemInfoReader memInfo = new MemInfoReader();
18568            memInfo.readMemInfo();
18569            if (nativeProcTotalPss > 0) {
18570                synchronized (this) {
18571                    final long cachedKb = memInfo.getCachedSizeKb();
18572                    final long freeKb = memInfo.getFreeSizeKb();
18573                    final long zramKb = memInfo.getZramTotalSizeKb();
18574                    final long kernelKb = memInfo.getKernelUsedSizeKb();
18575                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
18576                            kernelKb*1024, nativeProcTotalPss*1024);
18577                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
18578                            nativeProcTotalPss);
18579                }
18580            }
18581            if (!brief) {
18582                if (!opts.isCompact) {
18583                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
18584                    pw.print(" (status ");
18585                    switch (mLastMemoryLevel) {
18586                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
18587                            pw.println("normal)");
18588                            break;
18589                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
18590                            pw.println("moderate)");
18591                            break;
18592                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
18593                            pw.println("low)");
18594                            break;
18595                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18596                            pw.println("critical)");
18597                            break;
18598                        default:
18599                            pw.print(mLastMemoryLevel);
18600                            pw.println(")");
18601                            break;
18602                    }
18603                    pw.print(" Free RAM: ");
18604                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
18605                            + memInfo.getFreeSizeKb()));
18606                    pw.print(" (");
18607                    pw.print(stringifyKBSize(cachedPss));
18608                    pw.print(" cached pss + ");
18609                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
18610                    pw.print(" cached kernel + ");
18611                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
18612                    pw.println(" free)");
18613                } else {
18614                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
18615                    pw.print(cachedPss + memInfo.getCachedSizeKb()
18616                            + memInfo.getFreeSizeKb()); pw.print(",");
18617                    pw.println(totalPss - cachedPss);
18618                }
18619            }
18620            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
18621                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
18622                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
18623            if (!opts.isCompact) {
18624                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
18625                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
18626                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
18627                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
18628                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
18629            } else {
18630                pw.print("lostram,"); pw.println(lostRAM);
18631            }
18632            if (!brief) {
18633                if (memInfo.getZramTotalSizeKb() != 0) {
18634                    if (!opts.isCompact) {
18635                        pw.print("     ZRAM: ");
18636                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
18637                                pw.print(" physical used for ");
18638                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
18639                                        - memInfo.getSwapFreeSizeKb()));
18640                                pw.print(" in swap (");
18641                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
18642                                pw.println(" total swap)");
18643                    } else {
18644                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
18645                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
18646                                pw.println(memInfo.getSwapFreeSizeKb());
18647                    }
18648                }
18649                final long[] ksm = getKsmInfo();
18650                if (!opts.isCompact) {
18651                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
18652                            || ksm[KSM_VOLATILE] != 0) {
18653                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
18654                                pw.print(" saved from shared ");
18655                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
18656                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
18657                                pw.print(" unshared; ");
18658                                pw.print(stringifyKBSize(
18659                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
18660                    }
18661                    pw.print("   Tuning: ");
18662                    pw.print(ActivityManager.staticGetMemoryClass());
18663                    pw.print(" (large ");
18664                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18665                    pw.print("), oom ");
18666                    pw.print(stringifySize(
18667                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
18668                    pw.print(", restore limit ");
18669                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
18670                    if (ActivityManager.isLowRamDeviceStatic()) {
18671                        pw.print(" (low-ram)");
18672                    }
18673                    if (ActivityManager.isHighEndGfx()) {
18674                        pw.print(" (high-end-gfx)");
18675                    }
18676                    pw.println();
18677                } else {
18678                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
18679                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
18680                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
18681                    pw.print("tuning,");
18682                    pw.print(ActivityManager.staticGetMemoryClass());
18683                    pw.print(',');
18684                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18685                    pw.print(',');
18686                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
18687                    if (ActivityManager.isLowRamDeviceStatic()) {
18688                        pw.print(",low-ram");
18689                    }
18690                    if (ActivityManager.isHighEndGfx()) {
18691                        pw.print(",high-end-gfx");
18692                    }
18693                    pw.println();
18694                }
18695            }
18696        }
18697    }
18698
18699    private final void dumpApplicationMemoryUsage(FileDescriptor fd,
18700            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18701            ArrayList<ProcessRecord> procs) {
18702        final long uptimeMs = SystemClock.uptimeMillis();
18703        final long realtimeMs = SystemClock.elapsedRealtime();
18704        final long[] tmpLong = new long[1];
18705
18706        if (procs == null) {
18707            // No Java processes.  Maybe they want to print a native process.
18708            String proc = "N/A";
18709            if (innerArgs.length > 0) {
18710                proc = innerArgs[0];
18711                if (proc.charAt(0) != '-') {
18712                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18713                            = new ArrayList<ProcessCpuTracker.Stats>();
18714                    updateCpuStatsNow();
18715                    int findPid = -1;
18716                    try {
18717                        findPid = Integer.parseInt(innerArgs[0]);
18718                    } catch (NumberFormatException e) {
18719                    }
18720                    synchronized (mProcessCpuTracker) {
18721                        final int N = mProcessCpuTracker.countStats();
18722                        for (int i=0; i<N; i++) {
18723                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18724                            if (st.pid == findPid || (st.baseName != null
18725                                    && st.baseName.equals(innerArgs[0]))) {
18726                                nativeProcs.add(st);
18727                            }
18728                        }
18729                    }
18730                    if (nativeProcs.size() > 0) {
18731                        ProtoOutputStream proto = new ProtoOutputStream(fd);
18732
18733                        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
18734                        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
18735                        Debug.MemoryInfo mi = null;
18736                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18737                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18738                            final int pid = r.pid;
18739                            final long nToken = proto.start(MemInfoProto.NATIVE_PROCESSES);
18740
18741                            proto.write(MemInfoProto.ProcessMemory.PID, pid);
18742                            proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.baseName);
18743
18744                            if (mi == null) {
18745                                mi = new Debug.MemoryInfo();
18746                            }
18747                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18748                                Debug.getMemoryInfo(pid, mi);
18749                            } else {
18750                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18751                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18752                            }
18753                            ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
18754                                    opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
18755
18756                            proto.end(nToken);
18757                        }
18758
18759                        proto.flush();
18760                        return;
18761                    }
18762                }
18763            }
18764            Log.d(TAG, "No process found for: " + innerArgs[0]);
18765            return;
18766        }
18767
18768        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18769            opts.dumpDetails = true;
18770        }
18771
18772        ProtoOutputStream proto = new ProtoOutputStream(fd);
18773
18774        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
18775        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
18776
18777        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18778        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18779        long nativePss = 0;
18780        long nativeSwapPss = 0;
18781        long dalvikPss = 0;
18782        long dalvikSwapPss = 0;
18783        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18784                EmptyArray.LONG;
18785        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18786                EmptyArray.LONG;
18787        long otherPss = 0;
18788        long otherSwapPss = 0;
18789        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18790        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18791
18792        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18793        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18794        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18795                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18796
18797        long totalPss = 0;
18798        long totalSwapPss = 0;
18799        long cachedPss = 0;
18800        long cachedSwapPss = 0;
18801        boolean hasSwapPss = false;
18802
18803        Debug.MemoryInfo mi = null;
18804        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18805            final ProcessRecord r = procs.get(i);
18806            final IApplicationThread thread;
18807            final int pid;
18808            final int oomAdj;
18809            final boolean hasActivities;
18810            synchronized (this) {
18811                thread = r.thread;
18812                pid = r.pid;
18813                oomAdj = r.getSetAdjWithServices();
18814                hasActivities = r.activities.size() > 0;
18815            }
18816            if (thread == null) {
18817                continue;
18818            }
18819            if (mi == null) {
18820                mi = new Debug.MemoryInfo();
18821            }
18822            final int reportType;
18823            final long startTime;
18824            final long endTime;
18825            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18826                reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18827                startTime = SystemClock.currentThreadTimeMillis();
18828                Debug.getMemoryInfo(pid, mi);
18829                endTime = SystemClock.currentThreadTimeMillis();
18830                hasSwapPss = mi.hasSwappedOutPss;
18831            } else {
18832                reportType = ProcessStats.ADD_PSS_EXTERNAL;
18833                startTime = SystemClock.currentThreadTimeMillis();
18834                mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
18835                endTime = SystemClock.currentThreadTimeMillis();
18836                mi.dalvikPrivateDirty = (int) tmpLong[0];
18837            }
18838            if (opts.dumpDetails) {
18839                if (opts.localOnly) {
18840                    final long aToken = proto.start(MemInfoProto.APP_PROCESSES);
18841                    final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
18842                    proto.write(MemInfoProto.ProcessMemory.PID, pid);
18843                    proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.processName);
18844                    ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
18845                            opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
18846                    proto.end(mToken);
18847                    proto.end(aToken);
18848                } else {
18849                    try {
18850                        ByteTransferPipe tp = new ByteTransferPipe();
18851                        try {
18852                            thread.dumpMemInfoProto(tp.getWriteFd(),
18853                                mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18854                                opts.dumpUnreachable, innerArgs);
18855                            proto.write(MemInfoProto.APP_PROCESSES, tp.get());
18856                        } finally {
18857                            tp.kill();
18858                        }
18859                    } catch (IOException e) {
18860                        Log.e(TAG, "Got IOException!", e);
18861                    } catch (RemoteException e) {
18862                        Log.e(TAG, "Got RemoteException!", e);
18863                    }
18864                }
18865            }
18866
18867            final long myTotalPss = mi.getTotalPss();
18868            final long myTotalUss = mi.getTotalUss();
18869            final long myTotalRss = mi.getTotalRss();
18870            final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18871
18872            synchronized (this) {
18873                if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18874                    // Record this for posterity if the process has been stable.
18875                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
18876                            reportType, endTime-startTime, r.pkgList);
18877                }
18878            }
18879
18880            if (!opts.isCheckinRequest && mi != null) {
18881                totalPss += myTotalPss;
18882                totalSwapPss += myTotalSwapPss;
18883                MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
18884                        (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
18885                        myTotalSwapPss, pid, hasActivities);
18886                procMems.add(pssItem);
18887                procMemsMap.put(pid, pssItem);
18888
18889                nativePss += mi.nativePss;
18890                nativeSwapPss += mi.nativeSwappedOutPss;
18891                dalvikPss += mi.dalvikPss;
18892                dalvikSwapPss += mi.dalvikSwappedOutPss;
18893                for (int j=0; j<dalvikSubitemPss.length; j++) {
18894                    dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18895                    dalvikSubitemSwapPss[j] +=
18896                            mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18897                }
18898                otherPss += mi.otherPss;
18899                otherSwapPss += mi.otherSwappedOutPss;
18900                for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18901                    long mem = mi.getOtherPss(j);
18902                    miscPss[j] += mem;
18903                    otherPss -= mem;
18904                    mem = mi.getOtherSwappedOutPss(j);
18905                    miscSwapPss[j] += mem;
18906                    otherSwapPss -= mem;
18907                }
18908
18909                if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18910                    cachedPss += myTotalPss;
18911                    cachedSwapPss += myTotalSwapPss;
18912                }
18913
18914                for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
18915                    if (oomIndex == (oomPss.length - 1)
18916                            || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
18917                                    && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
18918                        oomPss[oomIndex] += myTotalPss;
18919                        oomSwapPss[oomIndex] += myTotalSwapPss;
18920                        if (oomProcs[oomIndex] == null) {
18921                            oomProcs[oomIndex] = new ArrayList<MemItem>();
18922                        }
18923                        oomProcs[oomIndex].add(pssItem);
18924                        break;
18925                    }
18926                }
18927            }
18928        }
18929
18930        long nativeProcTotalPss = 0;
18931
18932        if (procs.size() > 1 && !opts.packages) {
18933            // If we are showing aggregations, also look for native processes to
18934            // include so that our aggregations are more accurate.
18935            updateCpuStatsNow();
18936            mi = null;
18937            synchronized (mProcessCpuTracker) {
18938                final int N = mProcessCpuTracker.countStats();
18939                for (int i=0; i<N; i++) {
18940                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18941                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
18942                        if (mi == null) {
18943                            mi = new Debug.MemoryInfo();
18944                        }
18945                        if (!brief && !opts.oomOnly) {
18946                            Debug.getMemoryInfo(st.pid, mi);
18947                        } else {
18948                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
18949                            mi.nativePrivateDirty = (int)tmpLong[0];
18950                        }
18951
18952                        final long myTotalPss = mi.getTotalPss();
18953                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18954                        totalPss += myTotalPss;
18955                        nativeProcTotalPss += myTotalPss;
18956
18957                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
18958                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
18959                        procMems.add(pssItem);
18960
18961                        nativePss += mi.nativePss;
18962                        nativeSwapPss += mi.nativeSwappedOutPss;
18963                        dalvikPss += mi.dalvikPss;
18964                        dalvikSwapPss += mi.dalvikSwappedOutPss;
18965                        for (int j=0; j<dalvikSubitemPss.length; j++) {
18966                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18967                            dalvikSubitemSwapPss[j] +=
18968                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18969                        }
18970                        otherPss += mi.otherPss;
18971                        otherSwapPss += mi.otherSwappedOutPss;
18972                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18973                            long mem = mi.getOtherPss(j);
18974                            miscPss[j] += mem;
18975                            otherPss -= mem;
18976                            mem = mi.getOtherSwappedOutPss(j);
18977                            miscSwapPss[j] += mem;
18978                            otherSwapPss -= mem;
18979                        }
18980                        oomPss[0] += myTotalPss;
18981                        oomSwapPss[0] += myTotalSwapPss;
18982                        if (oomProcs[0] == null) {
18983                            oomProcs[0] = new ArrayList<MemItem>();
18984                        }
18985                        oomProcs[0].add(pssItem);
18986                    }
18987                }
18988            }
18989
18990            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
18991
18992            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
18993            final int dalvikId = -2;
18994            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
18995            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
18996            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18997                String label = Debug.MemoryInfo.getOtherLabel(j);
18998                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
18999            }
19000            if (dalvikSubitemPss.length > 0) {
19001                // Add dalvik subitems.
19002                for (MemItem memItem : catMems) {
19003                    int memItemStart = 0, memItemEnd = 0;
19004                    if (memItem.id == dalvikId) {
19005                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19006                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19007                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19008                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19009                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19010                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19011                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19012                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19013                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19014                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19015                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19016                    } else {
19017                        continue;  // No subitems, continue.
19018                    }
19019                    memItem.subitems = new ArrayList<MemItem>();
19020                    for (int j=memItemStart; j<=memItemEnd; j++) {
19021                        final String name = Debug.MemoryInfo.getOtherLabel(
19022                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
19023                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19024                                dalvikSubitemSwapPss[j], j));
19025                    }
19026                }
19027            }
19028
19029            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19030            for (int j=0; j<oomPss.length; j++) {
19031                if (oomPss[j] != 0) {
19032                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19033                            : DUMP_MEM_OOM_LABEL[j];
19034                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19035                            DUMP_MEM_OOM_ADJ[j]);
19036                    item.subitems = oomProcs[j];
19037                    oomMems.add(item);
19038                }
19039            }
19040
19041            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19042            if (!opts.oomOnly) {
19043                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_PROCESS, "proc",
19044                        procMems, true, opts.dumpSwapPss);
19045            }
19046            dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
19047                    oomMems, false, opts.dumpSwapPss);
19048            if (!brief && !opts.oomOnly) {
19049                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_CATEGORY, "cat",
19050                        catMems, true, opts.dumpSwapPss);
19051            }
19052            MemInfoReader memInfo = new MemInfoReader();
19053            memInfo.readMemInfo();
19054            if (nativeProcTotalPss > 0) {
19055                synchronized (this) {
19056                    final long cachedKb = memInfo.getCachedSizeKb();
19057                    final long freeKb = memInfo.getFreeSizeKb();
19058                    final long zramKb = memInfo.getZramTotalSizeKb();
19059                    final long kernelKb = memInfo.getKernelUsedSizeKb();
19060                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19061                            kernelKb*1024, nativeProcTotalPss*1024);
19062                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19063                            nativeProcTotalPss);
19064                }
19065            }
19066            if (!brief) {
19067                proto.write(MemInfoProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
19068                proto.write(MemInfoProto.STATUS, mLastMemoryLevel);
19069                proto.write(MemInfoProto.CACHED_PSS_KB, cachedPss);
19070                proto.write(MemInfoProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
19071                proto.write(MemInfoProto.FREE_KB, memInfo.getFreeSizeKb());
19072            }
19073            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19074                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19075                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19076            proto.write(MemInfoProto.USED_PSS_KB, totalPss - cachedPss);
19077            proto.write(MemInfoProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
19078            proto.write(MemInfoProto.LOST_RAM_KB, lostRAM);
19079            if (!brief) {
19080                if (memInfo.getZramTotalSizeKb() != 0) {
19081                    proto.write(MemInfoProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
19082                    proto.write(MemInfoProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
19083                            memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
19084                    proto.write(MemInfoProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
19085                }
19086                final long[] ksm = getKsmInfo();
19087                proto.write(MemInfoProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
19088                proto.write(MemInfoProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
19089                proto.write(MemInfoProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
19090                proto.write(MemInfoProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
19091
19092                proto.write(MemInfoProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
19093                proto.write(MemInfoProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
19094                proto.write(MemInfoProto.OOM_KB,
19095                        mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
19096                proto.write(MemInfoProto.RESTORE_LIMIT_KB,
19097                        mProcessList.getCachedRestoreThresholdKb());
19098
19099                proto.write(MemInfoProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
19100                proto.write(MemInfoProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
19101            }
19102        }
19103
19104        proto.flush();
19105    }
19106
19107    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
19108            long memtrack, String name) {
19109        sb.append("  ");
19110        sb.append(ProcessList.makeOomAdjString(oomAdj));
19111        sb.append(' ');
19112        sb.append(ProcessList.makeProcStateString(procState));
19113        sb.append(' ');
19114        ProcessList.appendRamKb(sb, pss);
19115        sb.append(": ");
19116        sb.append(name);
19117        if (memtrack > 0) {
19118            sb.append(" (");
19119            sb.append(stringifyKBSize(memtrack));
19120            sb.append(" memtrack)");
19121        }
19122    }
19123
19124    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
19125        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
19126        sb.append(" (pid ");
19127        sb.append(mi.pid);
19128        sb.append(") ");
19129        sb.append(mi.adjType);
19130        sb.append('\n');
19131        if (mi.adjReason != null) {
19132            sb.append("                      ");
19133            sb.append(mi.adjReason);
19134            sb.append('\n');
19135        }
19136    }
19137
19138    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
19139        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
19140        for (int i=0, N=memInfos.size(); i<N; i++) {
19141            ProcessMemInfo mi = memInfos.get(i);
19142            infoMap.put(mi.pid, mi);
19143        }
19144        updateCpuStatsNow();
19145        long[] memtrackTmp = new long[1];
19146        final List<ProcessCpuTracker.Stats> stats;
19147        // Get a list of Stats that have vsize > 0
19148        synchronized (mProcessCpuTracker) {
19149            stats = mProcessCpuTracker.getStats((st) -> {
19150                return st.vsize > 0;
19151            });
19152        }
19153        final int statsCount = stats.size();
19154        for (int i = 0; i < statsCount; i++) {
19155            ProcessCpuTracker.Stats st = stats.get(i);
19156            long pss = Debug.getPss(st.pid, null, memtrackTmp);
19157            if (pss > 0) {
19158                if (infoMap.indexOfKey(st.pid) < 0) {
19159                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19160                            ProcessList.NATIVE_ADJ, -1, "native", null);
19161                    mi.pss = pss;
19162                    mi.memtrack = memtrackTmp[0];
19163                    memInfos.add(mi);
19164                }
19165            }
19166        }
19167
19168        long totalPss = 0;
19169        long totalMemtrack = 0;
19170        for (int i=0, N=memInfos.size(); i<N; i++) {
19171            ProcessMemInfo mi = memInfos.get(i);
19172            if (mi.pss == 0) {
19173                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19174                mi.memtrack = memtrackTmp[0];
19175            }
19176            totalPss += mi.pss;
19177            totalMemtrack += mi.memtrack;
19178        }
19179        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
19180            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
19181                if (lhs.oomAdj != rhs.oomAdj) {
19182                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
19183                }
19184                if (lhs.pss != rhs.pss) {
19185                    return lhs.pss < rhs.pss ? 1 : -1;
19186                }
19187                return 0;
19188            }
19189        });
19190
19191        StringBuilder tag = new StringBuilder(128);
19192        StringBuilder stack = new StringBuilder(128);
19193        tag.append("Low on memory -- ");
19194        appendMemBucket(tag, totalPss, "total", false);
19195        appendMemBucket(stack, totalPss, "total", true);
19196
19197        StringBuilder fullNativeBuilder = new StringBuilder(1024);
19198        StringBuilder shortNativeBuilder = new StringBuilder(1024);
19199        StringBuilder fullJavaBuilder = new StringBuilder(1024);
19200
19201        boolean firstLine = true;
19202        int lastOomAdj = Integer.MIN_VALUE;
19203        long extraNativeRam = 0;
19204        long extraNativeMemtrack = 0;
19205        long cachedPss = 0;
19206        for (int i=0, N=memInfos.size(); i<N; i++) {
19207            ProcessMemInfo mi = memInfos.get(i);
19208
19209            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19210                cachedPss += mi.pss;
19211            }
19212
19213            if (mi.oomAdj != ProcessList.NATIVE_ADJ
19214                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
19215                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
19216                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
19217                if (lastOomAdj != mi.oomAdj) {
19218                    lastOomAdj = mi.oomAdj;
19219                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19220                        tag.append(" / ");
19221                    }
19222                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19223                        if (firstLine) {
19224                            stack.append(":");
19225                            firstLine = false;
19226                        }
19227                        stack.append("\n\t at ");
19228                    } else {
19229                        stack.append("$");
19230                    }
19231                } else {
19232                    tag.append(" ");
19233                    stack.append("$");
19234                }
19235                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19236                    appendMemBucket(tag, mi.pss, mi.name, false);
19237                }
19238                appendMemBucket(stack, mi.pss, mi.name, true);
19239                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
19240                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
19241                    stack.append("(");
19242                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
19243                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
19244                            stack.append(DUMP_MEM_OOM_LABEL[k]);
19245                            stack.append(":");
19246                            stack.append(DUMP_MEM_OOM_ADJ[k]);
19247                        }
19248                    }
19249                    stack.append(")");
19250                }
19251            }
19252
19253            appendMemInfo(fullNativeBuilder, mi);
19254            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
19255                // The short form only has native processes that are >= 512K.
19256                if (mi.pss >= 512) {
19257                    appendMemInfo(shortNativeBuilder, mi);
19258                } else {
19259                    extraNativeRam += mi.pss;
19260                    extraNativeMemtrack += mi.memtrack;
19261                }
19262            } else {
19263                // Short form has all other details, but if we have collected RAM
19264                // from smaller native processes let's dump a summary of that.
19265                if (extraNativeRam > 0) {
19266                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
19267                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
19268                    shortNativeBuilder.append('\n');
19269                    extraNativeRam = 0;
19270                }
19271                appendMemInfo(fullJavaBuilder, mi);
19272            }
19273        }
19274
19275        fullJavaBuilder.append("           ");
19276        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
19277        fullJavaBuilder.append(": TOTAL");
19278        if (totalMemtrack > 0) {
19279            fullJavaBuilder.append(" (");
19280            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
19281            fullJavaBuilder.append(" memtrack)");
19282        } else {
19283        }
19284        fullJavaBuilder.append("\n");
19285
19286        MemInfoReader memInfo = new MemInfoReader();
19287        memInfo.readMemInfo();
19288        final long[] infos = memInfo.getRawInfo();
19289
19290        StringBuilder memInfoBuilder = new StringBuilder(1024);
19291        Debug.getMemInfo(infos);
19292        memInfoBuilder.append("  MemInfo: ");
19293        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
19294        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
19295        memInfoBuilder.append(stringifyKBSize(
19296                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
19297        memInfoBuilder.append(stringifyKBSize(
19298                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
19299        memInfoBuilder.append(stringifyKBSize(
19300                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
19301        memInfoBuilder.append("           ");
19302        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
19303        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
19304        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
19305        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
19306        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
19307            memInfoBuilder.append("  ZRAM: ");
19308            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
19309            memInfoBuilder.append(" RAM, ");
19310            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
19311            memInfoBuilder.append(" swap total, ");
19312            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
19313            memInfoBuilder.append(" swap free\n");
19314        }
19315        final long[] ksm = getKsmInfo();
19316        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19317                || ksm[KSM_VOLATILE] != 0) {
19318            memInfoBuilder.append("  KSM: ");
19319            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
19320            memInfoBuilder.append(" saved from shared ");
19321            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
19322            memInfoBuilder.append("\n       ");
19323            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
19324            memInfoBuilder.append(" unshared; ");
19325            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
19326            memInfoBuilder.append(" volatile\n");
19327        }
19328        memInfoBuilder.append("  Free RAM: ");
19329        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19330                + memInfo.getFreeSizeKb()));
19331        memInfoBuilder.append("\n");
19332        memInfoBuilder.append("  Used RAM: ");
19333        memInfoBuilder.append(stringifyKBSize(
19334                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
19335        memInfoBuilder.append("\n");
19336        memInfoBuilder.append("  Lost RAM: ");
19337        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
19338                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19339                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
19340        memInfoBuilder.append("\n");
19341        Slog.i(TAG, "Low on memory:");
19342        Slog.i(TAG, shortNativeBuilder.toString());
19343        Slog.i(TAG, fullJavaBuilder.toString());
19344        Slog.i(TAG, memInfoBuilder.toString());
19345
19346        StringBuilder dropBuilder = new StringBuilder(1024);
19347        /*
19348        StringWriter oomSw = new StringWriter();
19349        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
19350        StringWriter catSw = new StringWriter();
19351        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19352        String[] emptyArgs = new String[] { };
19353        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
19354        oomPw.flush();
19355        String oomString = oomSw.toString();
19356        */
19357        dropBuilder.append("Low on memory:");
19358        dropBuilder.append(stack);
19359        dropBuilder.append('\n');
19360        dropBuilder.append(fullNativeBuilder);
19361        dropBuilder.append(fullJavaBuilder);
19362        dropBuilder.append('\n');
19363        dropBuilder.append(memInfoBuilder);
19364        dropBuilder.append('\n');
19365        /*
19366        dropBuilder.append(oomString);
19367        dropBuilder.append('\n');
19368        */
19369        StringWriter catSw = new StringWriter();
19370        synchronized (ActivityManagerService.this) {
19371            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19372            String[] emptyArgs = new String[] { };
19373            catPw.println();
19374            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
19375            catPw.println();
19376            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
19377                    false, null).dumpLocked();
19378            catPw.println();
19379            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
19380            catPw.flush();
19381        }
19382        dropBuilder.append(catSw.toString());
19383        addErrorToDropBox("lowmem", null, "system_server", null,
19384                null, tag.toString(), dropBuilder.toString(), null, null);
19385        //Slog.i(TAG, "Sent to dropbox:");
19386        //Slog.i(TAG, dropBuilder.toString());
19387        synchronized (ActivityManagerService.this) {
19388            long now = SystemClock.uptimeMillis();
19389            if (mLastMemUsageReportTime < now) {
19390                mLastMemUsageReportTime = now;
19391            }
19392        }
19393    }
19394
19395    /**
19396     * Searches array of arguments for the specified string
19397     * @param args array of argument strings
19398     * @param value value to search for
19399     * @return true if the value is contained in the array
19400     */
19401    private static boolean scanArgs(String[] args, String value) {
19402        if (args != null) {
19403            for (String arg : args) {
19404                if (value.equals(arg)) {
19405                    return true;
19406                }
19407            }
19408        }
19409        return false;
19410    }
19411
19412    private final boolean removeDyingProviderLocked(ProcessRecord proc,
19413            ContentProviderRecord cpr, boolean always) {
19414        final boolean inLaunching = mLaunchingProviders.contains(cpr);
19415
19416        if (!inLaunching || always) {
19417            synchronized (cpr) {
19418                cpr.launchingApp = null;
19419                cpr.notifyAll();
19420            }
19421            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
19422            String names[] = cpr.info.authority.split(";");
19423            for (int j = 0; j < names.length; j++) {
19424                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
19425            }
19426        }
19427
19428        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
19429            ContentProviderConnection conn = cpr.connections.get(i);
19430            if (conn.waiting) {
19431                // If this connection is waiting for the provider, then we don't
19432                // need to mess with its process unless we are always removing
19433                // or for some reason the provider is not currently launching.
19434                if (inLaunching && !always) {
19435                    continue;
19436                }
19437            }
19438            ProcessRecord capp = conn.client;
19439            conn.dead = true;
19440            if (conn.stableCount > 0) {
19441                if (!capp.persistent && capp.thread != null
19442                        && capp.pid != 0
19443                        && capp.pid != MY_PID) {
19444                    capp.kill("depends on provider "
19445                            + cpr.name.flattenToShortString()
19446                            + " in dying proc " + (proc != null ? proc.processName : "??")
19447                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
19448                }
19449            } else if (capp.thread != null && conn.provider.provider != null) {
19450                try {
19451                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
19452                } catch (RemoteException e) {
19453                }
19454                // In the protocol here, we don't expect the client to correctly
19455                // clean up this connection, we'll just remove it.
19456                cpr.connections.remove(i);
19457                if (conn.client.conProviders.remove(conn)) {
19458                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
19459                }
19460            }
19461        }
19462
19463        if (inLaunching && always) {
19464            mLaunchingProviders.remove(cpr);
19465        }
19466        return inLaunching;
19467    }
19468
19469    /**
19470     * Main code for cleaning up a process when it has gone away.  This is
19471     * called both as a result of the process dying, or directly when stopping
19472     * a process when running in single process mode.
19473     *
19474     * @return Returns true if the given process has been restarted, so the
19475     * app that was passed in must remain on the process lists.
19476     */
19477    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
19478            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
19479        if (index >= 0) {
19480            removeLruProcessLocked(app);
19481            ProcessList.remove(app.pid);
19482        }
19483
19484        mProcessesToGc.remove(app);
19485        mPendingPssProcesses.remove(app);
19486
19487        // Dismiss any open dialogs.
19488        if (app.crashDialog != null && !app.forceCrashReport) {
19489            app.crashDialog.dismiss();
19490            app.crashDialog = null;
19491        }
19492        if (app.anrDialog != null) {
19493            app.anrDialog.dismiss();
19494            app.anrDialog = null;
19495        }
19496        if (app.waitDialog != null) {
19497            app.waitDialog.dismiss();
19498            app.waitDialog = null;
19499        }
19500
19501        app.crashing = false;
19502        app.notResponding = false;
19503
19504        app.resetPackageList(mProcessStats);
19505        app.unlinkDeathRecipient();
19506        app.makeInactive(mProcessStats);
19507        app.waitingToKill = null;
19508        app.forcingToImportant = null;
19509        updateProcessForegroundLocked(app, false, false);
19510        app.foregroundActivities = false;
19511        app.hasShownUi = false;
19512        app.treatLikeActivity = false;
19513        app.hasAboveClient = false;
19514        app.hasClientActivities = false;
19515
19516        mServices.killServicesLocked(app, allowRestart);
19517
19518        boolean restart = false;
19519
19520        // Remove published content providers.
19521        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
19522            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
19523            final boolean always = app.bad || !allowRestart;
19524            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
19525            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
19526                // We left the provider in the launching list, need to
19527                // restart it.
19528                restart = true;
19529            }
19530
19531            cpr.provider = null;
19532            cpr.proc = null;
19533        }
19534        app.pubProviders.clear();
19535
19536        // Take care of any launching providers waiting for this process.
19537        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
19538            restart = true;
19539        }
19540
19541        // Unregister from connected content providers.
19542        if (!app.conProviders.isEmpty()) {
19543            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
19544                ContentProviderConnection conn = app.conProviders.get(i);
19545                conn.provider.connections.remove(conn);
19546                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
19547                        conn.provider.name);
19548            }
19549            app.conProviders.clear();
19550        }
19551
19552        // At this point there may be remaining entries in mLaunchingProviders
19553        // where we were the only one waiting, so they are no longer of use.
19554        // Look for these and clean up if found.
19555        // XXX Commented out for now.  Trying to figure out a way to reproduce
19556        // the actual situation to identify what is actually going on.
19557        if (false) {
19558            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19559                ContentProviderRecord cpr = mLaunchingProviders.get(i);
19560                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
19561                    synchronized (cpr) {
19562                        cpr.launchingApp = null;
19563                        cpr.notifyAll();
19564                    }
19565                }
19566            }
19567        }
19568
19569        skipCurrentReceiverLocked(app);
19570
19571        // Unregister any receivers.
19572        for (int i = app.receivers.size() - 1; i >= 0; i--) {
19573            removeReceiverLocked(app.receivers.valueAt(i));
19574        }
19575        app.receivers.clear();
19576
19577        // If the app is undergoing backup, tell the backup manager about it
19578        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
19579            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
19580                    + mBackupTarget.appInfo + " died during backup");
19581            mHandler.post(new Runnable() {
19582                @Override
19583                public void run(){
19584                    try {
19585                        IBackupManager bm = IBackupManager.Stub.asInterface(
19586                                ServiceManager.getService(Context.BACKUP_SERVICE));
19587                        bm.agentDisconnected(app.info.packageName);
19588                    } catch (RemoteException e) {
19589                        // can't happen; backup manager is local
19590                    }
19591                }
19592            });
19593        }
19594
19595        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
19596            ProcessChangeItem item = mPendingProcessChanges.get(i);
19597            if (app.pid > 0 && item.pid == app.pid) {
19598                mPendingProcessChanges.remove(i);
19599                mAvailProcessChanges.add(item);
19600            }
19601        }
19602        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
19603                null).sendToTarget();
19604
19605        // If the caller is restarting this app, then leave it in its
19606        // current lists and let the caller take care of it.
19607        if (restarting) {
19608            return false;
19609        }
19610
19611        if (!app.persistent || app.isolated) {
19612            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
19613                    "Removing non-persistent process during cleanup: " + app);
19614            if (!replacingPid) {
19615                removeProcessNameLocked(app.processName, app.uid, app);
19616            }
19617            if (mHeavyWeightProcess == app) {
19618                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
19619                        mHeavyWeightProcess.userId, 0));
19620                mHeavyWeightProcess = null;
19621            }
19622        } else if (!app.removed) {
19623            // This app is persistent, so we need to keep its record around.
19624            // If it is not already on the pending app list, add it there
19625            // and start a new process for it.
19626            if (mPersistentStartingProcesses.indexOf(app) < 0) {
19627                mPersistentStartingProcesses.add(app);
19628                restart = true;
19629            }
19630        }
19631        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
19632                TAG_CLEANUP, "Clean-up removing on hold: " + app);
19633        mProcessesOnHold.remove(app);
19634
19635        if (app == mHomeProcess) {
19636            mHomeProcess = null;
19637        }
19638        if (app == mPreviousProcess) {
19639            mPreviousProcess = null;
19640        }
19641
19642        if (restart && !app.isolated) {
19643            // We have components that still need to be running in the
19644            // process, so re-launch it.
19645            if (index < 0) {
19646                ProcessList.remove(app.pid);
19647            }
19648            addProcessNameLocked(app);
19649            app.pendingStart = false;
19650            startProcessLocked(app, "restart", app.processName);
19651            return true;
19652        } else if (app.pid > 0 && app.pid != MY_PID) {
19653            // Goodbye!
19654            boolean removed;
19655            synchronized (mPidsSelfLocked) {
19656                mPidsSelfLocked.remove(app.pid);
19657                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
19658            }
19659            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
19660            if (app.isolated) {
19661                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
19662            }
19663            app.setPid(0);
19664        }
19665        return false;
19666    }
19667
19668    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
19669        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19670            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19671            if (cpr.launchingApp == app) {
19672                return true;
19673            }
19674        }
19675        return false;
19676    }
19677
19678    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
19679        // Look through the content providers we are waiting to have launched,
19680        // and if any run in this process then either schedule a restart of
19681        // the process or kill the client waiting for it if this process has
19682        // gone bad.
19683        boolean restart = false;
19684        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19685            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19686            if (cpr.launchingApp == app) {
19687                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
19688                    restart = true;
19689                } else {
19690                    removeDyingProviderLocked(app, cpr, true);
19691                }
19692            }
19693        }
19694        return restart;
19695    }
19696
19697    // =========================================================
19698    // SERVICES
19699    // =========================================================
19700
19701    @Override
19702    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
19703        enforceNotIsolatedCaller("getServices");
19704
19705        final int callingUid = Binder.getCallingUid();
19706        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
19707            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
19708        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
19709            callingUid);
19710        synchronized (this) {
19711            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
19712                allowed, canInteractAcrossUsers);
19713        }
19714    }
19715
19716    @Override
19717    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
19718        enforceNotIsolatedCaller("getRunningServiceControlPanel");
19719        synchronized (this) {
19720            return mServices.getRunningServiceControlPanelLocked(name);
19721        }
19722    }
19723
19724    @Override
19725    public ComponentName startService(IApplicationThread caller, Intent service,
19726            String resolvedType, boolean requireForeground, String callingPackage, int userId)
19727            throws TransactionTooLargeException {
19728        enforceNotIsolatedCaller("startService");
19729        // Refuse possible leaked file descriptors
19730        if (service != null && service.hasFileDescriptors() == true) {
19731            throw new IllegalArgumentException("File descriptors passed in Intent");
19732        }
19733
19734        if (callingPackage == null) {
19735            throw new IllegalArgumentException("callingPackage cannot be null");
19736        }
19737
19738        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
19739                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
19740        synchronized(this) {
19741            final int callingPid = Binder.getCallingPid();
19742            final int callingUid = Binder.getCallingUid();
19743            final long origId = Binder.clearCallingIdentity();
19744            ComponentName res;
19745            try {
19746                res = mServices.startServiceLocked(caller, service,
19747                        resolvedType, callingPid, callingUid,
19748                        requireForeground, callingPackage, userId);
19749            } finally {
19750                Binder.restoreCallingIdentity(origId);
19751            }
19752            return res;
19753        }
19754    }
19755
19756    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
19757            boolean fgRequired, String callingPackage, int userId)
19758            throws TransactionTooLargeException {
19759        synchronized(this) {
19760            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
19761                    "startServiceInPackage: " + service + " type=" + resolvedType);
19762            final long origId = Binder.clearCallingIdentity();
19763            ComponentName res;
19764            try {
19765                res = mServices.startServiceLocked(null, service,
19766                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
19767            } finally {
19768                Binder.restoreCallingIdentity(origId);
19769            }
19770            return res;
19771        }
19772    }
19773
19774    @Override
19775    public int stopService(IApplicationThread caller, Intent service,
19776            String resolvedType, int userId) {
19777        enforceNotIsolatedCaller("stopService");
19778        // Refuse possible leaked file descriptors
19779        if (service != null && service.hasFileDescriptors() == true) {
19780            throw new IllegalArgumentException("File descriptors passed in Intent");
19781        }
19782
19783        synchronized(this) {
19784            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
19785        }
19786    }
19787
19788    @Override
19789    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
19790        enforceNotIsolatedCaller("peekService");
19791        // Refuse possible leaked file descriptors
19792        if (service != null && service.hasFileDescriptors() == true) {
19793            throw new IllegalArgumentException("File descriptors passed in Intent");
19794        }
19795
19796        if (callingPackage == null) {
19797            throw new IllegalArgumentException("callingPackage cannot be null");
19798        }
19799
19800        synchronized(this) {
19801            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
19802        }
19803    }
19804
19805    @Override
19806    public boolean stopServiceToken(ComponentName className, IBinder token,
19807            int startId) {
19808        synchronized(this) {
19809            return mServices.stopServiceTokenLocked(className, token, startId);
19810        }
19811    }
19812
19813    @Override
19814    public void setServiceForeground(ComponentName className, IBinder token,
19815            int id, Notification notification, int flags) {
19816        synchronized(this) {
19817            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
19818        }
19819    }
19820
19821    @Override
19822    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
19823            boolean requireFull, String name, String callerPackage) {
19824        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
19825                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
19826    }
19827
19828    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
19829            String className, int flags) {
19830        boolean result = false;
19831        // For apps that don't have pre-defined UIDs, check for permission
19832        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
19833            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
19834                if (ActivityManager.checkUidPermission(
19835                        INTERACT_ACROSS_USERS,
19836                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
19837                    ComponentName comp = new ComponentName(aInfo.packageName, className);
19838                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
19839                            + " requests FLAG_SINGLE_USER, but app does not hold "
19840                            + INTERACT_ACROSS_USERS;
19841                    Slog.w(TAG, msg);
19842                    throw new SecurityException(msg);
19843                }
19844                // Permission passed
19845                result = true;
19846            }
19847        } else if ("system".equals(componentProcessName)) {
19848            result = true;
19849        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
19850            // Phone app and persistent apps are allowed to export singleuser providers.
19851            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
19852                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
19853        }
19854        if (DEBUG_MU) Slog.v(TAG_MU,
19855                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
19856                + Integer.toHexString(flags) + ") = " + result);
19857        return result;
19858    }
19859
19860    /**
19861     * Checks to see if the caller is in the same app as the singleton
19862     * component, or the component is in a special app. It allows special apps
19863     * to export singleton components but prevents exporting singleton
19864     * components for regular apps.
19865     */
19866    boolean isValidSingletonCall(int callingUid, int componentUid) {
19867        int componentAppId = UserHandle.getAppId(componentUid);
19868        return UserHandle.isSameApp(callingUid, componentUid)
19869                || componentAppId == SYSTEM_UID
19870                || componentAppId == PHONE_UID
19871                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
19872                        == PackageManager.PERMISSION_GRANTED;
19873    }
19874
19875    public int bindService(IApplicationThread caller, IBinder token, Intent service,
19876            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
19877            int userId) throws TransactionTooLargeException {
19878        enforceNotIsolatedCaller("bindService");
19879
19880        // Refuse possible leaked file descriptors
19881        if (service != null && service.hasFileDescriptors() == true) {
19882            throw new IllegalArgumentException("File descriptors passed in Intent");
19883        }
19884
19885        if (callingPackage == null) {
19886            throw new IllegalArgumentException("callingPackage cannot be null");
19887        }
19888
19889        synchronized(this) {
19890            return mServices.bindServiceLocked(caller, token, service,
19891                    resolvedType, connection, flags, callingPackage, userId);
19892        }
19893    }
19894
19895    public boolean unbindService(IServiceConnection connection) {
19896        synchronized (this) {
19897            return mServices.unbindServiceLocked(connection);
19898        }
19899    }
19900
19901    public void publishService(IBinder token, Intent intent, IBinder service) {
19902        // Refuse possible leaked file descriptors
19903        if (intent != null && intent.hasFileDescriptors() == true) {
19904            throw new IllegalArgumentException("File descriptors passed in Intent");
19905        }
19906
19907        synchronized(this) {
19908            if (!(token instanceof ServiceRecord)) {
19909                throw new IllegalArgumentException("Invalid service token");
19910            }
19911            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
19912        }
19913    }
19914
19915    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
19916        // Refuse possible leaked file descriptors
19917        if (intent != null && intent.hasFileDescriptors() == true) {
19918            throw new IllegalArgumentException("File descriptors passed in Intent");
19919        }
19920
19921        synchronized(this) {
19922            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
19923        }
19924    }
19925
19926    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
19927        synchronized(this) {
19928            if (!(token instanceof ServiceRecord)) {
19929                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
19930                throw new IllegalArgumentException("Invalid service token");
19931            }
19932            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
19933        }
19934    }
19935
19936    // =========================================================
19937    // BACKUP AND RESTORE
19938    // =========================================================
19939
19940    // Cause the target app to be launched if necessary and its backup agent
19941    // instantiated.  The backup agent will invoke backupAgentCreated() on the
19942    // activity manager to announce its creation.
19943    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
19944        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
19945        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
19946
19947        IPackageManager pm = AppGlobals.getPackageManager();
19948        ApplicationInfo app = null;
19949        try {
19950            app = pm.getApplicationInfo(packageName, 0, userId);
19951        } catch (RemoteException e) {
19952            // can't happen; package manager is process-local
19953        }
19954        if (app == null) {
19955            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
19956            return false;
19957        }
19958
19959        int oldBackupUid;
19960        int newBackupUid;
19961
19962        synchronized(this) {
19963            // !!! TODO: currently no check here that we're already bound
19964            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
19965            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19966            synchronized (stats) {
19967                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
19968            }
19969
19970            // Backup agent is now in use, its package can't be stopped.
19971            try {
19972                AppGlobals.getPackageManager().setPackageStoppedState(
19973                        app.packageName, false, UserHandle.getUserId(app.uid));
19974            } catch (RemoteException e) {
19975            } catch (IllegalArgumentException e) {
19976                Slog.w(TAG, "Failed trying to unstop package "
19977                        + app.packageName + ": " + e);
19978            }
19979
19980            BackupRecord r = new BackupRecord(ss, app, backupMode);
19981            ComponentName hostingName =
19982                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
19983                            ? new ComponentName(app.packageName, app.backupAgentName)
19984                            : new ComponentName("android", "FullBackupAgent");
19985            // startProcessLocked() returns existing proc's record if it's already running
19986            ProcessRecord proc = startProcessLocked(app.processName, app,
19987                    false, 0, "backup", hostingName, false, false, false);
19988            if (proc == null) {
19989                Slog.e(TAG, "Unable to start backup agent process " + r);
19990                return false;
19991            }
19992
19993            // If the app is a regular app (uid >= 10000) and not the system server or phone
19994            // process, etc, then mark it as being in full backup so that certain calls to the
19995            // process can be blocked. This is not reset to false anywhere because we kill the
19996            // process after the full backup is done and the ProcessRecord will vaporize anyway.
19997            if (UserHandle.isApp(app.uid) &&
19998                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
19999                proc.inFullBackup = true;
20000            }
20001            r.app = proc;
20002            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20003            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
20004            mBackupTarget = r;
20005            mBackupAppName = app.packageName;
20006
20007            // Try not to kill the process during backup
20008            updateOomAdjLocked(proc, true);
20009
20010            // If the process is already attached, schedule the creation of the backup agent now.
20011            // If it is not yet live, this will be done when it attaches to the framework.
20012            if (proc.thread != null) {
20013                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
20014                try {
20015                    proc.thread.scheduleCreateBackupAgent(app,
20016                            compatibilityInfoForPackageLocked(app), backupMode);
20017                } catch (RemoteException e) {
20018                    // Will time out on the backup manager side
20019                }
20020            } else {
20021                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
20022            }
20023            // Invariants: at this point, the target app process exists and the application
20024            // is either already running or in the process of coming up.  mBackupTarget and
20025            // mBackupAppName describe the app, so that when it binds back to the AM we
20026            // know that it's scheduled for a backup-agent operation.
20027        }
20028
20029        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20030        if (oldBackupUid != -1) {
20031            js.removeBackingUpUid(oldBackupUid);
20032        }
20033        if (newBackupUid != -1) {
20034            js.addBackingUpUid(newBackupUid);
20035        }
20036
20037        return true;
20038    }
20039
20040    @Override
20041    public void clearPendingBackup() {
20042        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
20043        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
20044
20045        synchronized (this) {
20046            mBackupTarget = null;
20047            mBackupAppName = null;
20048        }
20049
20050        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20051        js.clearAllBackingUpUids();
20052    }
20053
20054    // A backup agent has just come up
20055    public void backupAgentCreated(String agentPackageName, IBinder agent) {
20056        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
20057                + " = " + agent);
20058
20059        synchronized(this) {
20060            if (!agentPackageName.equals(mBackupAppName)) {
20061                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
20062                return;
20063            }
20064        }
20065
20066        long oldIdent = Binder.clearCallingIdentity();
20067        try {
20068            IBackupManager bm = IBackupManager.Stub.asInterface(
20069                    ServiceManager.getService(Context.BACKUP_SERVICE));
20070            bm.agentConnected(agentPackageName, agent);
20071        } catch (RemoteException e) {
20072            // can't happen; the backup manager service is local
20073        } catch (Exception e) {
20074            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
20075            e.printStackTrace();
20076        } finally {
20077            Binder.restoreCallingIdentity(oldIdent);
20078        }
20079    }
20080
20081    // done with this agent
20082    public void unbindBackupAgent(ApplicationInfo appInfo) {
20083        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
20084        if (appInfo == null) {
20085            Slog.w(TAG, "unbind backup agent for null app");
20086            return;
20087        }
20088
20089        int oldBackupUid;
20090
20091        synchronized(this) {
20092            try {
20093                if (mBackupAppName == null) {
20094                    Slog.w(TAG, "Unbinding backup agent with no active backup");
20095                    return;
20096                }
20097
20098                if (!mBackupAppName.equals(appInfo.packageName)) {
20099                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
20100                    return;
20101                }
20102
20103                // Not backing this app up any more; reset its OOM adjustment
20104                final ProcessRecord proc = mBackupTarget.app;
20105                updateOomAdjLocked(proc, true);
20106                proc.inFullBackup = false;
20107
20108                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20109
20110                // If the app crashed during backup, 'thread' will be null here
20111                if (proc.thread != null) {
20112                    try {
20113                        proc.thread.scheduleDestroyBackupAgent(appInfo,
20114                                compatibilityInfoForPackageLocked(appInfo));
20115                    } catch (Exception e) {
20116                        Slog.e(TAG, "Exception when unbinding backup agent:");
20117                        e.printStackTrace();
20118                    }
20119                }
20120            } finally {
20121                mBackupTarget = null;
20122                mBackupAppName = null;
20123            }
20124        }
20125
20126        if (oldBackupUid != -1) {
20127            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20128            js.removeBackingUpUid(oldBackupUid);
20129        }
20130    }
20131
20132    // =========================================================
20133    // BROADCASTS
20134    // =========================================================
20135
20136    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
20137        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
20138            return false;
20139        }
20140        // Easy case -- we have the app's ProcessRecord.
20141        if (record != null) {
20142            return record.info.isInstantApp();
20143        }
20144        // Otherwise check with PackageManager.
20145        if (callerPackage == null) {
20146            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
20147            throw new IllegalArgumentException("Calling application did not provide package name");
20148        }
20149        mAppOpsService.checkPackage(uid, callerPackage);
20150        try {
20151            IPackageManager pm = AppGlobals.getPackageManager();
20152            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
20153        } catch (RemoteException e) {
20154            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
20155            return true;
20156        }
20157    }
20158
20159    boolean isPendingBroadcastProcessLocked(int pid) {
20160        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20161                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
20162    }
20163
20164    void skipPendingBroadcastLocked(int pid) {
20165            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
20166            for (BroadcastQueue queue : mBroadcastQueues) {
20167                queue.skipPendingBroadcastLocked(pid);
20168            }
20169    }
20170
20171    // The app just attached; send any pending broadcasts that it should receive
20172    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
20173        boolean didSomething = false;
20174        for (BroadcastQueue queue : mBroadcastQueues) {
20175            didSomething |= queue.sendPendingBroadcastsLocked(app);
20176        }
20177        return didSomething;
20178    }
20179
20180    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20181            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
20182            int flags) {
20183        enforceNotIsolatedCaller("registerReceiver");
20184        ArrayList<Intent> stickyIntents = null;
20185        ProcessRecord callerApp = null;
20186        final boolean visibleToInstantApps
20187                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
20188        int callingUid;
20189        int callingPid;
20190        boolean instantApp;
20191        synchronized(this) {
20192            if (caller != null) {
20193                callerApp = getRecordForAppLocked(caller);
20194                if (callerApp == null) {
20195                    throw new SecurityException(
20196                            "Unable to find app for caller " + caller
20197                            + " (pid=" + Binder.getCallingPid()
20198                            + ") when registering receiver " + receiver);
20199                }
20200                if (callerApp.info.uid != SYSTEM_UID &&
20201                        !callerApp.pkgList.containsKey(callerPackage) &&
20202                        !"android".equals(callerPackage)) {
20203                    throw new SecurityException("Given caller package " + callerPackage
20204                            + " is not running in process " + callerApp);
20205                }
20206                callingUid = callerApp.info.uid;
20207                callingPid = callerApp.pid;
20208            } else {
20209                callerPackage = null;
20210                callingUid = Binder.getCallingUid();
20211                callingPid = Binder.getCallingPid();
20212            }
20213
20214            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20215            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20216                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
20217
20218            Iterator<String> actions = filter.actionsIterator();
20219            if (actions == null) {
20220                ArrayList<String> noAction = new ArrayList<String>(1);
20221                noAction.add(null);
20222                actions = noAction.iterator();
20223            }
20224
20225            // Collect stickies of users
20226            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
20227            while (actions.hasNext()) {
20228                String action = actions.next();
20229                for (int id : userIds) {
20230                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
20231                    if (stickies != null) {
20232                        ArrayList<Intent> intents = stickies.get(action);
20233                        if (intents != null) {
20234                            if (stickyIntents == null) {
20235                                stickyIntents = new ArrayList<Intent>();
20236                            }
20237                            stickyIntents.addAll(intents);
20238                        }
20239                    }
20240                }
20241            }
20242        }
20243
20244        ArrayList<Intent> allSticky = null;
20245        if (stickyIntents != null) {
20246            final ContentResolver resolver = mContext.getContentResolver();
20247            // Look for any matching sticky broadcasts...
20248            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
20249                Intent intent = stickyIntents.get(i);
20250                // Don't provided intents that aren't available to instant apps.
20251                if (instantApp &&
20252                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
20253                    continue;
20254                }
20255                // If intent has scheme "content", it will need to acccess
20256                // provider that needs to lock mProviderMap in ActivityThread
20257                // and also it may need to wait application response, so we
20258                // cannot lock ActivityManagerService here.
20259                if (filter.match(resolver, intent, true, TAG) >= 0) {
20260                    if (allSticky == null) {
20261                        allSticky = new ArrayList<Intent>();
20262                    }
20263                    allSticky.add(intent);
20264                }
20265            }
20266        }
20267
20268        // The first sticky in the list is returned directly back to the client.
20269        Intent sticky = allSticky != null ? allSticky.get(0) : null;
20270        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
20271        if (receiver == null) {
20272            return sticky;
20273        }
20274
20275        synchronized (this) {
20276            if (callerApp != null && (callerApp.thread == null
20277                    || callerApp.thread.asBinder() != caller.asBinder())) {
20278                // Original caller already died
20279                return null;
20280            }
20281            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20282            if (rl == null) {
20283                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
20284                        userId, receiver);
20285                if (rl.app != null) {
20286                    rl.app.receivers.add(rl);
20287                } else {
20288                    try {
20289                        receiver.asBinder().linkToDeath(rl, 0);
20290                    } catch (RemoteException e) {
20291                        return sticky;
20292                    }
20293                    rl.linkedToDeath = true;
20294                }
20295                mRegisteredReceivers.put(receiver.asBinder(), rl);
20296            } else if (rl.uid != callingUid) {
20297                throw new IllegalArgumentException(
20298                        "Receiver requested to register for uid " + callingUid
20299                        + " was previously registered for uid " + rl.uid
20300                        + " callerPackage is " + callerPackage);
20301            } else if (rl.pid != callingPid) {
20302                throw new IllegalArgumentException(
20303                        "Receiver requested to register for pid " + callingPid
20304                        + " was previously registered for pid " + rl.pid
20305                        + " callerPackage is " + callerPackage);
20306            } else if (rl.userId != userId) {
20307                throw new IllegalArgumentException(
20308                        "Receiver requested to register for user " + userId
20309                        + " was previously registered for user " + rl.userId
20310                        + " callerPackage is " + callerPackage);
20311            }
20312            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
20313                    permission, callingUid, userId, instantApp, visibleToInstantApps);
20314            rl.add(bf);
20315            if (!bf.debugCheck()) {
20316                Slog.w(TAG, "==> For Dynamic broadcast");
20317            }
20318            mReceiverResolver.addFilter(bf);
20319
20320            // Enqueue broadcasts for all existing stickies that match
20321            // this filter.
20322            if (allSticky != null) {
20323                ArrayList receivers = new ArrayList();
20324                receivers.add(bf);
20325
20326                final int stickyCount = allSticky.size();
20327                for (int i = 0; i < stickyCount; i++) {
20328                    Intent intent = allSticky.get(i);
20329                    BroadcastQueue queue = broadcastQueueForIntent(intent);
20330                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
20331                            null, -1, -1, false, null, null, OP_NONE, null, receivers,
20332                            null, 0, null, null, false, true, true, -1);
20333                    queue.enqueueParallelBroadcastLocked(r);
20334                    queue.scheduleBroadcastsLocked();
20335                }
20336            }
20337
20338            return sticky;
20339        }
20340    }
20341
20342    public void unregisterReceiver(IIntentReceiver receiver) {
20343        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
20344
20345        final long origId = Binder.clearCallingIdentity();
20346        try {
20347            boolean doTrim = false;
20348
20349            synchronized(this) {
20350                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20351                if (rl != null) {
20352                    final BroadcastRecord r = rl.curBroadcast;
20353                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
20354                        final boolean doNext = r.queue.finishReceiverLocked(
20355                                r, r.resultCode, r.resultData, r.resultExtras,
20356                                r.resultAbort, false);
20357                        if (doNext) {
20358                            doTrim = true;
20359                            r.queue.processNextBroadcast(false);
20360                        }
20361                    }
20362
20363                    if (rl.app != null) {
20364                        rl.app.receivers.remove(rl);
20365                    }
20366                    removeReceiverLocked(rl);
20367                    if (rl.linkedToDeath) {
20368                        rl.linkedToDeath = false;
20369                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
20370                    }
20371                }
20372            }
20373
20374            // If we actually concluded any broadcasts, we might now be able
20375            // to trim the recipients' apps from our working set
20376            if (doTrim) {
20377                trimApplications();
20378                return;
20379            }
20380
20381        } finally {
20382            Binder.restoreCallingIdentity(origId);
20383        }
20384    }
20385
20386    void removeReceiverLocked(ReceiverList rl) {
20387        mRegisteredReceivers.remove(rl.receiver.asBinder());
20388        for (int i = rl.size() - 1; i >= 0; i--) {
20389            mReceiverResolver.removeFilter(rl.get(i));
20390        }
20391    }
20392
20393    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
20394        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20395            ProcessRecord r = mLruProcesses.get(i);
20396            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
20397                try {
20398                    r.thread.dispatchPackageBroadcast(cmd, packages);
20399                } catch (RemoteException ex) {
20400                }
20401            }
20402        }
20403    }
20404
20405    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
20406            int callingUid, int[] users) {
20407        // TODO: come back and remove this assumption to triage all broadcasts
20408        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
20409
20410        List<ResolveInfo> receivers = null;
20411        try {
20412            HashSet<ComponentName> singleUserReceivers = null;
20413            boolean scannedFirstReceivers = false;
20414            for (int user : users) {
20415                // Skip users that have Shell restrictions, with exception of always permitted
20416                // Shell broadcasts
20417                if (callingUid == SHELL_UID
20418                        && mUserController.hasUserRestriction(
20419                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
20420                        && !isPermittedShellBroadcast(intent)) {
20421                    continue;
20422                }
20423                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
20424                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
20425                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
20426                    // If this is not the system user, we need to check for
20427                    // any receivers that should be filtered out.
20428                    for (int i=0; i<newReceivers.size(); i++) {
20429                        ResolveInfo ri = newReceivers.get(i);
20430                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
20431                            newReceivers.remove(i);
20432                            i--;
20433                        }
20434                    }
20435                }
20436                if (newReceivers != null && newReceivers.size() == 0) {
20437                    newReceivers = null;
20438                }
20439                if (receivers == null) {
20440                    receivers = newReceivers;
20441                } else if (newReceivers != null) {
20442                    // We need to concatenate the additional receivers
20443                    // found with what we have do far.  This would be easy,
20444                    // but we also need to de-dup any receivers that are
20445                    // singleUser.
20446                    if (!scannedFirstReceivers) {
20447                        // Collect any single user receivers we had already retrieved.
20448                        scannedFirstReceivers = true;
20449                        for (int i=0; i<receivers.size(); i++) {
20450                            ResolveInfo ri = receivers.get(i);
20451                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20452                                ComponentName cn = new ComponentName(
20453                                        ri.activityInfo.packageName, ri.activityInfo.name);
20454                                if (singleUserReceivers == null) {
20455                                    singleUserReceivers = new HashSet<ComponentName>();
20456                                }
20457                                singleUserReceivers.add(cn);
20458                            }
20459                        }
20460                    }
20461                    // Add the new results to the existing results, tracking
20462                    // and de-dupping single user receivers.
20463                    for (int i=0; i<newReceivers.size(); i++) {
20464                        ResolveInfo ri = newReceivers.get(i);
20465                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20466                            ComponentName cn = new ComponentName(
20467                                    ri.activityInfo.packageName, ri.activityInfo.name);
20468                            if (singleUserReceivers == null) {
20469                                singleUserReceivers = new HashSet<ComponentName>();
20470                            }
20471                            if (!singleUserReceivers.contains(cn)) {
20472                                singleUserReceivers.add(cn);
20473                                receivers.add(ri);
20474                            }
20475                        } else {
20476                            receivers.add(ri);
20477                        }
20478                    }
20479                }
20480            }
20481        } catch (RemoteException ex) {
20482            // pm is in same process, this will never happen.
20483        }
20484        return receivers;
20485    }
20486
20487    private boolean isPermittedShellBroadcast(Intent intent) {
20488        // remote bugreport should always be allowed to be taken
20489        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
20490    }
20491
20492    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
20493            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
20494        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
20495            // Don't yell about broadcasts sent via shell
20496            return;
20497        }
20498
20499        final String action = intent.getAction();
20500        if (isProtectedBroadcast
20501                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
20502                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
20503                || Intent.ACTION_MEDIA_BUTTON.equals(action)
20504                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
20505                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
20506                || Intent.ACTION_MASTER_CLEAR.equals(action)
20507                || Intent.ACTION_FACTORY_RESET.equals(action)
20508                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20509                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
20510                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
20511                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
20512                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
20513                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
20514                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
20515            // Broadcast is either protected, or it's a public action that
20516            // we've relaxed, so it's fine for system internals to send.
20517            return;
20518        }
20519
20520        // This broadcast may be a problem...  but there are often system components that
20521        // want to send an internal broadcast to themselves, which is annoying to have to
20522        // explicitly list each action as a protected broadcast, so we will check for that
20523        // one safe case and allow it: an explicit broadcast, only being received by something
20524        // that has protected itself.
20525        if (receivers != null && receivers.size() > 0
20526                && (intent.getPackage() != null || intent.getComponent() != null)) {
20527            boolean allProtected = true;
20528            for (int i = receivers.size()-1; i >= 0; i--) {
20529                Object target = receivers.get(i);
20530                if (target instanceof ResolveInfo) {
20531                    ResolveInfo ri = (ResolveInfo)target;
20532                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
20533                        allProtected = false;
20534                        break;
20535                    }
20536                } else {
20537                    BroadcastFilter bf = (BroadcastFilter)target;
20538                    if (bf.requiredPermission == null) {
20539                        allProtected = false;
20540                        break;
20541                    }
20542                }
20543            }
20544            if (allProtected) {
20545                // All safe!
20546                return;
20547            }
20548        }
20549
20550        // The vast majority of broadcasts sent from system internals
20551        // should be protected to avoid security holes, so yell loudly
20552        // to ensure we examine these cases.
20553        if (callerApp != null) {
20554            Log.wtf(TAG, "Sending non-protected broadcast " + action
20555                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
20556                    new Throwable());
20557        } else {
20558            Log.wtf(TAG, "Sending non-protected broadcast " + action
20559                            + " from system uid " + UserHandle.formatUid(callingUid)
20560                            + " pkg " + callerPackage,
20561                    new Throwable());
20562        }
20563    }
20564
20565    final int broadcastIntentLocked(ProcessRecord callerApp,
20566            String callerPackage, Intent intent, String resolvedType,
20567            IIntentReceiver resultTo, int resultCode, String resultData,
20568            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
20569            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
20570        intent = new Intent(intent);
20571
20572        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
20573        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
20574        if (callerInstantApp) {
20575            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20576        }
20577
20578        // By default broadcasts do not go to stopped apps.
20579        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
20580
20581        // If we have not finished booting, don't allow this to launch new processes.
20582        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
20583            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20584        }
20585
20586        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
20587                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
20588                + " ordered=" + ordered + " userid=" + userId);
20589        if ((resultTo != null) && !ordered) {
20590            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
20591        }
20592
20593        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20594                ALLOW_NON_FULL, "broadcast", callerPackage);
20595
20596        // Make sure that the user who is receiving this broadcast or its parent is running.
20597        // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
20598        if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
20599            if ((callingUid != SYSTEM_UID
20600                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
20601                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
20602                Slog.w(TAG, "Skipping broadcast of " + intent
20603                        + ": user " + userId + " and its parent (if any) are stopped");
20604                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
20605            }
20606        }
20607
20608        BroadcastOptions brOptions = null;
20609        if (bOptions != null) {
20610            brOptions = new BroadcastOptions(bOptions);
20611            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
20612                // See if the caller is allowed to do this.  Note we are checking against
20613                // the actual real caller (not whoever provided the operation as say a
20614                // PendingIntent), because that who is actually supplied the arguments.
20615                if (checkComponentPermission(
20616                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
20617                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
20618                        != PackageManager.PERMISSION_GRANTED) {
20619                    String msg = "Permission Denial: " + intent.getAction()
20620                            + " broadcast from " + callerPackage + " (pid=" + callingPid
20621                            + ", uid=" + callingUid + ")"
20622                            + " requires "
20623                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
20624                    Slog.w(TAG, msg);
20625                    throw new SecurityException(msg);
20626                }
20627            }
20628        }
20629
20630        // Verify that protected broadcasts are only being sent by system code,
20631        // and that system code is only sending protected broadcasts.
20632        final String action = intent.getAction();
20633        final boolean isProtectedBroadcast;
20634        try {
20635            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
20636        } catch (RemoteException e) {
20637            Slog.w(TAG, "Remote exception", e);
20638            return ActivityManager.BROADCAST_SUCCESS;
20639        }
20640
20641        final boolean isCallerSystem;
20642        switch (UserHandle.getAppId(callingUid)) {
20643            case ROOT_UID:
20644            case SYSTEM_UID:
20645            case PHONE_UID:
20646            case BLUETOOTH_UID:
20647            case NFC_UID:
20648            case SE_UID:
20649                isCallerSystem = true;
20650                break;
20651            default:
20652                isCallerSystem = (callerApp != null) && callerApp.persistent;
20653                break;
20654        }
20655
20656        // First line security check before anything else: stop non-system apps from
20657        // sending protected broadcasts.
20658        if (!isCallerSystem) {
20659            if (isProtectedBroadcast) {
20660                String msg = "Permission Denial: not allowed to send broadcast "
20661                        + action + " from pid="
20662                        + callingPid + ", uid=" + callingUid;
20663                Slog.w(TAG, msg);
20664                throw new SecurityException(msg);
20665
20666            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20667                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
20668                // Special case for compatibility: we don't want apps to send this,
20669                // but historically it has not been protected and apps may be using it
20670                // to poke their own app widget.  So, instead of making it protected,
20671                // just limit it to the caller.
20672                if (callerPackage == null) {
20673                    String msg = "Permission Denial: not allowed to send broadcast "
20674                            + action + " from unknown caller.";
20675                    Slog.w(TAG, msg);
20676                    throw new SecurityException(msg);
20677                } else if (intent.getComponent() != null) {
20678                    // They are good enough to send to an explicit component...  verify
20679                    // it is being sent to the calling app.
20680                    if (!intent.getComponent().getPackageName().equals(
20681                            callerPackage)) {
20682                        String msg = "Permission Denial: not allowed to send broadcast "
20683                                + action + " to "
20684                                + intent.getComponent().getPackageName() + " from "
20685                                + callerPackage;
20686                        Slog.w(TAG, msg);
20687                        throw new SecurityException(msg);
20688                    }
20689                } else {
20690                    // Limit broadcast to their own package.
20691                    intent.setPackage(callerPackage);
20692                }
20693            }
20694        }
20695
20696        if (action != null) {
20697            if (getBackgroundLaunchBroadcasts().contains(action)) {
20698                if (DEBUG_BACKGROUND_CHECK) {
20699                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
20700                }
20701                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
20702            }
20703
20704            switch (action) {
20705                case Intent.ACTION_UID_REMOVED:
20706                case Intent.ACTION_PACKAGE_REMOVED:
20707                case Intent.ACTION_PACKAGE_CHANGED:
20708                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
20709                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
20710                case Intent.ACTION_PACKAGES_SUSPENDED:
20711                case Intent.ACTION_PACKAGES_UNSUSPENDED:
20712                    // Handle special intents: if this broadcast is from the package
20713                    // manager about a package being removed, we need to remove all of
20714                    // its activities from the history stack.
20715                    if (checkComponentPermission(
20716                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
20717                            callingPid, callingUid, -1, true)
20718                            != PackageManager.PERMISSION_GRANTED) {
20719                        String msg = "Permission Denial: " + intent.getAction()
20720                                + " broadcast from " + callerPackage + " (pid=" + callingPid
20721                                + ", uid=" + callingUid + ")"
20722                                + " requires "
20723                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
20724                        Slog.w(TAG, msg);
20725                        throw new SecurityException(msg);
20726                    }
20727                    switch (action) {
20728                        case Intent.ACTION_UID_REMOVED:
20729                            final int uid = getUidFromIntent(intent);
20730                            if (uid >= 0) {
20731                                mBatteryStatsService.removeUid(uid);
20732                                mAppOpsService.uidRemoved(uid);
20733                            }
20734                            break;
20735                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
20736                            // If resources are unavailable just force stop all those packages
20737                            // and flush the attribute cache as well.
20738                            String list[] =
20739                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
20740                            if (list != null && list.length > 0) {
20741                                for (int i = 0; i < list.length; i++) {
20742                                    forceStopPackageLocked(list[i], -1, false, true, true,
20743                                            false, false, userId, "storage unmount");
20744                                }
20745                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
20746                                sendPackageBroadcastLocked(
20747                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
20748                                        list, userId);
20749                            }
20750                            break;
20751                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
20752                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
20753                            break;
20754                        case Intent.ACTION_PACKAGE_REMOVED:
20755                        case Intent.ACTION_PACKAGE_CHANGED:
20756                            Uri data = intent.getData();
20757                            String ssp;
20758                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
20759                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
20760                                final boolean replacing =
20761                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
20762                                final boolean killProcess =
20763                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
20764                                final boolean fullUninstall = removed && !replacing;
20765                                if (removed) {
20766                                    if (killProcess) {
20767                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
20768                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
20769                                                false, true, true, false, fullUninstall, userId,
20770                                                removed ? "pkg removed" : "pkg changed");
20771                                    }
20772                                    final int cmd = killProcess
20773                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
20774                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
20775                                    sendPackageBroadcastLocked(cmd,
20776                                            new String[] {ssp}, userId);
20777                                    if (fullUninstall) {
20778                                        mAppOpsService.packageRemoved(
20779                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
20780
20781                                        // Remove all permissions granted from/to this package
20782                                        removeUriPermissionsForPackageLocked(ssp, userId, true,
20783                                                false);
20784
20785                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
20786
20787                                        mServices.forceStopPackageLocked(ssp, userId);
20788                                        mAppWarnings.onPackageUninstalled(ssp);
20789                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
20790                                        mBatteryStatsService.notePackageUninstalled(ssp);
20791                                    }
20792                                } else {
20793                                    if (killProcess) {
20794                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
20795                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
20796                                                userId, ProcessList.INVALID_ADJ,
20797                                                false, true, true, false, "change " + ssp);
20798                                    }
20799                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
20800                                            intent.getStringArrayExtra(
20801                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
20802                                }
20803                            }
20804                            break;
20805                        case Intent.ACTION_PACKAGES_SUSPENDED:
20806                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
20807                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
20808                                    intent.getAction());
20809                            final String[] packageNames = intent.getStringArrayExtra(
20810                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
20811                            final int userHandle = intent.getIntExtra(
20812                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
20813
20814                            synchronized(ActivityManagerService.this) {
20815                                mRecentTasks.onPackagesSuspendedChanged(
20816                                        packageNames, suspended, userHandle);
20817                            }
20818                            break;
20819                    }
20820                    break;
20821                case Intent.ACTION_PACKAGE_REPLACED:
20822                {
20823                    final Uri data = intent.getData();
20824                    final String ssp;
20825                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20826                        ApplicationInfo aInfo = null;
20827                        try {
20828                            aInfo = AppGlobals.getPackageManager()
20829                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
20830                        } catch (RemoteException ignore) {}
20831                        if (aInfo == null) {
20832                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
20833                                    + " ssp=" + ssp + " data=" + data);
20834                            return ActivityManager.BROADCAST_SUCCESS;
20835                        }
20836                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
20837                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
20838                                new String[] {ssp}, userId);
20839                    }
20840                    break;
20841                }
20842                case Intent.ACTION_PACKAGE_ADDED:
20843                {
20844                    // Special case for adding a package: by default turn on compatibility mode.
20845                    Uri data = intent.getData();
20846                    String ssp;
20847                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20848                        final boolean replacing =
20849                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
20850                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
20851
20852                        try {
20853                            ApplicationInfo ai = AppGlobals.getPackageManager().
20854                                    getApplicationInfo(ssp, 0, 0);
20855                            mBatteryStatsService.notePackageInstalled(ssp,
20856                                    ai != null ? ai.versionCode : 0);
20857                        } catch (RemoteException e) {
20858                        }
20859                    }
20860                    break;
20861                }
20862                case Intent.ACTION_PACKAGE_DATA_CLEARED:
20863                {
20864                    Uri data = intent.getData();
20865                    String ssp;
20866                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20867                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
20868                        mAppWarnings.onPackageDataCleared(ssp);
20869                    }
20870                    break;
20871                }
20872                case Intent.ACTION_TIMEZONE_CHANGED:
20873                    // If this is the time zone changed action, queue up a message that will reset
20874                    // the timezone of all currently running processes. This message will get
20875                    // queued up before the broadcast happens.
20876                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
20877                    break;
20878                case Intent.ACTION_TIME_CHANGED:
20879                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
20880                    // the tri-state value it may contain and "unknown".
20881                    // For convenience we re-use the Intent extra values.
20882                    final int NO_EXTRA_VALUE_FOUND = -1;
20883                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
20884                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
20885                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
20886                    // Only send a message if the time preference is available.
20887                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
20888                        Message updateTimePreferenceMsg =
20889                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
20890                                        timeFormatPreferenceMsgValue, 0);
20891                        mHandler.sendMessage(updateTimePreferenceMsg);
20892                    }
20893                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20894                    synchronized (stats) {
20895                        stats.noteCurrentTimeChangedLocked();
20896                    }
20897                    break;
20898                case Intent.ACTION_CLEAR_DNS_CACHE:
20899                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
20900                    break;
20901                case Proxy.PROXY_CHANGE_ACTION:
20902                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
20903                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
20904                    break;
20905                case android.hardware.Camera.ACTION_NEW_PICTURE:
20906                case android.hardware.Camera.ACTION_NEW_VIDEO:
20907                    // In N we just turned these off; in O we are turing them back on partly,
20908                    // only for registered receivers.  This will still address the main problem
20909                    // (a spam of apps waking up when a picture is taken putting significant
20910                    // memory pressure on the system at a bad point), while still allowing apps
20911                    // that are already actively running to know about this happening.
20912                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20913                    break;
20914                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
20915                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
20916                    break;
20917                case "com.android.launcher.action.INSTALL_SHORTCUT":
20918                    // As of O, we no longer support this broadcasts, even for pre-O apps.
20919                    // Apps should now be using ShortcutManager.pinRequestShortcut().
20920                    Log.w(TAG, "Broadcast " + action
20921                            + " no longer supported. It will not be delivered.");
20922                    return ActivityManager.BROADCAST_SUCCESS;
20923            }
20924
20925            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
20926                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
20927                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
20928                final int uid = getUidFromIntent(intent);
20929                if (uid != -1) {
20930                    final UidRecord uidRec = mActiveUids.get(uid);
20931                    if (uidRec != null) {
20932                        uidRec.updateHasInternetPermission();
20933                    }
20934                }
20935            }
20936        }
20937
20938        // Add to the sticky list if requested.
20939        if (sticky) {
20940            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
20941                    callingPid, callingUid)
20942                    != PackageManager.PERMISSION_GRANTED) {
20943                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
20944                        + callingPid + ", uid=" + callingUid
20945                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
20946                Slog.w(TAG, msg);
20947                throw new SecurityException(msg);
20948            }
20949            if (requiredPermissions != null && requiredPermissions.length > 0) {
20950                Slog.w(TAG, "Can't broadcast sticky intent " + intent
20951                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
20952                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
20953            }
20954            if (intent.getComponent() != null) {
20955                throw new SecurityException(
20956                        "Sticky broadcasts can't target a specific component");
20957            }
20958            // We use userId directly here, since the "all" target is maintained
20959            // as a separate set of sticky broadcasts.
20960            if (userId != UserHandle.USER_ALL) {
20961                // But first, if this is not a broadcast to all users, then
20962                // make sure it doesn't conflict with an existing broadcast to
20963                // all users.
20964                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
20965                        UserHandle.USER_ALL);
20966                if (stickies != null) {
20967                    ArrayList<Intent> list = stickies.get(intent.getAction());
20968                    if (list != null) {
20969                        int N = list.size();
20970                        int i;
20971                        for (i=0; i<N; i++) {
20972                            if (intent.filterEquals(list.get(i))) {
20973                                throw new IllegalArgumentException(
20974                                        "Sticky broadcast " + intent + " for user "
20975                                        + userId + " conflicts with existing global broadcast");
20976                            }
20977                        }
20978                    }
20979                }
20980            }
20981            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
20982            if (stickies == null) {
20983                stickies = new ArrayMap<>();
20984                mStickyBroadcasts.put(userId, stickies);
20985            }
20986            ArrayList<Intent> list = stickies.get(intent.getAction());
20987            if (list == null) {
20988                list = new ArrayList<>();
20989                stickies.put(intent.getAction(), list);
20990            }
20991            final int stickiesCount = list.size();
20992            int i;
20993            for (i = 0; i < stickiesCount; i++) {
20994                if (intent.filterEquals(list.get(i))) {
20995                    // This sticky already exists, replace it.
20996                    list.set(i, new Intent(intent));
20997                    break;
20998                }
20999            }
21000            if (i >= stickiesCount) {
21001                list.add(new Intent(intent));
21002            }
21003        }
21004
21005        int[] users;
21006        if (userId == UserHandle.USER_ALL) {
21007            // Caller wants broadcast to go to all started users.
21008            users = mUserController.getStartedUserArray();
21009        } else {
21010            // Caller wants broadcast to go to one specific user.
21011            users = new int[] {userId};
21012        }
21013
21014        // Figure out who all will receive this broadcast.
21015        List receivers = null;
21016        List<BroadcastFilter> registeredReceivers = null;
21017        // Need to resolve the intent to interested receivers...
21018        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
21019                 == 0) {
21020            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
21021        }
21022        if (intent.getComponent() == null) {
21023            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
21024                // Query one target user at a time, excluding shell-restricted users
21025                for (int i = 0; i < users.length; i++) {
21026                    if (mUserController.hasUserRestriction(
21027                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
21028                        continue;
21029                    }
21030                    List<BroadcastFilter> registeredReceiversForUser =
21031                            mReceiverResolver.queryIntent(intent,
21032                                    resolvedType, false /*defaultOnly*/, users[i]);
21033                    if (registeredReceivers == null) {
21034                        registeredReceivers = registeredReceiversForUser;
21035                    } else if (registeredReceiversForUser != null) {
21036                        registeredReceivers.addAll(registeredReceiversForUser);
21037                    }
21038                }
21039            } else {
21040                registeredReceivers = mReceiverResolver.queryIntent(intent,
21041                        resolvedType, false /*defaultOnly*/, userId);
21042            }
21043        }
21044
21045        final boolean replacePending =
21046                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
21047
21048        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
21049                + " replacePending=" + replacePending);
21050
21051        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
21052        if (!ordered && NR > 0) {
21053            // If we are not serializing this broadcast, then send the
21054            // registered receivers separately so they don't wait for the
21055            // components to be launched.
21056            if (isCallerSystem) {
21057                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21058                        isProtectedBroadcast, registeredReceivers);
21059            }
21060            final BroadcastQueue queue = broadcastQueueForIntent(intent);
21061            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21062                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21063                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
21064                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
21065            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
21066            final boolean replaced = replacePending
21067                    && (queue.replaceParallelBroadcastLocked(r) != null);
21068            // Note: We assume resultTo is null for non-ordered broadcasts.
21069            if (!replaced) {
21070                queue.enqueueParallelBroadcastLocked(r);
21071                queue.scheduleBroadcastsLocked();
21072            }
21073            registeredReceivers = null;
21074            NR = 0;
21075        }
21076
21077        // Merge into one list.
21078        int ir = 0;
21079        if (receivers != null) {
21080            // A special case for PACKAGE_ADDED: do not allow the package
21081            // being added to see this broadcast.  This prevents them from
21082            // using this as a back door to get run as soon as they are
21083            // installed.  Maybe in the future we want to have a special install
21084            // broadcast or such for apps, but we'd like to deliberately make
21085            // this decision.
21086            String skipPackages[] = null;
21087            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
21088                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
21089                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
21090                Uri data = intent.getData();
21091                if (data != null) {
21092                    String pkgName = data.getSchemeSpecificPart();
21093                    if (pkgName != null) {
21094                        skipPackages = new String[] { pkgName };
21095                    }
21096                }
21097            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
21098                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21099            }
21100            if (skipPackages != null && (skipPackages.length > 0)) {
21101                for (String skipPackage : skipPackages) {
21102                    if (skipPackage != null) {
21103                        int NT = receivers.size();
21104                        for (int it=0; it<NT; it++) {
21105                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
21106                            if (curt.activityInfo.packageName.equals(skipPackage)) {
21107                                receivers.remove(it);
21108                                it--;
21109                                NT--;
21110                            }
21111                        }
21112                    }
21113                }
21114            }
21115
21116            int NT = receivers != null ? receivers.size() : 0;
21117            int it = 0;
21118            ResolveInfo curt = null;
21119            BroadcastFilter curr = null;
21120            while (it < NT && ir < NR) {
21121                if (curt == null) {
21122                    curt = (ResolveInfo)receivers.get(it);
21123                }
21124                if (curr == null) {
21125                    curr = registeredReceivers.get(ir);
21126                }
21127                if (curr.getPriority() >= curt.priority) {
21128                    // Insert this broadcast record into the final list.
21129                    receivers.add(it, curr);
21130                    ir++;
21131                    curr = null;
21132                    it++;
21133                    NT++;
21134                } else {
21135                    // Skip to the next ResolveInfo in the final list.
21136                    it++;
21137                    curt = null;
21138                }
21139            }
21140        }
21141        while (ir < NR) {
21142            if (receivers == null) {
21143                receivers = new ArrayList();
21144            }
21145            receivers.add(registeredReceivers.get(ir));
21146            ir++;
21147        }
21148
21149        if (isCallerSystem) {
21150            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21151                    isProtectedBroadcast, receivers);
21152        }
21153
21154        if ((receivers != null && receivers.size() > 0)
21155                || resultTo != null) {
21156            BroadcastQueue queue = broadcastQueueForIntent(intent);
21157            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21158                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21159                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
21160                    resultData, resultExtras, ordered, sticky, false, userId);
21161
21162            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
21163                    + ": prev had " + queue.mOrderedBroadcasts.size());
21164            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
21165                    "Enqueueing broadcast " + r.intent.getAction());
21166
21167            final BroadcastRecord oldRecord =
21168                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
21169            if (oldRecord != null) {
21170                // Replaced, fire the result-to receiver.
21171                if (oldRecord.resultTo != null) {
21172                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
21173                    try {
21174                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
21175                                oldRecord.intent,
21176                                Activity.RESULT_CANCELED, null, null,
21177                                false, false, oldRecord.userId);
21178                    } catch (RemoteException e) {
21179                        Slog.w(TAG, "Failure ["
21180                                + queue.mQueueName + "] sending broadcast result of "
21181                                + intent, e);
21182
21183                    }
21184                }
21185            } else {
21186                queue.enqueueOrderedBroadcastLocked(r);
21187                queue.scheduleBroadcastsLocked();
21188            }
21189        } else {
21190            // There was nobody interested in the broadcast, but we still want to record
21191            // that it happened.
21192            if (intent.getComponent() == null && intent.getPackage() == null
21193                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21194                // This was an implicit broadcast... let's record it for posterity.
21195                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
21196            }
21197        }
21198
21199        return ActivityManager.BROADCAST_SUCCESS;
21200    }
21201
21202    /**
21203     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21204     */
21205    private int getUidFromIntent(Intent intent) {
21206        if (intent == null) {
21207            return -1;
21208        }
21209        final Bundle intentExtras = intent.getExtras();
21210        return intent.hasExtra(Intent.EXTRA_UID)
21211                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
21212    }
21213
21214    final void rotateBroadcastStatsIfNeededLocked() {
21215        final long now = SystemClock.elapsedRealtime();
21216        if (mCurBroadcastStats == null ||
21217                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
21218            mLastBroadcastStats = mCurBroadcastStats;
21219            if (mLastBroadcastStats != null) {
21220                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
21221                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
21222            }
21223            mCurBroadcastStats = new BroadcastStats();
21224        }
21225    }
21226
21227    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
21228            int skipCount, long dispatchTime) {
21229        rotateBroadcastStatsIfNeededLocked();
21230        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
21231    }
21232
21233    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21234        rotateBroadcastStatsIfNeededLocked();
21235        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
21236    }
21237
21238    final Intent verifyBroadcastLocked(Intent intent) {
21239        // Refuse possible leaked file descriptors
21240        if (intent != null && intent.hasFileDescriptors() == true) {
21241            throw new IllegalArgumentException("File descriptors passed in Intent");
21242        }
21243
21244        int flags = intent.getFlags();
21245
21246        if (!mProcessesReady) {
21247            // if the caller really truly claims to know what they're doing, go
21248            // ahead and allow the broadcast without launching any receivers
21249            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
21250                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
21251            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21252                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
21253                        + " before boot completion");
21254                throw new IllegalStateException("Cannot broadcast before boot completed");
21255            }
21256        }
21257
21258        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
21259            throw new IllegalArgumentException(
21260                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
21261        }
21262
21263        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21264            switch (Binder.getCallingUid()) {
21265                case ROOT_UID:
21266                case SHELL_UID:
21267                    break;
21268                default:
21269                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
21270                            + Binder.getCallingUid());
21271                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
21272                    break;
21273            }
21274        }
21275
21276        return intent;
21277    }
21278
21279    public final int broadcastIntent(IApplicationThread caller,
21280            Intent intent, String resolvedType, IIntentReceiver resultTo,
21281            int resultCode, String resultData, Bundle resultExtras,
21282            String[] requiredPermissions, int appOp, Bundle bOptions,
21283            boolean serialized, boolean sticky, int userId) {
21284        enforceNotIsolatedCaller("broadcastIntent");
21285        synchronized(this) {
21286            intent = verifyBroadcastLocked(intent);
21287
21288            final ProcessRecord callerApp = getRecordForAppLocked(caller);
21289            final int callingPid = Binder.getCallingPid();
21290            final int callingUid = Binder.getCallingUid();
21291            final long origId = Binder.clearCallingIdentity();
21292            int res = broadcastIntentLocked(callerApp,
21293                    callerApp != null ? callerApp.info.packageName : null,
21294                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
21295                    requiredPermissions, appOp, bOptions, serialized, sticky,
21296                    callingPid, callingUid, userId);
21297            Binder.restoreCallingIdentity(origId);
21298            return res;
21299        }
21300    }
21301
21302
21303    int broadcastIntentInPackage(String packageName, int uid,
21304            Intent intent, String resolvedType, IIntentReceiver resultTo,
21305            int resultCode, String resultData, Bundle resultExtras,
21306            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
21307            int userId) {
21308        synchronized(this) {
21309            intent = verifyBroadcastLocked(intent);
21310
21311            final long origId = Binder.clearCallingIdentity();
21312            String[] requiredPermissions = requiredPermission == null ? null
21313                    : new String[] {requiredPermission};
21314            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
21315                    resultTo, resultCode, resultData, resultExtras,
21316                    requiredPermissions, OP_NONE, bOptions, serialized,
21317                    sticky, -1, uid, userId);
21318            Binder.restoreCallingIdentity(origId);
21319            return res;
21320        }
21321    }
21322
21323    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
21324        // Refuse possible leaked file descriptors
21325        if (intent != null && intent.hasFileDescriptors() == true) {
21326            throw new IllegalArgumentException("File descriptors passed in Intent");
21327        }
21328
21329        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21330                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
21331
21332        synchronized(this) {
21333            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
21334                    != PackageManager.PERMISSION_GRANTED) {
21335                String msg = "Permission Denial: unbroadcastIntent() from pid="
21336                        + Binder.getCallingPid()
21337                        + ", uid=" + Binder.getCallingUid()
21338                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21339                Slog.w(TAG, msg);
21340                throw new SecurityException(msg);
21341            }
21342            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21343            if (stickies != null) {
21344                ArrayList<Intent> list = stickies.get(intent.getAction());
21345                if (list != null) {
21346                    int N = list.size();
21347                    int i;
21348                    for (i=0; i<N; i++) {
21349                        if (intent.filterEquals(list.get(i))) {
21350                            list.remove(i);
21351                            break;
21352                        }
21353                    }
21354                    if (list.size() <= 0) {
21355                        stickies.remove(intent.getAction());
21356                    }
21357                }
21358                if (stickies.size() <= 0) {
21359                    mStickyBroadcasts.remove(userId);
21360                }
21361            }
21362        }
21363    }
21364
21365    void backgroundServicesFinishedLocked(int userId) {
21366        for (BroadcastQueue queue : mBroadcastQueues) {
21367            queue.backgroundServicesFinishedLocked(userId);
21368        }
21369    }
21370
21371    public void finishReceiver(IBinder who, int resultCode, String resultData,
21372            Bundle resultExtras, boolean resultAbort, int flags) {
21373        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
21374
21375        // Refuse possible leaked file descriptors
21376        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
21377            throw new IllegalArgumentException("File descriptors passed in Bundle");
21378        }
21379
21380        final long origId = Binder.clearCallingIdentity();
21381        try {
21382            boolean doNext = false;
21383            BroadcastRecord r;
21384
21385            synchronized(this) {
21386                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
21387                        ? mFgBroadcastQueue : mBgBroadcastQueue;
21388                r = queue.getMatchingOrderedReceiver(who);
21389                if (r != null) {
21390                    doNext = r.queue.finishReceiverLocked(r, resultCode,
21391                        resultData, resultExtras, resultAbort, true);
21392                }
21393            }
21394
21395            if (doNext) {
21396                r.queue.processNextBroadcast(false);
21397            }
21398            trimApplications();
21399        } finally {
21400            Binder.restoreCallingIdentity(origId);
21401        }
21402    }
21403
21404    // =========================================================
21405    // INSTRUMENTATION
21406    // =========================================================
21407
21408    public boolean startInstrumentation(ComponentName className,
21409            String profileFile, int flags, Bundle arguments,
21410            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
21411            int userId, String abiOverride) {
21412        enforceNotIsolatedCaller("startInstrumentation");
21413        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21414                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
21415        // Refuse possible leaked file descriptors
21416        if (arguments != null && arguments.hasFileDescriptors()) {
21417            throw new IllegalArgumentException("File descriptors passed in Bundle");
21418        }
21419
21420        synchronized(this) {
21421            InstrumentationInfo ii = null;
21422            ApplicationInfo ai = null;
21423            try {
21424                ii = mContext.getPackageManager().getInstrumentationInfo(
21425                    className, STOCK_PM_FLAGS);
21426                ai = AppGlobals.getPackageManager().getApplicationInfo(
21427                        ii.targetPackage, STOCK_PM_FLAGS, userId);
21428            } catch (PackageManager.NameNotFoundException e) {
21429            } catch (RemoteException e) {
21430            }
21431            if (ii == null) {
21432                reportStartInstrumentationFailureLocked(watcher, className,
21433                        "Unable to find instrumentation info for: " + className);
21434                return false;
21435            }
21436            if (ai == null) {
21437                reportStartInstrumentationFailureLocked(watcher, className,
21438                        "Unable to find instrumentation target package: " + ii.targetPackage);
21439                return false;
21440            }
21441            if (!ai.hasCode()) {
21442                reportStartInstrumentationFailureLocked(watcher, className,
21443                        "Instrumentation target has no code: " + ii.targetPackage);
21444                return false;
21445            }
21446
21447            int match = mContext.getPackageManager().checkSignatures(
21448                    ii.targetPackage, ii.packageName);
21449            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
21450                String msg = "Permission Denial: starting instrumentation "
21451                        + className + " from pid="
21452                        + Binder.getCallingPid()
21453                        + ", uid=" + Binder.getCallingPid()
21454                        + " not allowed because package " + ii.packageName
21455                        + " does not have a signature matching the target "
21456                        + ii.targetPackage;
21457                reportStartInstrumentationFailureLocked(watcher, className, msg);
21458                throw new SecurityException(msg);
21459            }
21460
21461            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
21462            activeInstr.mClass = className;
21463            String defProcess = ai.processName;;
21464            if (ii.targetProcesses == null) {
21465                activeInstr.mTargetProcesses = new String[]{ai.processName};
21466            } else if (ii.targetProcesses.equals("*")) {
21467                activeInstr.mTargetProcesses = new String[0];
21468            } else {
21469                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
21470                defProcess = activeInstr.mTargetProcesses[0];
21471            }
21472            activeInstr.mTargetInfo = ai;
21473            activeInstr.mProfileFile = profileFile;
21474            activeInstr.mArguments = arguments;
21475            activeInstr.mWatcher = watcher;
21476            activeInstr.mUiAutomationConnection = uiAutomationConnection;
21477            activeInstr.mResultClass = className;
21478
21479            final long origId = Binder.clearCallingIdentity();
21480            // Instrumentation can kill and relaunch even persistent processes
21481            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
21482                    "start instr");
21483            // Inform usage stats to make the target package active
21484            if (mUsageStatsService != null) {
21485                mUsageStatsService.reportEvent(ii.targetPackage, userId,
21486                        UsageEvents.Event.SYSTEM_INTERACTION);
21487            }
21488            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
21489            app.instr = activeInstr;
21490            activeInstr.mFinished = false;
21491            activeInstr.mRunningProcesses.add(app);
21492            if (!mActiveInstrumentation.contains(activeInstr)) {
21493                mActiveInstrumentation.add(activeInstr);
21494            }
21495            Binder.restoreCallingIdentity(origId);
21496        }
21497
21498        return true;
21499    }
21500
21501    /**
21502     * Report errors that occur while attempting to start Instrumentation.  Always writes the
21503     * error to the logs, but if somebody is watching, send the report there too.  This enables
21504     * the "am" command to report errors with more information.
21505     *
21506     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
21507     * @param cn The component name of the instrumentation.
21508     * @param report The error report.
21509     */
21510    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
21511            ComponentName cn, String report) {
21512        Slog.w(TAG, report);
21513        if (watcher != null) {
21514            Bundle results = new Bundle();
21515            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
21516            results.putString("Error", report);
21517            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
21518        }
21519    }
21520
21521    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
21522        if (app.instr == null) {
21523            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21524            return;
21525        }
21526
21527        if (!app.instr.mFinished && results != null) {
21528            if (app.instr.mCurResults == null) {
21529                app.instr.mCurResults = new Bundle(results);
21530            } else {
21531                app.instr.mCurResults.putAll(results);
21532            }
21533        }
21534    }
21535
21536    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
21537        int userId = UserHandle.getCallingUserId();
21538        // Refuse possible leaked file descriptors
21539        if (results != null && results.hasFileDescriptors()) {
21540            throw new IllegalArgumentException("File descriptors passed in Intent");
21541        }
21542
21543        synchronized(this) {
21544            ProcessRecord app = getRecordForAppLocked(target);
21545            if (app == null) {
21546                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
21547                return;
21548            }
21549            final long origId = Binder.clearCallingIdentity();
21550            addInstrumentationResultsLocked(app, results);
21551            Binder.restoreCallingIdentity(origId);
21552        }
21553    }
21554
21555    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
21556        if (app.instr == null) {
21557            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21558            return;
21559        }
21560
21561        if (!app.instr.mFinished) {
21562            if (app.instr.mWatcher != null) {
21563                Bundle finalResults = app.instr.mCurResults;
21564                if (finalResults != null) {
21565                    if (app.instr.mCurResults != null && results != null) {
21566                        finalResults.putAll(results);
21567                    }
21568                } else {
21569                    finalResults = results;
21570                }
21571                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
21572                        app.instr.mClass, resultCode, finalResults);
21573            }
21574
21575            // Can't call out of the system process with a lock held, so post a message.
21576            if (app.instr.mUiAutomationConnection != null) {
21577                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
21578                        app.instr.mUiAutomationConnection).sendToTarget();
21579            }
21580            app.instr.mFinished = true;
21581        }
21582
21583        app.instr.removeProcess(app);
21584        app.instr = null;
21585
21586        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
21587                "finished inst");
21588    }
21589
21590    public void finishInstrumentation(IApplicationThread target,
21591            int resultCode, Bundle results) {
21592        int userId = UserHandle.getCallingUserId();
21593        // Refuse possible leaked file descriptors
21594        if (results != null && results.hasFileDescriptors()) {
21595            throw new IllegalArgumentException("File descriptors passed in Intent");
21596        }
21597
21598        synchronized(this) {
21599            ProcessRecord app = getRecordForAppLocked(target);
21600            if (app == null) {
21601                Slog.w(TAG, "finishInstrumentation: no app for " + target);
21602                return;
21603            }
21604            final long origId = Binder.clearCallingIdentity();
21605            finishInstrumentationLocked(app, resultCode, results);
21606            Binder.restoreCallingIdentity(origId);
21607        }
21608    }
21609
21610    // =========================================================
21611    // CONFIGURATION
21612    // =========================================================
21613
21614    public ConfigurationInfo getDeviceConfigurationInfo() {
21615        ConfigurationInfo config = new ConfigurationInfo();
21616        synchronized (this) {
21617            final Configuration globalConfig = getGlobalConfiguration();
21618            config.reqTouchScreen = globalConfig.touchscreen;
21619            config.reqKeyboardType = globalConfig.keyboard;
21620            config.reqNavigation = globalConfig.navigation;
21621            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
21622                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
21623                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
21624            }
21625            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
21626                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
21627                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
21628            }
21629            config.reqGlEsVersion = GL_ES_VERSION;
21630        }
21631        return config;
21632    }
21633
21634    ActivityStack getFocusedStack() {
21635        return mStackSupervisor.getFocusedStack();
21636    }
21637
21638    @Override
21639    public StackInfo getFocusedStackInfo() throws RemoteException {
21640        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
21641        long ident = Binder.clearCallingIdentity();
21642        try {
21643            synchronized (this) {
21644                ActivityStack focusedStack = getFocusedStack();
21645                if (focusedStack != null) {
21646                    return mStackSupervisor.getStackInfo(focusedStack.mStackId);
21647                }
21648                return null;
21649            }
21650        } finally {
21651            Binder.restoreCallingIdentity(ident);
21652        }
21653    }
21654
21655    public Configuration getConfiguration() {
21656        Configuration ci;
21657        synchronized(this) {
21658            ci = new Configuration(getGlobalConfiguration());
21659            ci.userSetLocale = false;
21660        }
21661        return ci;
21662    }
21663
21664    @Override
21665    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
21666        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
21667        synchronized (this) {
21668            mSuppressResizeConfigChanges = suppress;
21669        }
21670    }
21671
21672    /**
21673     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
21674     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
21675     *       activity and clearing the task at the same time.
21676     */
21677    @Override
21678    // TODO: API should just be about changing windowing modes...
21679    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
21680        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
21681                "moveTasksToFullscreenStack()");
21682        synchronized (this) {
21683            final long origId = Binder.clearCallingIdentity();
21684            try {
21685                final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
21686                if (stack != null){
21687                    if (!stack.isActivityTypeStandardOrUndefined()) {
21688                        throw new IllegalArgumentException(
21689                                "You can't move tasks from non-standard stacks.");
21690                    }
21691                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
21692                }
21693            } finally {
21694                Binder.restoreCallingIdentity(origId);
21695            }
21696        }
21697    }
21698
21699    @Override
21700    public void updatePersistentConfiguration(Configuration values) {
21701        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
21702        enforceWriteSettingsPermission("updatePersistentConfiguration()");
21703        if (values == null) {
21704            throw new NullPointerException("Configuration must not be null");
21705        }
21706
21707        int userId = UserHandle.getCallingUserId();
21708
21709        synchronized(this) {
21710            updatePersistentConfigurationLocked(values, userId);
21711        }
21712    }
21713
21714    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
21715        final long origId = Binder.clearCallingIdentity();
21716        try {
21717            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
21718        } finally {
21719            Binder.restoreCallingIdentity(origId);
21720        }
21721    }
21722
21723    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
21724        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
21725                FONT_SCALE, 1.0f, userId);
21726
21727        synchronized (this) {
21728            if (getGlobalConfiguration().fontScale == scaleFactor) {
21729                return;
21730            }
21731
21732            final Configuration configuration
21733                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
21734            configuration.fontScale = scaleFactor;
21735            updatePersistentConfigurationLocked(configuration, userId);
21736        }
21737    }
21738
21739    private void enforceWriteSettingsPermission(String func) {
21740        int uid = Binder.getCallingUid();
21741        if (uid == ROOT_UID) {
21742            return;
21743        }
21744
21745        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
21746                Settings.getPackageNameForUid(mContext, uid), false)) {
21747            return;
21748        }
21749
21750        String msg = "Permission Denial: " + func + " from pid="
21751                + Binder.getCallingPid()
21752                + ", uid=" + uid
21753                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
21754        Slog.w(TAG, msg);
21755        throw new SecurityException(msg);
21756    }
21757
21758    @Override
21759    public boolean updateConfiguration(Configuration values) {
21760        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
21761
21762        synchronized(this) {
21763            if (values == null && mWindowManager != null) {
21764                // sentinel: fetch the current configuration from the window manager
21765                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
21766            }
21767
21768            if (mWindowManager != null) {
21769                // Update OOM levels based on display size.
21770                mProcessList.applyDisplaySize(mWindowManager);
21771            }
21772
21773            final long origId = Binder.clearCallingIdentity();
21774            try {
21775                if (values != null) {
21776                    Settings.System.clearConfiguration(values);
21777                }
21778                updateConfigurationLocked(values, null, false, false /* persistent */,
21779                        UserHandle.USER_NULL, false /* deferResume */,
21780                        mTmpUpdateConfigurationResult);
21781                return mTmpUpdateConfigurationResult.changes != 0;
21782            } finally {
21783                Binder.restoreCallingIdentity(origId);
21784            }
21785        }
21786    }
21787
21788    void updateUserConfigurationLocked() {
21789        final Configuration configuration = new Configuration(getGlobalConfiguration());
21790        final int currentUserId = mUserController.getCurrentUserId();
21791        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
21792                currentUserId, Settings.System.canWrite(mContext));
21793        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
21794                false /* persistent */, currentUserId, false /* deferResume */);
21795    }
21796
21797    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21798            boolean initLocale) {
21799        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
21800    }
21801
21802    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21803            boolean initLocale, boolean deferResume) {
21804        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
21805        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
21806                UserHandle.USER_NULL, deferResume);
21807    }
21808
21809    // To cache the list of supported system locales
21810    private String[] mSupportedSystemLocales = null;
21811
21812    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21813            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
21814        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
21815                deferResume, null /* result */);
21816    }
21817
21818    /**
21819     * Do either or both things: (1) change the current configuration, and (2)
21820     * make sure the given activity is running with the (now) current
21821     * configuration.  Returns true if the activity has been left running, or
21822     * false if <var>starting</var> is being destroyed to match the new
21823     * configuration.
21824     *
21825     * @param userId is only used when persistent parameter is set to true to persist configuration
21826     *               for that particular user
21827     */
21828    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21829            boolean initLocale, boolean persistent, int userId, boolean deferResume,
21830            UpdateConfigurationResult result) {
21831        int changes = 0;
21832        boolean kept = true;
21833
21834        if (mWindowManager != null) {
21835            mWindowManager.deferSurfaceLayout();
21836        }
21837        try {
21838            if (values != null) {
21839                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
21840                        deferResume);
21841            }
21842
21843            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
21844        } finally {
21845            if (mWindowManager != null) {
21846                mWindowManager.continueSurfaceLayout();
21847            }
21848        }
21849
21850        if (result != null) {
21851            result.changes = changes;
21852            result.activityRelaunched = !kept;
21853        }
21854        return kept;
21855    }
21856
21857    /** Update default (global) configuration and notify listeners about changes. */
21858    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
21859            boolean persistent, int userId, boolean deferResume) {
21860        mTempConfig.setTo(getGlobalConfiguration());
21861        final int changes = mTempConfig.updateFrom(values);
21862        if (changes == 0) {
21863            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
21864            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
21865            // performDisplayOverrideConfigUpdate in order to send the new display configuration
21866            // (even if there are no actual changes) to unfreeze the window.
21867            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
21868            return 0;
21869        }
21870
21871        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
21872                "Updating global configuration to: " + values);
21873
21874        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
21875
21876        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
21877            final LocaleList locales = values.getLocales();
21878            int bestLocaleIndex = 0;
21879            if (locales.size() > 1) {
21880                if (mSupportedSystemLocales == null) {
21881                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
21882                }
21883                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
21884            }
21885            SystemProperties.set("persist.sys.locale",
21886                    locales.get(bestLocaleIndex).toLanguageTag());
21887            LocaleList.setDefault(locales, bestLocaleIndex);
21888            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
21889                    locales.get(bestLocaleIndex)));
21890        }
21891
21892        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
21893        mTempConfig.seq = mConfigurationSeq;
21894
21895        // Update stored global config and notify everyone about the change.
21896        mStackSupervisor.onConfigurationChanged(mTempConfig);
21897
21898        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
21899        // TODO(multi-display): Update UsageEvents#Event to include displayId.
21900        mUsageStatsService.reportConfigurationChange(mTempConfig,
21901                mUserController.getCurrentUserId());
21902
21903        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
21904        mShowDialogs = shouldShowDialogs(mTempConfig);
21905
21906        AttributeCache ac = AttributeCache.instance();
21907        if (ac != null) {
21908            ac.updateConfiguration(mTempConfig);
21909        }
21910
21911        // Make sure all resources in our process are updated right now, so that anyone who is going
21912        // to retrieve resource values after we return will be sure to get the new ones. This is
21913        // especially important during boot, where the first config change needs to guarantee all
21914        // resources have that config before following boot code is executed.
21915        mSystemThread.applyConfigurationToResources(mTempConfig);
21916
21917        // We need another copy of global config because we're scheduling some calls instead of
21918        // running them in place. We need to be sure that object we send will be handled unchanged.
21919        final Configuration configCopy = new Configuration(mTempConfig);
21920        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
21921            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
21922            msg.obj = configCopy;
21923            msg.arg1 = userId;
21924            mHandler.sendMessage(msg);
21925        }
21926
21927        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21928            ProcessRecord app = mLruProcesses.get(i);
21929            try {
21930                if (app.thread != null) {
21931                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
21932                            + app.processName + " new config " + configCopy);
21933                    mLifecycleManager.scheduleTransaction(app.thread,
21934                            ConfigurationChangeItem.obtain(configCopy));
21935                }
21936            } catch (Exception e) {
21937                Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
21938            }
21939        }
21940
21941        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
21942        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
21943                | Intent.FLAG_RECEIVER_FOREGROUND
21944                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21945        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
21946                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
21947                UserHandle.USER_ALL);
21948        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
21949            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
21950            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
21951                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
21952                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21953            if (initLocale || !mProcessesReady) {
21954                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21955            }
21956            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
21957                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
21958                    UserHandle.USER_ALL);
21959        }
21960
21961        // Override configuration of the default display duplicates global config, so we need to
21962        // update it also. This will also notify WindowManager about changes.
21963        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
21964                DEFAULT_DISPLAY);
21965
21966        return changes;
21967    }
21968
21969    @Override
21970    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
21971        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
21972
21973        synchronized (this) {
21974            // Check if display is initialized in AM.
21975            if (!mStackSupervisor.isDisplayAdded(displayId)) {
21976                // Call might come when display is not yet added or has already been removed.
21977                if (DEBUG_CONFIGURATION) {
21978                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
21979                            + displayId);
21980                }
21981                return false;
21982            }
21983
21984            if (values == null && mWindowManager != null) {
21985                // sentinel: fetch the current configuration from the window manager
21986                values = mWindowManager.computeNewConfiguration(displayId);
21987            }
21988
21989            if (mWindowManager != null) {
21990                // Update OOM levels based on display size.
21991                mProcessList.applyDisplaySize(mWindowManager);
21992            }
21993
21994            final long origId = Binder.clearCallingIdentity();
21995            try {
21996                if (values != null) {
21997                    Settings.System.clearConfiguration(values);
21998                }
21999                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
22000                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
22001                return mTmpUpdateConfigurationResult.changes != 0;
22002            } finally {
22003                Binder.restoreCallingIdentity(origId);
22004            }
22005        }
22006    }
22007
22008    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
22009            boolean deferResume, int displayId) {
22010        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
22011                displayId, null /* result */);
22012    }
22013
22014    /**
22015     * Updates override configuration specific for the selected display. If no config is provided,
22016     * new one will be computed in WM based on current display info.
22017     */
22018    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
22019            ActivityRecord starting, boolean deferResume, int displayId,
22020            UpdateConfigurationResult result) {
22021        int changes = 0;
22022        boolean kept = true;
22023
22024        if (mWindowManager != null) {
22025            mWindowManager.deferSurfaceLayout();
22026        }
22027        try {
22028            if (values != null) {
22029                if (displayId == DEFAULT_DISPLAY) {
22030                    // Override configuration of the default display duplicates global config, so
22031                    // we're calling global config update instead for default display. It will also
22032                    // apply the correct override config.
22033                    changes = updateGlobalConfiguration(values, false /* initLocale */,
22034                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
22035                } else {
22036                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
22037                }
22038            }
22039
22040            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22041        } finally {
22042            if (mWindowManager != null) {
22043                mWindowManager.continueSurfaceLayout();
22044            }
22045        }
22046
22047        if (result != null) {
22048            result.changes = changes;
22049            result.activityRelaunched = !kept;
22050        }
22051        return kept;
22052    }
22053
22054    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
22055            int displayId) {
22056        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
22057        final int changes = mTempConfig.updateFrom(values);
22058        if (changes != 0) {
22059            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
22060                    + mTempConfig + " for displayId=" + displayId);
22061            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
22062
22063            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
22064            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
22065                mAppWarnings.onDensityChanged();
22066
22067                killAllBackgroundProcessesExcept(N,
22068                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
22069            }
22070        }
22071
22072        // Update the configuration with WM first and check if any of the stacks need to be resized
22073        // due to the configuration change. If so, resize the stacks now and do any relaunches if
22074        // necessary. This way we don't need to relaunch again afterwards in
22075        // ensureActivityConfigurationLocked().
22076        if (mWindowManager != null) {
22077            final int[] resizedStacks =
22078                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
22079            if (resizedStacks != null) {
22080                for (int stackId : resizedStacks) {
22081                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
22082                }
22083            }
22084        }
22085
22086        return changes;
22087    }
22088
22089    /** Applies latest configuration and/or visibility updates if needed. */
22090    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
22091        boolean kept = true;
22092        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
22093        // mainStack is null during startup.
22094        if (mainStack != null) {
22095            if (changes != 0 && starting == null) {
22096                // If the configuration changed, and the caller is not already
22097                // in the process of starting an activity, then find the top
22098                // activity to check if its configuration needs to change.
22099                starting = mainStack.topRunningActivityLocked();
22100            }
22101
22102            if (starting != null) {
22103                kept = starting.ensureActivityConfigurationLocked(changes,
22104                        false /* preserveWindow */);
22105                // And we need to make sure at this point that all other activities
22106                // are made visible with the correct configuration.
22107                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
22108                        !PRESERVE_WINDOWS);
22109            }
22110        }
22111
22112        return kept;
22113    }
22114
22115    /** Helper method that requests bounds from WM and applies them to stack. */
22116    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
22117        final Rect newStackBounds = new Rect();
22118        final ActivityStack stack = mStackSupervisor.getStack(stackId);
22119
22120        // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
22121        if (stack == null) {
22122            final StringWriter writer = new StringWriter();
22123            final PrintWriter printWriter = new PrintWriter(writer);
22124            mStackSupervisor.dumpDisplays(printWriter);
22125            printWriter.flush();
22126
22127            Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
22128        }
22129
22130        stack.getBoundsForNewConfiguration(newStackBounds);
22131        mStackSupervisor.resizeStackLocked(
22132                stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
22133                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
22134                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
22135    }
22136
22137    /**
22138     * Decide based on the configuration whether we should show the ANR,
22139     * crash, etc dialogs.  The idea is that if there is no affordance to
22140     * press the on-screen buttons, or the user experience would be more
22141     * greatly impacted than the crash itself, we shouldn't show the dialog.
22142     *
22143     * A thought: SystemUI might also want to get told about this, the Power
22144     * dialog / global actions also might want different behaviors.
22145     */
22146    private static boolean shouldShowDialogs(Configuration config) {
22147        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
22148                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
22149                                   && config.navigation == Configuration.NAVIGATION_NONAV);
22150        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
22151        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
22152                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
22153                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
22154                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
22155        return inputMethodExists && uiModeSupportsDialogs;
22156    }
22157
22158    @Override
22159    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
22160        synchronized (this) {
22161            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
22162            if (srec != null) {
22163                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
22164            }
22165        }
22166        return false;
22167    }
22168
22169    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22170            Intent resultData) {
22171
22172        synchronized (this) {
22173            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22174            if (r != null) {
22175                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22176            }
22177            return false;
22178        }
22179    }
22180
22181    public int getLaunchedFromUid(IBinder activityToken) {
22182        ActivityRecord srec;
22183        synchronized (this) {
22184            srec = ActivityRecord.forTokenLocked(activityToken);
22185        }
22186        if (srec == null) {
22187            return -1;
22188        }
22189        return srec.launchedFromUid;
22190    }
22191
22192    public String getLaunchedFromPackage(IBinder activityToken) {
22193        ActivityRecord srec;
22194        synchronized (this) {
22195            srec = ActivityRecord.forTokenLocked(activityToken);
22196        }
22197        if (srec == null) {
22198            return null;
22199        }
22200        return srec.launchedFromPackage;
22201    }
22202
22203    // =========================================================
22204    // LIFETIME MANAGEMENT
22205    // =========================================================
22206
22207    // Returns whether the app is receiving broadcast.
22208    // If receiving, fetch all broadcast queues which the app is
22209    // the current [or imminent] receiver on.
22210    private boolean isReceivingBroadcastLocked(ProcessRecord app,
22211            ArraySet<BroadcastQueue> receivingQueues) {
22212        final int N = app.curReceivers.size();
22213        if (N > 0) {
22214            for (int i = 0; i < N; i++) {
22215                receivingQueues.add(app.curReceivers.valueAt(i).queue);
22216            }
22217            return true;
22218        }
22219
22220        // It's not the current receiver, but it might be starting up to become one
22221        for (BroadcastQueue queue : mBroadcastQueues) {
22222            final BroadcastRecord r = queue.mPendingBroadcast;
22223            if (r != null && r.curApp == app) {
22224                // found it; report which queue it's in
22225                receivingQueues.add(queue);
22226            }
22227        }
22228
22229        return !receivingQueues.isEmpty();
22230    }
22231
22232    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
22233            int targetUid, ComponentName targetComponent, String targetProcess) {
22234        if (!mTrackingAssociations) {
22235            return null;
22236        }
22237        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22238                = mAssociations.get(targetUid);
22239        if (components == null) {
22240            components = new ArrayMap<>();
22241            mAssociations.put(targetUid, components);
22242        }
22243        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22244        if (sourceUids == null) {
22245            sourceUids = new SparseArray<>();
22246            components.put(targetComponent, sourceUids);
22247        }
22248        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22249        if (sourceProcesses == null) {
22250            sourceProcesses = new ArrayMap<>();
22251            sourceUids.put(sourceUid, sourceProcesses);
22252        }
22253        Association ass = sourceProcesses.get(sourceProcess);
22254        if (ass == null) {
22255            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
22256                    targetProcess);
22257            sourceProcesses.put(sourceProcess, ass);
22258        }
22259        ass.mCount++;
22260        ass.mNesting++;
22261        if (ass.mNesting == 1) {
22262            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
22263            ass.mLastState = sourceState;
22264        }
22265        return ass;
22266    }
22267
22268    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
22269            ComponentName targetComponent) {
22270        if (!mTrackingAssociations) {
22271            return;
22272        }
22273        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22274                = mAssociations.get(targetUid);
22275        if (components == null) {
22276            return;
22277        }
22278        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22279        if (sourceUids == null) {
22280            return;
22281        }
22282        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22283        if (sourceProcesses == null) {
22284            return;
22285        }
22286        Association ass = sourceProcesses.get(sourceProcess);
22287        if (ass == null || ass.mNesting <= 0) {
22288            return;
22289        }
22290        ass.mNesting--;
22291        if (ass.mNesting == 0) {
22292            long uptime = SystemClock.uptimeMillis();
22293            ass.mTime += uptime - ass.mStartTime;
22294            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22295                    += uptime - ass.mLastStateUptime;
22296            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
22297        }
22298    }
22299
22300    private void noteUidProcessState(final int uid, final int state) {
22301        mBatteryStatsService.noteUidProcessState(uid, state);
22302        if (mTrackingAssociations) {
22303            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
22304                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
22305                        = mAssociations.valueAt(i1);
22306                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
22307                    SparseArray<ArrayMap<String, Association>> sourceUids
22308                            = targetComponents.valueAt(i2);
22309                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
22310                    if (sourceProcesses != null) {
22311                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
22312                            Association ass = sourceProcesses.valueAt(i4);
22313                            if (ass.mNesting >= 1) {
22314                                // currently associated
22315                                long uptime = SystemClock.uptimeMillis();
22316                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22317                                        += uptime - ass.mLastStateUptime;
22318                                ass.mLastState = state;
22319                                ass.mLastStateUptime = uptime;
22320                            }
22321                        }
22322                    }
22323                }
22324            }
22325        }
22326    }
22327
22328    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
22329            boolean doingAll, long now) {
22330        if (mAdjSeq == app.adjSeq) {
22331            // This adjustment has already been computed.
22332            return app.curRawAdj;
22333        }
22334
22335        if (app.thread == null) {
22336            app.adjSeq = mAdjSeq;
22337            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22338            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22339            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
22340        }
22341
22342        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
22343        app.adjSource = null;
22344        app.adjTarget = null;
22345        app.empty = false;
22346        app.cached = false;
22347
22348        final int activitiesSize = app.activities.size();
22349
22350        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
22351            // The max adjustment doesn't allow this app to be anything
22352            // below foreground, so it is not worth doing work for it.
22353            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
22354            app.adjType = "fixed";
22355            app.adjSeq = mAdjSeq;
22356            app.curRawAdj = app.maxAdj;
22357            app.foregroundActivities = false;
22358            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22359            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
22360            // System processes can do UI, and when they do we want to have
22361            // them trim their memory after the user leaves the UI.  To
22362            // facilitate this, here we need to determine whether or not it
22363            // is currently showing UI.
22364            app.systemNoUi = true;
22365            if (app == TOP_APP) {
22366                app.systemNoUi = false;
22367                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22368                app.adjType = "pers-top-activity";
22369            } else if (app.hasTopUi) {
22370                app.systemNoUi = false;
22371                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22372                app.adjType = "pers-top-ui";
22373            } else if (activitiesSize > 0) {
22374                for (int j = 0; j < activitiesSize; j++) {
22375                    final ActivityRecord r = app.activities.get(j);
22376                    if (r.visible) {
22377                        app.systemNoUi = false;
22378                    }
22379                }
22380            }
22381            if (!app.systemNoUi) {
22382                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
22383            }
22384            return (app.curAdj=app.maxAdj);
22385        }
22386
22387        app.systemNoUi = false;
22388
22389        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
22390
22391        // Determine the importance of the process, starting with most
22392        // important to least, and assign an appropriate OOM adjustment.
22393        int adj;
22394        int schedGroup;
22395        int procState;
22396        boolean foregroundActivities = false;
22397        mTmpBroadcastQueue.clear();
22398        if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
22399            // The last app on the list is the foreground app.
22400            adj = ProcessList.FOREGROUND_APP_ADJ;
22401            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22402            app.adjType = "top-activity";
22403            foregroundActivities = true;
22404            procState = PROCESS_STATE_CUR_TOP;
22405            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22406        } else if (app.instr != null) {
22407            // Don't want to kill running instrumentation.
22408            adj = ProcessList.FOREGROUND_APP_ADJ;
22409            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22410            app.adjType = "instrumentation";
22411            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22412            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
22413        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
22414            // An app that is currently receiving a broadcast also
22415            // counts as being in the foreground for OOM killer purposes.
22416            // It's placed in a sched group based on the nature of the
22417            // broadcast as reflected by which queue it's active in.
22418            adj = ProcessList.FOREGROUND_APP_ADJ;
22419            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
22420                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22421            app.adjType = "broadcast";
22422            procState = ActivityManager.PROCESS_STATE_RECEIVER;
22423            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
22424        } else if (app.executingServices.size() > 0) {
22425            // An app that is currently executing a service callback also
22426            // counts as being in the foreground.
22427            adj = ProcessList.FOREGROUND_APP_ADJ;
22428            schedGroup = app.execServicesFg ?
22429                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22430            app.adjType = "exec-service";
22431            procState = ActivityManager.PROCESS_STATE_SERVICE;
22432            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
22433            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
22434        } else if (app == TOP_APP) {
22435            adj = ProcessList.FOREGROUND_APP_ADJ;
22436            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22437            app.adjType = "top-sleeping";
22438            foregroundActivities = true;
22439            procState = PROCESS_STATE_CUR_TOP;
22440            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22441        } else {
22442            // As far as we know the process is empty.  We may change our mind later.
22443            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22444            // At this point we don't actually know the adjustment.  Use the cached adj
22445            // value that the caller wants us to.
22446            adj = cachedAdj;
22447            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22448            app.cached = true;
22449            app.empty = true;
22450            app.adjType = "cch-empty";
22451            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
22452        }
22453
22454        // Examine all activities if not already foreground.
22455        if (!foregroundActivities && activitiesSize > 0) {
22456            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
22457            for (int j = 0; j < activitiesSize; j++) {
22458                final ActivityRecord r = app.activities.get(j);
22459                if (r.app != app) {
22460                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
22461                            + " instead of expected " + app);
22462                    if (r.app == null || (r.app.uid == app.uid)) {
22463                        // Only fix things up when they look sane
22464                        r.setProcess(app);
22465                    } else {
22466                        continue;
22467                    }
22468                }
22469                if (r.visible) {
22470                    // App has a visible activity; only upgrade adjustment.
22471                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
22472                        adj = ProcessList.VISIBLE_APP_ADJ;
22473                        app.adjType = "vis-activity";
22474                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22475                    }
22476                    if (procState > PROCESS_STATE_CUR_TOP) {
22477                        procState = PROCESS_STATE_CUR_TOP;
22478                        app.adjType = "vis-activity";
22479                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22480                    }
22481                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22482                    app.cached = false;
22483                    app.empty = false;
22484                    foregroundActivities = true;
22485                    final TaskRecord task = r.getTask();
22486                    if (task != null && minLayer > 0) {
22487                        final int layer = task.mLayerRank;
22488                        if (layer >= 0 && minLayer > layer) {
22489                            minLayer = layer;
22490                        }
22491                    }
22492                    break;
22493                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
22494                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22495                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22496                        app.adjType = "pause-activity";
22497                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22498                    }
22499                    if (procState > PROCESS_STATE_CUR_TOP) {
22500                        procState = PROCESS_STATE_CUR_TOP;
22501                        app.adjType = "pause-activity";
22502                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22503                    }
22504                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22505                    app.cached = false;
22506                    app.empty = false;
22507                    foregroundActivities = true;
22508                } else if (r.state == ActivityState.STOPPING) {
22509                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22510                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22511                        app.adjType = "stop-activity";
22512                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22513                    }
22514                    // For the process state, we will at this point consider the
22515                    // process to be cached.  It will be cached either as an activity
22516                    // or empty depending on whether the activity is finishing.  We do
22517                    // this so that we can treat the process as cached for purposes of
22518                    // memory trimming (determing current memory level, trim command to
22519                    // send to process) since there can be an arbitrary number of stopping
22520                    // processes and they should soon all go into the cached state.
22521                    if (!r.finishing) {
22522                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22523                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22524                            app.adjType = "stop-activity";
22525                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22526                        }
22527                    }
22528                    app.cached = false;
22529                    app.empty = false;
22530                    foregroundActivities = true;
22531                } else {
22532                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22533                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
22534                        app.adjType = "cch-act";
22535                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
22536                    }
22537                }
22538            }
22539            if (adj == ProcessList.VISIBLE_APP_ADJ) {
22540                adj += minLayer;
22541            }
22542        }
22543        if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
22544            procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
22545            app.adjType = "cch-rec";
22546            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached recent: " + app);
22547        }
22548
22549        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22550                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
22551            if (app.foregroundServices) {
22552                // The user is aware of this app, so make it visible.
22553                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22554                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22555                app.cached = false;
22556                app.adjType = "fg-service";
22557                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22558                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
22559            } else if (app.hasOverlayUi) {
22560                // The process is display an overlay UI.
22561                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22562                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22563                app.cached = false;
22564                app.adjType = "has-overlay-ui";
22565                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22566                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
22567            }
22568        }
22569
22570        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22571                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22572            if (app.forcingToImportant != null) {
22573                // This is currently used for toasts...  they are not interactive, and
22574                // we don't want them to cause the app to become fully foreground (and
22575                // thus out of background check), so we yes the best background level we can.
22576                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22577                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22578                app.cached = false;
22579                app.adjType = "force-imp";
22580                app.adjSource = app.forcingToImportant;
22581                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22582                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
22583            }
22584        }
22585
22586        if (app == mHeavyWeightProcess) {
22587            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
22588                // We don't want to kill the current heavy-weight process.
22589                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
22590                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22591                app.cached = false;
22592                app.adjType = "heavy";
22593                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22594            }
22595            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22596                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
22597                app.adjType = "heavy";
22598                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22599            }
22600        }
22601
22602        if (app == mHomeProcess) {
22603            if (adj > ProcessList.HOME_APP_ADJ) {
22604                // This process is hosting what we currently consider to be the
22605                // home app, so we don't want to let it go into the background.
22606                adj = ProcessList.HOME_APP_ADJ;
22607                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22608                app.cached = false;
22609                app.adjType = "home";
22610                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22611            }
22612            if (procState > ActivityManager.PROCESS_STATE_HOME) {
22613                procState = ActivityManager.PROCESS_STATE_HOME;
22614                app.adjType = "home";
22615                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22616            }
22617        }
22618
22619        if (app == mPreviousProcess && app.activities.size() > 0) {
22620            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
22621                // This was the previous process that showed UI to the user.
22622                // We want to try to keep it around more aggressively, to give
22623                // a good experience around switching between two apps.
22624                adj = ProcessList.PREVIOUS_APP_ADJ;
22625                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22626                app.cached = false;
22627                app.adjType = "previous";
22628                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
22629            }
22630            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22631                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22632                app.adjType = "previous";
22633                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
22634            }
22635        }
22636
22637        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
22638                + " reason=" + app.adjType);
22639
22640        // By default, we use the computed adjustment.  It may be changed if
22641        // there are applications dependent on our services or providers, but
22642        // this gives us a baseline and makes sure we don't get into an
22643        // infinite recursion.
22644        app.adjSeq = mAdjSeq;
22645        app.curRawAdj = adj;
22646        app.hasStartedServices = false;
22647
22648        if (mBackupTarget != null && app == mBackupTarget.app) {
22649            // If possible we want to avoid killing apps while they're being backed up
22650            if (adj > ProcessList.BACKUP_APP_ADJ) {
22651                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
22652                adj = ProcessList.BACKUP_APP_ADJ;
22653                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22654                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22655                }
22656                app.adjType = "backup";
22657                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22658                app.cached = false;
22659            }
22660            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
22661                procState = ActivityManager.PROCESS_STATE_BACKUP;
22662                app.adjType = "backup";
22663                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22664            }
22665        }
22666
22667        boolean mayBeTop = false;
22668        String mayBeTopType = null;
22669        Object mayBeTopSource = null;
22670        Object mayBeTopTarget = null;
22671
22672        for (int is = app.services.size()-1;
22673                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22674                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22675                        || procState > ActivityManager.PROCESS_STATE_TOP);
22676                is--) {
22677            ServiceRecord s = app.services.valueAt(is);
22678            if (s.startRequested) {
22679                app.hasStartedServices = true;
22680                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
22681                    procState = ActivityManager.PROCESS_STATE_SERVICE;
22682                    app.adjType = "started-services";
22683                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
22684                }
22685                if (app.hasShownUi && app != mHomeProcess) {
22686                    // If this process has shown some UI, let it immediately
22687                    // go to the LRU list because it may be pretty heavy with
22688                    // UI stuff.  We'll tag it with a label just to help
22689                    // debug and understand what is going on.
22690                    if (adj > ProcessList.SERVICE_ADJ) {
22691                        app.adjType = "cch-started-ui-services";
22692                    }
22693                } else {
22694                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
22695                        // This service has seen some activity within
22696                        // recent memory, so we will keep its process ahead
22697                        // of the background processes.
22698                        if (adj > ProcessList.SERVICE_ADJ) {
22699                            adj = ProcessList.SERVICE_ADJ;
22700                            app.adjType = "started-services";
22701                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
22702                            app.cached = false;
22703                        }
22704                    }
22705                    // If we have let the service slide into the background
22706                    // state, still have some text describing what it is doing
22707                    // even though the service no longer has an impact.
22708                    if (adj > ProcessList.SERVICE_ADJ) {
22709                        app.adjType = "cch-started-services";
22710                    }
22711                }
22712            }
22713
22714            for (int conni = s.connections.size()-1;
22715                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22716                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22717                            || procState > ActivityManager.PROCESS_STATE_TOP);
22718                    conni--) {
22719                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
22720                for (int i = 0;
22721                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
22722                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22723                                || procState > ActivityManager.PROCESS_STATE_TOP);
22724                        i++) {
22725                    // XXX should compute this based on the max of
22726                    // all connected clients.
22727                    ConnectionRecord cr = clist.get(i);
22728                    if (cr.binding.client == app) {
22729                        // Binding to ourself is not interesting.
22730                        continue;
22731                    }
22732
22733                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
22734                        ProcessRecord client = cr.binding.client;
22735                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
22736                                TOP_APP, doingAll, now);
22737                        int clientProcState = client.curProcState;
22738                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22739                            // If the other app is cached for any reason, for purposes here
22740                            // we are going to consider it empty.  The specific cached state
22741                            // doesn't propagate except under certain conditions.
22742                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22743                        }
22744                        String adjType = null;
22745                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
22746                            // Not doing bind OOM management, so treat
22747                            // this guy more like a started service.
22748                            if (app.hasShownUi && app != mHomeProcess) {
22749                                // If this process has shown some UI, let it immediately
22750                                // go to the LRU list because it may be pretty heavy with
22751                                // UI stuff.  We'll tag it with a label just to help
22752                                // debug and understand what is going on.
22753                                if (adj > clientAdj) {
22754                                    adjType = "cch-bound-ui-services";
22755                                }
22756                                app.cached = false;
22757                                clientAdj = adj;
22758                                clientProcState = procState;
22759                            } else {
22760                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
22761                                    // This service has not seen activity within
22762                                    // recent memory, so allow it to drop to the
22763                                    // LRU list if there is no other reason to keep
22764                                    // it around.  We'll also tag it with a label just
22765                                    // to help debug and undertand what is going on.
22766                                    if (adj > clientAdj) {
22767                                        adjType = "cch-bound-services";
22768                                    }
22769                                    clientAdj = adj;
22770                                }
22771                            }
22772                        }
22773                        if (adj > clientAdj) {
22774                            // If this process has recently shown UI, and
22775                            // the process that is binding to it is less
22776                            // important than being visible, then we don't
22777                            // care about the binding as much as we care
22778                            // about letting this process get into the LRU
22779                            // list to be killed and restarted if needed for
22780                            // memory.
22781                            if (app.hasShownUi && app != mHomeProcess
22782                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22783                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
22784                                    adjType = "cch-bound-ui-services";
22785                                }
22786                            } else {
22787                                int newAdj;
22788                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
22789                                        |Context.BIND_IMPORTANT)) != 0) {
22790                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
22791                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
22792                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
22793                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
22794                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22795                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
22796                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
22797                                    newAdj = clientAdj;
22798                                } else {
22799                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
22800                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
22801                                    } else {
22802                                        newAdj = adj;
22803                                    }
22804                                }
22805                                if (!client.cached) {
22806                                    app.cached = false;
22807                                }
22808                                if (adj >  newAdj) {
22809                                    adj = newAdj;
22810                                    adjType = "service";
22811                                }
22812                            }
22813                        }
22814                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
22815                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
22816                            // This will treat important bound services identically to
22817                            // the top app, which may behave differently than generic
22818                            // foreground work.
22819                            if (client.curSchedGroup > schedGroup) {
22820                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
22821                                    schedGroup = client.curSchedGroup;
22822                                } else {
22823                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22824                                }
22825                            }
22826                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
22827                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
22828                                    // Special handling of clients who are in the top state.
22829                                    // We *may* want to consider this process to be in the
22830                                    // top state as well, but only if there is not another
22831                                    // reason for it to be running.  Being on the top is a
22832                                    // special state, meaning you are specifically running
22833                                    // for the current top app.  If the process is already
22834                                    // running in the background for some other reason, it
22835                                    // is more important to continue considering it to be
22836                                    // in the background state.
22837                                    mayBeTop = true;
22838                                    mayBeTopType = "service";
22839                                    mayBeTopSource = cr.binding.client;
22840                                    mayBeTopTarget = s.name;
22841                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22842                                } else {
22843                                    // Special handling for above-top states (persistent
22844                                    // processes).  These should not bring the current process
22845                                    // into the top state, since they are not on top.  Instead
22846                                    // give them the best state after that.
22847                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
22848                                        clientProcState =
22849                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22850                                    } else if (mWakefulness
22851                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
22852                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
22853                                                    != 0) {
22854                                        clientProcState =
22855                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22856                                    } else {
22857                                        clientProcState =
22858                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22859                                    }
22860                                }
22861                            }
22862                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
22863                            if (clientProcState <
22864                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22865                                clientProcState =
22866                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22867                            }
22868                        } else {
22869                            if (clientProcState <
22870                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
22871                                clientProcState =
22872                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
22873                            }
22874                        }
22875                        if (procState > clientProcState) {
22876                            procState = clientProcState;
22877                            if (adjType == null) {
22878                                adjType = "service";
22879                            }
22880                        }
22881                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22882                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
22883                            app.pendingUiClean = true;
22884                        }
22885                        if (adjType != null) {
22886                            app.adjType = adjType;
22887                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
22888                                    .REASON_SERVICE_IN_USE;
22889                            app.adjSource = cr.binding.client;
22890                            app.adjSourceProcState = clientProcState;
22891                            app.adjTarget = s.name;
22892                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
22893                                    + ": " + app + ", due to " + cr.binding.client
22894                                    + " adj=" + adj + " procState=" + procState);
22895                        }
22896                    }
22897                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
22898                        app.treatLikeActivity = true;
22899                    }
22900                    final ActivityRecord a = cr.activity;
22901                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
22902                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
22903                            (a.visible || a.state == ActivityState.RESUMED ||
22904                             a.state == ActivityState.PAUSING)) {
22905                            adj = ProcessList.FOREGROUND_APP_ADJ;
22906                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
22907                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
22908                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
22909                                } else {
22910                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22911                                }
22912                            }
22913                            app.cached = false;
22914                            app.adjType = "service";
22915                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
22916                                    .REASON_SERVICE_IN_USE;
22917                            app.adjSource = a;
22918                            app.adjSourceProcState = procState;
22919                            app.adjTarget = s.name;
22920                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
22921                                    + app);
22922                        }
22923                    }
22924                }
22925            }
22926        }
22927
22928        for (int provi = app.pubProviders.size()-1;
22929                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22930                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22931                        || procState > ActivityManager.PROCESS_STATE_TOP);
22932                provi--) {
22933            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
22934            for (int i = cpr.connections.size()-1;
22935                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22936                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22937                            || procState > ActivityManager.PROCESS_STATE_TOP);
22938                    i--) {
22939                ContentProviderConnection conn = cpr.connections.get(i);
22940                ProcessRecord client = conn.client;
22941                if (client == app) {
22942                    // Being our own client is not interesting.
22943                    continue;
22944                }
22945                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
22946                int clientProcState = client.curProcState;
22947                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22948                    // If the other app is cached for any reason, for purposes here
22949                    // we are going to consider it empty.
22950                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22951                }
22952                String adjType = null;
22953                if (adj > clientAdj) {
22954                    if (app.hasShownUi && app != mHomeProcess
22955                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22956                        adjType = "cch-ui-provider";
22957                    } else {
22958                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
22959                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
22960                        adjType = "provider";
22961                    }
22962                    app.cached &= client.cached;
22963                }
22964                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
22965                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
22966                        // Special handling of clients who are in the top state.
22967                        // We *may* want to consider this process to be in the
22968                        // top state as well, but only if there is not another
22969                        // reason for it to be running.  Being on the top is a
22970                        // special state, meaning you are specifically running
22971                        // for the current top app.  If the process is already
22972                        // running in the background for some other reason, it
22973                        // is more important to continue considering it to be
22974                        // in the background state.
22975                        mayBeTop = true;
22976                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22977                        mayBeTopType = adjType = "provider-top";
22978                        mayBeTopSource = client;
22979                        mayBeTopTarget = cpr.name;
22980                    } else {
22981                        // Special handling for above-top states (persistent
22982                        // processes).  These should not bring the current process
22983                        // into the top state, since they are not on top.  Instead
22984                        // give them the best state after that.
22985                        clientProcState =
22986                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22987                        if (adjType == null) {
22988                            adjType = "provider";
22989                        }
22990                    }
22991                }
22992                if (procState > clientProcState) {
22993                    procState = clientProcState;
22994                }
22995                if (client.curSchedGroup > schedGroup) {
22996                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22997                }
22998                if (adjType != null) {
22999                    app.adjType = adjType;
23000                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23001                            .REASON_PROVIDER_IN_USE;
23002                    app.adjSource = client;
23003                    app.adjSourceProcState = clientProcState;
23004                    app.adjTarget = cpr.name;
23005                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
23006                            + ": " + app + ", due to " + client
23007                            + " adj=" + adj + " procState=" + procState);
23008                }
23009            }
23010            // If the provider has external (non-framework) process
23011            // dependencies, ensure that its adjustment is at least
23012            // FOREGROUND_APP_ADJ.
23013            if (cpr.hasExternalProcessHandles()) {
23014                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
23015                    adj = ProcessList.FOREGROUND_APP_ADJ;
23016                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23017                    app.cached = false;
23018                    app.adjType = "ext-provider";
23019                    app.adjTarget = cpr.name;
23020                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
23021                }
23022                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23023                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23024                }
23025            }
23026        }
23027
23028        if (app.lastProviderTime > 0 &&
23029                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
23030            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23031                adj = ProcessList.PREVIOUS_APP_ADJ;
23032                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23033                app.cached = false;
23034                app.adjType = "recent-provider";
23035                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
23036            }
23037            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23038                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23039                app.adjType = "recent-provider";
23040                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
23041            }
23042        }
23043
23044        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
23045            // A client of one of our services or providers is in the top state.  We
23046            // *may* want to be in the top state, but not if we are already running in
23047            // the background for some other reason.  For the decision here, we are going
23048            // to pick out a few specific states that we want to remain in when a client
23049            // is top (states that tend to be longer-term) and otherwise allow it to go
23050            // to the top state.
23051            switch (procState) {
23052                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
23053                case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
23054                    // Something else is keeping it at this level, just leave it.
23055                    break;
23056                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
23057                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
23058                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
23059                case ActivityManager.PROCESS_STATE_SERVICE:
23060                    // These all are longer-term states, so pull them up to the top
23061                    // of the background states, but not all the way to the top state.
23062                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23063                    app.adjType = mayBeTopType;
23064                    app.adjSource = mayBeTopSource;
23065                    app.adjTarget = mayBeTopTarget;
23066                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
23067                            + ": " + app + ", due to " + mayBeTopSource
23068                            + " adj=" + adj + " procState=" + procState);
23069                    break;
23070                default:
23071                    // Otherwise, top is a better choice, so take it.
23072                    procState = ActivityManager.PROCESS_STATE_TOP;
23073                    app.adjType = mayBeTopType;
23074                    app.adjSource = mayBeTopSource;
23075                    app.adjTarget = mayBeTopTarget;
23076                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
23077                            + ": " + app + ", due to " + mayBeTopSource
23078                            + " adj=" + adj + " procState=" + procState);
23079                    break;
23080            }
23081        }
23082
23083        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
23084            if (app.hasClientActivities) {
23085                // This is a cached process, but with client activities.  Mark it so.
23086                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
23087                app.adjType = "cch-client-act";
23088            } else if (app.treatLikeActivity) {
23089                // This is a cached process, but somebody wants us to treat it like it has
23090                // an activity, okay!
23091                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23092                app.adjType = "cch-as-act";
23093            }
23094        }
23095
23096        if (adj == ProcessList.SERVICE_ADJ) {
23097            if (doingAll) {
23098                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
23099                mNewNumServiceProcs++;
23100                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
23101                if (!app.serviceb) {
23102                    // This service isn't far enough down on the LRU list to
23103                    // normally be a B service, but if we are low on RAM and it
23104                    // is large we want to force it down since we would prefer to
23105                    // keep launcher over it.
23106                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
23107                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
23108                        app.serviceHighRam = true;
23109                        app.serviceb = true;
23110                        //Slog.i(TAG, "ADJ " + app + " high ram!");
23111                    } else {
23112                        mNewNumAServiceProcs++;
23113                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
23114                    }
23115                } else {
23116                    app.serviceHighRam = false;
23117                }
23118            }
23119            if (app.serviceb) {
23120                adj = ProcessList.SERVICE_B_ADJ;
23121            }
23122        }
23123
23124        app.curRawAdj = adj;
23125
23126        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
23127        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
23128        if (adj > app.maxAdj) {
23129            adj = app.maxAdj;
23130            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
23131                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23132            }
23133        }
23134
23135        // Do final modification to adj.  Everything we do between here and applying
23136        // the final setAdj must be done in this function, because we will also use
23137        // it when computing the final cached adj later.  Note that we don't need to
23138        // worry about this for max adj above, since max adj will always be used to
23139        // keep it out of the cached vaues.
23140        app.curAdj = app.modifyRawOomAdj(adj);
23141        app.curSchedGroup = schedGroup;
23142        app.curProcState = procState;
23143        app.foregroundActivities = foregroundActivities;
23144
23145        return app.curRawAdj;
23146    }
23147
23148    /**
23149     * Record new PSS sample for a process.
23150     */
23151    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
23152            long rss, int statType, long pssDuration, long now) {
23153        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
23154                swapPss * 1024, rss * 1024, statType, procState, pssDuration);
23155        proc.lastPssTime = now;
23156        proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
23157        if (DEBUG_PSS) Slog.d(TAG_PSS,
23158                "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
23159                + " state=" + ProcessList.makeProcStateString(procState));
23160        if (proc.initialIdlePss == 0) {
23161            proc.initialIdlePss = pss;
23162        }
23163        proc.lastPss = pss;
23164        proc.lastSwapPss = swapPss;
23165        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
23166            proc.lastCachedPss = pss;
23167            proc.lastCachedSwapPss = swapPss;
23168        }
23169
23170        final SparseArray<Pair<Long, String>> watchUids
23171                = mMemWatchProcesses.getMap().get(proc.processName);
23172        Long check = null;
23173        if (watchUids != null) {
23174            Pair<Long, String> val = watchUids.get(proc.uid);
23175            if (val == null) {
23176                val = watchUids.get(0);
23177            }
23178            if (val != null) {
23179                check = val.first;
23180            }
23181        }
23182        if (check != null) {
23183            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
23184                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23185                if (!isDebuggable) {
23186                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
23187                        isDebuggable = true;
23188                    }
23189                }
23190                if (isDebuggable) {
23191                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
23192                    final ProcessRecord myProc = proc;
23193                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
23194                    mMemWatchDumpProcName = proc.processName;
23195                    mMemWatchDumpFile = heapdumpFile.toString();
23196                    mMemWatchDumpPid = proc.pid;
23197                    mMemWatchDumpUid = proc.uid;
23198                    BackgroundThread.getHandler().post(new Runnable() {
23199                        @Override
23200                        public void run() {
23201                            revokeUriPermission(ActivityThread.currentActivityThread()
23202                                            .getApplicationThread(),
23203                                    null, DumpHeapActivity.JAVA_URI,
23204                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
23205                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
23206                                    UserHandle.myUserId());
23207                            ParcelFileDescriptor fd = null;
23208                            try {
23209                                heapdumpFile.delete();
23210                                fd = ParcelFileDescriptor.open(heapdumpFile,
23211                                        ParcelFileDescriptor.MODE_CREATE |
23212                                                ParcelFileDescriptor.MODE_TRUNCATE |
23213                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
23214                                                ParcelFileDescriptor.MODE_APPEND);
23215                                IApplicationThread thread = myProc.thread;
23216                                if (thread != null) {
23217                                    try {
23218                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
23219                                                "Requesting dump heap from "
23220                                                + myProc + " to " + heapdumpFile);
23221                                        thread.dumpHeap(/* managed= */ true,
23222                                                /* mallocInfo= */ false, /* runGc= */ false,
23223                                                heapdumpFile.toString(), fd);
23224                                    } catch (RemoteException e) {
23225                                    }
23226                                }
23227                            } catch (FileNotFoundException e) {
23228                                e.printStackTrace();
23229                            } finally {
23230                                if (fd != null) {
23231                                    try {
23232                                        fd.close();
23233                                    } catch (IOException e) {
23234                                    }
23235                                }
23236                            }
23237                        }
23238                    });
23239                } else {
23240                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
23241                            + ", but debugging not enabled");
23242                }
23243            }
23244        }
23245    }
23246
23247    /**
23248     * Schedule PSS collection of a process.
23249     */
23250    void requestPssLocked(ProcessRecord proc, int procState) {
23251        if (mPendingPssProcesses.contains(proc)) {
23252            return;
23253        }
23254        if (mPendingPssProcesses.size() == 0) {
23255            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23256        }
23257        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
23258        proc.pssProcState = procState;
23259        proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
23260        mPendingPssProcesses.add(proc);
23261    }
23262
23263    /**
23264     * Schedule PSS collection of all processes.
23265     */
23266    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
23267        if (!always) {
23268            if (now < (mLastFullPssTime +
23269                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
23270                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
23271                return;
23272            }
23273        }
23274        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs!  memLowered=" + memLowered);
23275        mLastFullPssTime = now;
23276        mFullPssPending = true;
23277        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
23278        mPendingPssProcesses.clear();
23279        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23280            ProcessRecord app = mLruProcesses.get(i);
23281            if (app.thread == null
23282                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
23283                continue;
23284            }
23285            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
23286                app.pssProcState = app.setProcState;
23287                app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
23288                        : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
23289                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
23290                        app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
23291                mPendingPssProcesses.add(app);
23292            }
23293        }
23294        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23295    }
23296
23297    public void setTestPssMode(boolean enabled) {
23298        synchronized (this) {
23299            mTestPssMode = enabled;
23300            if (enabled) {
23301                // Whenever we enable the mode, we want to take a snapshot all of current
23302                // process mem use.
23303                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
23304            }
23305        }
23306    }
23307
23308    /**
23309     * Ask a given process to GC right now.
23310     */
23311    final void performAppGcLocked(ProcessRecord app) {
23312        try {
23313            app.lastRequestedGc = SystemClock.uptimeMillis();
23314            if (app.thread != null) {
23315                if (app.reportLowMemory) {
23316                    app.reportLowMemory = false;
23317                    app.thread.scheduleLowMemory();
23318                } else {
23319                    app.thread.processInBackground();
23320                }
23321            }
23322        } catch (Exception e) {
23323            // whatever.
23324        }
23325    }
23326
23327    /**
23328     * Returns true if things are idle enough to perform GCs.
23329     */
23330    private final boolean canGcNowLocked() {
23331        boolean processingBroadcasts = false;
23332        for (BroadcastQueue q : mBroadcastQueues) {
23333            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
23334                processingBroadcasts = true;
23335            }
23336        }
23337        return !processingBroadcasts
23338                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
23339    }
23340
23341    /**
23342     * Perform GCs on all processes that are waiting for it, but only
23343     * if things are idle.
23344     */
23345    final void performAppGcsLocked() {
23346        final int N = mProcessesToGc.size();
23347        if (N <= 0) {
23348            return;
23349        }
23350        if (canGcNowLocked()) {
23351            while (mProcessesToGc.size() > 0) {
23352                ProcessRecord proc = mProcessesToGc.remove(0);
23353                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
23354                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
23355                            <= SystemClock.uptimeMillis()) {
23356                        // To avoid spamming the system, we will GC processes one
23357                        // at a time, waiting a few seconds between each.
23358                        performAppGcLocked(proc);
23359                        scheduleAppGcsLocked();
23360                        return;
23361                    } else {
23362                        // It hasn't been long enough since we last GCed this
23363                        // process...  put it in the list to wait for its time.
23364                        addProcessToGcListLocked(proc);
23365                        break;
23366                    }
23367                }
23368            }
23369
23370            scheduleAppGcsLocked();
23371        }
23372    }
23373
23374    /**
23375     * If all looks good, perform GCs on all processes waiting for them.
23376     */
23377    final void performAppGcsIfAppropriateLocked() {
23378        if (canGcNowLocked()) {
23379            performAppGcsLocked();
23380            return;
23381        }
23382        // Still not idle, wait some more.
23383        scheduleAppGcsLocked();
23384    }
23385
23386    /**
23387     * Schedule the execution of all pending app GCs.
23388     */
23389    final void scheduleAppGcsLocked() {
23390        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
23391
23392        if (mProcessesToGc.size() > 0) {
23393            // Schedule a GC for the time to the next process.
23394            ProcessRecord proc = mProcessesToGc.get(0);
23395            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
23396
23397            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
23398            long now = SystemClock.uptimeMillis();
23399            if (when < (now+mConstants.GC_TIMEOUT)) {
23400                when = now + mConstants.GC_TIMEOUT;
23401            }
23402            mHandler.sendMessageAtTime(msg, when);
23403        }
23404    }
23405
23406    /**
23407     * Add a process to the array of processes waiting to be GCed.  Keeps the
23408     * list in sorted order by the last GC time.  The process can't already be
23409     * on the list.
23410     */
23411    final void addProcessToGcListLocked(ProcessRecord proc) {
23412        boolean added = false;
23413        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
23414            if (mProcessesToGc.get(i).lastRequestedGc <
23415                    proc.lastRequestedGc) {
23416                added = true;
23417                mProcessesToGc.add(i+1, proc);
23418                break;
23419            }
23420        }
23421        if (!added) {
23422            mProcessesToGc.add(0, proc);
23423        }
23424    }
23425
23426    /**
23427     * Set up to ask a process to GC itself.  This will either do it
23428     * immediately, or put it on the list of processes to gc the next
23429     * time things are idle.
23430     */
23431    final void scheduleAppGcLocked(ProcessRecord app) {
23432        long now = SystemClock.uptimeMillis();
23433        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
23434            return;
23435        }
23436        if (!mProcessesToGc.contains(app)) {
23437            addProcessToGcListLocked(app);
23438            scheduleAppGcsLocked();
23439        }
23440    }
23441
23442    final void checkExcessivePowerUsageLocked() {
23443        updateCpuStatsNow();
23444
23445        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
23446        boolean doCpuKills = true;
23447        if (mLastPowerCheckUptime == 0) {
23448            doCpuKills = false;
23449        }
23450        final long curUptime = SystemClock.uptimeMillis();
23451        final long uptimeSince = curUptime - mLastPowerCheckUptime;
23452        mLastPowerCheckUptime = curUptime;
23453        int i = mLruProcesses.size();
23454        while (i > 0) {
23455            i--;
23456            ProcessRecord app = mLruProcesses.get(i);
23457            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
23458                if (app.lastCpuTime <= 0) {
23459                    continue;
23460                }
23461                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
23462                if (DEBUG_POWER) {
23463                    StringBuilder sb = new StringBuilder(128);
23464                    sb.append("CPU for ");
23465                    app.toShortString(sb);
23466                    sb.append(": over ");
23467                    TimeUtils.formatDuration(uptimeSince, sb);
23468                    sb.append(" used ");
23469                    TimeUtils.formatDuration(cputimeUsed, sb);
23470                    sb.append(" (");
23471                    sb.append((cputimeUsed*100)/uptimeSince);
23472                    sb.append("%)");
23473                    Slog.i(TAG_POWER, sb.toString());
23474                }
23475                // If the process has used too much CPU over the last duration, the
23476                // user probably doesn't want this, so kill!
23477                if (doCpuKills && uptimeSince > 0) {
23478                    // What is the limit for this process?
23479                    int cpuLimit;
23480                    long checkDur = curUptime - app.whenUnimportant;
23481                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
23482                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
23483                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
23484                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
23485                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
23486                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
23487                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
23488                    } else {
23489                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
23490                    }
23491                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
23492                        synchronized (stats) {
23493                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
23494                                    uptimeSince, cputimeUsed);
23495                        }
23496                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
23497                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
23498                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
23499                    }
23500                }
23501                app.lastCpuTime = app.curCpuTime;
23502            }
23503        }
23504    }
23505
23506    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
23507            long nowElapsed) {
23508        boolean success = true;
23509
23510        if (app.curRawAdj != app.setRawAdj) {
23511            app.setRawAdj = app.curRawAdj;
23512        }
23513
23514        int changes = 0;
23515
23516        if (app.curAdj != app.setAdj) {
23517            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
23518            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
23519                String msg = "Set " + app.pid + " " + app.processName + " adj "
23520                        + app.curAdj + ": " + app.adjType;
23521                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23522            }
23523            app.setAdj = app.curAdj;
23524            app.verifiedAdj = ProcessList.INVALID_ADJ;
23525        }
23526
23527        if (app.setSchedGroup != app.curSchedGroup) {
23528            int oldSchedGroup = app.setSchedGroup;
23529            app.setSchedGroup = app.curSchedGroup;
23530            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
23531                String msg = "Setting sched group of " + app.processName
23532                        + " to " + app.curSchedGroup;
23533                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23534            }
23535            if (app.waitingToKill != null && app.curReceivers.isEmpty()
23536                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
23537                app.kill(app.waitingToKill, true);
23538                success = false;
23539            } else {
23540                int processGroup;
23541                switch (app.curSchedGroup) {
23542                    case ProcessList.SCHED_GROUP_BACKGROUND:
23543                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
23544                        break;
23545                    case ProcessList.SCHED_GROUP_TOP_APP:
23546                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
23547                        processGroup = THREAD_GROUP_TOP_APP;
23548                        break;
23549                    default:
23550                        processGroup = THREAD_GROUP_DEFAULT;
23551                        break;
23552                }
23553                long oldId = Binder.clearCallingIdentity();
23554                try {
23555                    setProcessGroup(app.pid, processGroup);
23556                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
23557                        // do nothing if we already switched to RT
23558                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23559                            mVrController.onTopProcChangedLocked(app);
23560                            if (mUseFifoUiScheduling) {
23561                                // Switch UI pipeline for app to SCHED_FIFO
23562                                app.savedPriority = Process.getThreadPriority(app.pid);
23563                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
23564                                if (app.renderThreadTid != 0) {
23565                                    scheduleAsFifoPriority(app.renderThreadTid,
23566                                        /* suppressLogs */true);
23567                                    if (DEBUG_OOM_ADJ) {
23568                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
23569                                            app.renderThreadTid + ") to FIFO");
23570                                    }
23571                                } else {
23572                                    if (DEBUG_OOM_ADJ) {
23573                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
23574                                    }
23575                                }
23576                            } else {
23577                                // Boost priority for top app UI and render threads
23578                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
23579                                if (app.renderThreadTid != 0) {
23580                                    try {
23581                                        setThreadPriority(app.renderThreadTid,
23582                                                TOP_APP_PRIORITY_BOOST);
23583                                    } catch (IllegalArgumentException e) {
23584                                        // thread died, ignore
23585                                    }
23586                                }
23587                            }
23588                        }
23589                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
23590                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23591                        mVrController.onTopProcChangedLocked(app);
23592                        if (mUseFifoUiScheduling) {
23593                            try {
23594                                // Reset UI pipeline to SCHED_OTHER
23595                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
23596                                setThreadPriority(app.pid, app.savedPriority);
23597                                if (app.renderThreadTid != 0) {
23598                                    setThreadScheduler(app.renderThreadTid,
23599                                        SCHED_OTHER, 0);
23600                                    setThreadPriority(app.renderThreadTid, -4);
23601                                }
23602                            } catch (IllegalArgumentException e) {
23603                                Slog.w(TAG,
23604                                        "Failed to set scheduling policy, thread does not exist:\n"
23605                                                + e);
23606                            } catch (SecurityException e) {
23607                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
23608                            }
23609                        } else {
23610                            // Reset priority for top app UI and render threads
23611                            setThreadPriority(app.pid, 0);
23612                            if (app.renderThreadTid != 0) {
23613                                setThreadPriority(app.renderThreadTid, 0);
23614                            }
23615                        }
23616                    }
23617                } catch (Exception e) {
23618                    if (false) {
23619                        Slog.w(TAG, "Failed setting process group of " + app.pid
23620                                + " to " + app.curSchedGroup);
23621                        Slog.w(TAG, "at location", e);
23622                    }
23623                } finally {
23624                    Binder.restoreCallingIdentity(oldId);
23625                }
23626            }
23627        }
23628        if (app.repForegroundActivities != app.foregroundActivities) {
23629            app.repForegroundActivities = app.foregroundActivities;
23630            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
23631        }
23632        if (app.repProcState != app.curProcState) {
23633            app.repProcState = app.curProcState;
23634            if (app.thread != null) {
23635                try {
23636                    if (false) {
23637                        //RuntimeException h = new RuntimeException("here");
23638                        Slog.i(TAG, "Sending new process state " + app.repProcState
23639                                + " to " + app /*, h*/);
23640                    }
23641                    app.thread.setProcessState(app.repProcState);
23642                } catch (RemoteException e) {
23643                }
23644            }
23645        }
23646        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
23647                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
23648            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
23649                // Experimental code to more aggressively collect pss while
23650                // running test...  the problem is that this tends to collect
23651                // the data right when a process is transitioning between process
23652                // states, which well tend to give noisy data.
23653                long start = SystemClock.uptimeMillis();
23654                long startTime = SystemClock.currentThreadTimeMillis();
23655                long pss = Debug.getPss(app.pid, mTmpLong, null);
23656                long endTime = SystemClock.currentThreadTimeMillis();
23657                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
23658                        mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
23659                mPendingPssProcesses.remove(app);
23660                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
23661                        + " to " + app.curProcState + ": "
23662                        + (SystemClock.uptimeMillis()-start) + "ms");
23663            }
23664            app.lastStateTime = now;
23665            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
23666                    app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
23667            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
23668                    + ProcessList.makeProcStateString(app.setProcState) + " to "
23669                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
23670                    + (app.nextPssTime-now) + ": " + app);
23671        } else {
23672            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
23673                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
23674                    mTestPssMode)))) {
23675                requestPssLocked(app, app.setProcState);
23676                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
23677                        app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
23678            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
23679                    "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
23680        }
23681        if (app.setProcState != app.curProcState) {
23682            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
23683                String msg = "Proc state change of " + app.processName
23684                        + " to " + app.curProcState;
23685                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23686            }
23687            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
23688            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
23689            if (setImportant && !curImportant) {
23690                // This app is no longer something we consider important enough to allow to
23691                // use arbitrary amounts of battery power.  Note
23692                // its current CPU time to later know to kill it if
23693                // it is not behaving well.
23694                app.whenUnimportant = now;
23695                app.lastCpuTime = 0;
23696            }
23697            // Inform UsageStats of important process state change
23698            // Must be called before updating setProcState
23699            maybeUpdateUsageStatsLocked(app, nowElapsed);
23700
23701            app.setProcState = app.curProcState;
23702            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
23703                app.notCachedSinceIdle = false;
23704            }
23705            if (!doingAll) {
23706                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
23707            } else {
23708                app.procStateChanged = true;
23709            }
23710        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
23711                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
23712            // For apps that sit around for a long time in the interactive state, we need
23713            // to report this at least once a day so they don't go idle.
23714            maybeUpdateUsageStatsLocked(app, nowElapsed);
23715        }
23716
23717        if (changes != 0) {
23718            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23719                    "Changes in " + app + ": " + changes);
23720            int i = mPendingProcessChanges.size()-1;
23721            ProcessChangeItem item = null;
23722            while (i >= 0) {
23723                item = mPendingProcessChanges.get(i);
23724                if (item.pid == app.pid) {
23725                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23726                            "Re-using existing item: " + item);
23727                    break;
23728                }
23729                i--;
23730            }
23731            if (i < 0) {
23732                // No existing item in pending changes; need a new one.
23733                final int NA = mAvailProcessChanges.size();
23734                if (NA > 0) {
23735                    item = mAvailProcessChanges.remove(NA-1);
23736                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23737                            "Retrieving available item: " + item);
23738                } else {
23739                    item = new ProcessChangeItem();
23740                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23741                            "Allocating new item: " + item);
23742                }
23743                item.changes = 0;
23744                item.pid = app.pid;
23745                item.uid = app.info.uid;
23746                if (mPendingProcessChanges.size() == 0) {
23747                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23748                            "*** Enqueueing dispatch processes changed!");
23749                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
23750                }
23751                mPendingProcessChanges.add(item);
23752            }
23753            item.changes |= changes;
23754            item.foregroundActivities = app.repForegroundActivities;
23755            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23756                    "Item " + Integer.toHexString(System.identityHashCode(item))
23757                    + " " + app.toShortString() + ": changes=" + item.changes
23758                    + " foreground=" + item.foregroundActivities
23759                    + " type=" + app.adjType + " source=" + app.adjSource
23760                    + " target=" + app.adjTarget);
23761        }
23762
23763        return success;
23764    }
23765
23766    private boolean isEphemeralLocked(int uid) {
23767        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
23768        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
23769            return false;
23770        }
23771        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
23772                packages[0]);
23773    }
23774
23775    @VisibleForTesting
23776    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
23777        final UidRecord.ChangeItem pendingChange;
23778        if (uidRec == null || uidRec.pendingChange == null) {
23779            if (mPendingUidChanges.size() == 0) {
23780                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23781                        "*** Enqueueing dispatch uid changed!");
23782                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
23783            }
23784            final int NA = mAvailUidChanges.size();
23785            if (NA > 0) {
23786                pendingChange = mAvailUidChanges.remove(NA-1);
23787                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23788                        "Retrieving available item: " + pendingChange);
23789            } else {
23790                pendingChange = new UidRecord.ChangeItem();
23791                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23792                        "Allocating new item: " + pendingChange);
23793            }
23794            if (uidRec != null) {
23795                uidRec.pendingChange = pendingChange;
23796                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
23797                    // If this uid is going away, and we haven't yet reported it is gone,
23798                    // then do so now.
23799                    change |= UidRecord.CHANGE_IDLE;
23800                }
23801            } else if (uid < 0) {
23802                throw new IllegalArgumentException("No UidRecord or uid");
23803            }
23804            pendingChange.uidRecord = uidRec;
23805            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
23806            mPendingUidChanges.add(pendingChange);
23807        } else {
23808            pendingChange = uidRec.pendingChange;
23809            // If there is no change in idle or active state, then keep whatever was pending.
23810            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
23811                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
23812                        | UidRecord.CHANGE_ACTIVE));
23813            }
23814            // If there is no change in cached or uncached state, then keep whatever was pending.
23815            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
23816                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
23817                        | UidRecord.CHANGE_UNCACHED));
23818            }
23819            // If this is a report of the UID being gone, then we shouldn't keep any previous
23820            // report of it being active or cached.  (That is, a gone uid is never active,
23821            // and never cached.)
23822            if ((change & UidRecord.CHANGE_GONE) != 0) {
23823                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
23824                if (!uidRec.idle) {
23825                    // If this uid is going away, and we haven't yet reported it is gone,
23826                    // then do so now.
23827                    change |= UidRecord.CHANGE_IDLE;
23828                }
23829            }
23830        }
23831        pendingChange.change = change;
23832        pendingChange.processState = uidRec != null
23833                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
23834        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
23835        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
23836        if (uidRec != null) {
23837            uidRec.lastReportedChange = change;
23838            uidRec.updateLastDispatchedProcStateSeq(change);
23839        }
23840
23841        // Directly update the power manager, since we sit on top of it and it is critical
23842        // it be kept in sync (so wake locks will be held as soon as appropriate).
23843        if (mLocalPowerManager != null) {
23844            // TO DO: dispatch cached/uncached changes here, so we don't need to report
23845            // all proc state changes.
23846            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
23847                mLocalPowerManager.uidActive(pendingChange.uid);
23848            }
23849            if ((change & UidRecord.CHANGE_IDLE) != 0) {
23850                mLocalPowerManager.uidIdle(pendingChange.uid);
23851            }
23852            if ((change & UidRecord.CHANGE_GONE) != 0) {
23853                mLocalPowerManager.uidGone(pendingChange.uid);
23854            } else {
23855                mLocalPowerManager.updateUidProcState(pendingChange.uid,
23856                        pendingChange.processState);
23857            }
23858        }
23859    }
23860
23861    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
23862            String authority) {
23863        if (app == null) return;
23864        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23865            UserState userState = mUserController.getStartedUserState(app.userId);
23866            if (userState == null) return;
23867            final long now = SystemClock.elapsedRealtime();
23868            Long lastReported = userState.mProviderLastReportedFg.get(authority);
23869            if (lastReported == null || lastReported < now - 60 * 1000L) {
23870                if (mSystemReady) {
23871                    // Cannot touch the user stats if not system ready
23872                    mUsageStatsService.reportContentProviderUsage(
23873                            authority, providerPkgName, app.userId);
23874                }
23875                userState.mProviderLastReportedFg.put(authority, now);
23876            }
23877        }
23878    }
23879
23880    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
23881        if (DEBUG_USAGE_STATS) {
23882            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
23883                    + "] state changes: old = " + app.setProcState + ", new = "
23884                    + app.curProcState);
23885        }
23886        if (mUsageStatsService == null) {
23887            return;
23888        }
23889        boolean isInteraction;
23890        // To avoid some abuse patterns, we are going to be careful about what we consider
23891        // to be an app interaction.  Being the top activity doesn't count while the display
23892        // is sleeping, nor do short foreground services.
23893        if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
23894            isInteraction = true;
23895            app.fgInteractionTime = 0;
23896        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
23897            if (app.fgInteractionTime == 0) {
23898                app.fgInteractionTime = nowElapsed;
23899                isInteraction = false;
23900            } else {
23901                isInteraction = nowElapsed > app.fgInteractionTime
23902                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
23903            }
23904        } else {
23905            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23906            app.fgInteractionTime = 0;
23907        }
23908        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
23909                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
23910            app.interactionEventTime = nowElapsed;
23911            String[] packages = app.getPackageList();
23912            if (packages != null) {
23913                for (int i = 0; i < packages.length; i++) {
23914                    mUsageStatsService.reportEvent(packages[i], app.userId,
23915                            UsageEvents.Event.SYSTEM_INTERACTION);
23916                }
23917            }
23918        }
23919        app.reportedInteraction = isInteraction;
23920        if (!isInteraction) {
23921            app.interactionEventTime = 0;
23922        }
23923    }
23924
23925    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
23926        if (proc.thread != null) {
23927            if (proc.baseProcessTracker != null) {
23928                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
23929            }
23930        }
23931    }
23932
23933    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
23934            ProcessRecord TOP_APP, boolean doingAll, long now) {
23935        if (app.thread == null) {
23936            return false;
23937        }
23938
23939        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
23940
23941        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
23942    }
23943
23944    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
23945            boolean oomAdj) {
23946        if (isForeground != proc.foregroundServices) {
23947            proc.foregroundServices = isForeground;
23948            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
23949                    proc.info.uid);
23950            if (isForeground) {
23951                if (curProcs == null) {
23952                    curProcs = new ArrayList<ProcessRecord>();
23953                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
23954                }
23955                if (!curProcs.contains(proc)) {
23956                    curProcs.add(proc);
23957                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
23958                            proc.info.packageName, proc.info.uid);
23959                }
23960            } else {
23961                if (curProcs != null) {
23962                    if (curProcs.remove(proc)) {
23963                        mBatteryStatsService.noteEvent(
23964                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
23965                                proc.info.packageName, proc.info.uid);
23966                        if (curProcs.size() <= 0) {
23967                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
23968                        }
23969                    }
23970                }
23971            }
23972            if (oomAdj) {
23973                updateOomAdjLocked();
23974            }
23975        }
23976    }
23977
23978    private final ActivityRecord resumedAppLocked() {
23979        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
23980        String pkg;
23981        int uid;
23982        if (act != null) {
23983            pkg = act.packageName;
23984            uid = act.info.applicationInfo.uid;
23985        } else {
23986            pkg = null;
23987            uid = -1;
23988        }
23989        // Has the UID or resumed package name changed?
23990        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
23991                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
23992            if (mCurResumedPackage != null) {
23993                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
23994                        mCurResumedPackage, mCurResumedUid);
23995            }
23996            mCurResumedPackage = pkg;
23997            mCurResumedUid = uid;
23998            if (mCurResumedPackage != null) {
23999                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
24000                        mCurResumedPackage, mCurResumedUid);
24001            }
24002        }
24003        return act;
24004    }
24005
24006    /**
24007     * Update OomAdj for a specific process.
24008     * @param app The process to update
24009     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
24010     *                  if necessary, or skip.
24011     * @return whether updateOomAdjLocked(app) was successful.
24012     */
24013    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
24014        final ActivityRecord TOP_ACT = resumedAppLocked();
24015        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24016        final boolean wasCached = app.cached;
24017
24018        mAdjSeq++;
24019
24020        // This is the desired cached adjusment we want to tell it to use.
24021        // If our app is currently cached, we know it, and that is it.  Otherwise,
24022        // we don't know it yet, and it needs to now be cached we will then
24023        // need to do a complete oom adj.
24024        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
24025                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
24026        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
24027                SystemClock.uptimeMillis());
24028        if (oomAdjAll
24029                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
24030            // Changed to/from cached state, so apps after it in the LRU
24031            // list may also be changed.
24032            updateOomAdjLocked();
24033        }
24034        return success;
24035    }
24036
24037    final void updateOomAdjLocked() {
24038        final ActivityRecord TOP_ACT = resumedAppLocked();
24039        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24040        final long now = SystemClock.uptimeMillis();
24041        final long nowElapsed = SystemClock.elapsedRealtime();
24042        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
24043        final int N = mLruProcesses.size();
24044
24045        if (false) {
24046            RuntimeException e = new RuntimeException();
24047            e.fillInStackTrace();
24048            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
24049        }
24050
24051        // Reset state in all uid records.
24052        for (int i=mActiveUids.size()-1; i>=0; i--) {
24053            final UidRecord uidRec = mActiveUids.valueAt(i);
24054            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24055                    "Starting update of " + uidRec);
24056            uidRec.reset();
24057        }
24058
24059        mStackSupervisor.rankTaskLayersIfNeeded();
24060
24061        mAdjSeq++;
24062        mNewNumServiceProcs = 0;
24063        mNewNumAServiceProcs = 0;
24064
24065        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
24066        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
24067
24068        // Let's determine how many processes we have running vs.
24069        // how many slots we have for background processes; we may want
24070        // to put multiple processes in a slot of there are enough of
24071        // them.
24072        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
24073                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
24074        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
24075        if (numEmptyProcs > cachedProcessLimit) {
24076            // If there are more empty processes than our limit on cached
24077            // processes, then use the cached process limit for the factor.
24078            // This ensures that the really old empty processes get pushed
24079            // down to the bottom, so if we are running low on memory we will
24080            // have a better chance at keeping around more cached processes
24081            // instead of a gazillion empty processes.
24082            numEmptyProcs = cachedProcessLimit;
24083        }
24084        int emptyFactor = numEmptyProcs/numSlots;
24085        if (emptyFactor < 1) emptyFactor = 1;
24086        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
24087        if (cachedFactor < 1) cachedFactor = 1;
24088        int stepCached = 0;
24089        int stepEmpty = 0;
24090        int numCached = 0;
24091        int numEmpty = 0;
24092        int numTrimming = 0;
24093
24094        mNumNonCachedProcs = 0;
24095        mNumCachedHiddenProcs = 0;
24096
24097        // First update the OOM adjustment for each of the
24098        // application processes based on their current state.
24099        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
24100        int nextCachedAdj = curCachedAdj+1;
24101        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
24102        int nextEmptyAdj = curEmptyAdj+2;
24103        for (int i=N-1; i>=0; i--) {
24104            ProcessRecord app = mLruProcesses.get(i);
24105            if (!app.killedByAm && app.thread != null) {
24106                app.procStateChanged = false;
24107                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
24108
24109                // If we haven't yet assigned the final cached adj
24110                // to the process, do that now.
24111                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
24112                    switch (app.curProcState) {
24113                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24114                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24115                        case ActivityManager.PROCESS_STATE_CACHED_RECENT:
24116                            // This process is a cached process holding activities...
24117                            // assign it the next cached value for that type, and then
24118                            // step that cached level.
24119                            app.curRawAdj = curCachedAdj;
24120                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
24121                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
24122                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
24123                                    + ")");
24124                            if (curCachedAdj != nextCachedAdj) {
24125                                stepCached++;
24126                                if (stepCached >= cachedFactor) {
24127                                    stepCached = 0;
24128                                    curCachedAdj = nextCachedAdj;
24129                                    nextCachedAdj += 2;
24130                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24131                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
24132                                    }
24133                                }
24134                            }
24135                            break;
24136                        default:
24137                            // For everything else, assign next empty cached process
24138                            // level and bump that up.  Note that this means that
24139                            // long-running services that have dropped down to the
24140                            // cached level will be treated as empty (since their process
24141                            // state is still as a service), which is what we want.
24142                            app.curRawAdj = curEmptyAdj;
24143                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
24144                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
24145                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
24146                                    + ")");
24147                            if (curEmptyAdj != nextEmptyAdj) {
24148                                stepEmpty++;
24149                                if (stepEmpty >= emptyFactor) {
24150                                    stepEmpty = 0;
24151                                    curEmptyAdj = nextEmptyAdj;
24152                                    nextEmptyAdj += 2;
24153                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24154                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
24155                                    }
24156                                }
24157                            }
24158                            break;
24159                    }
24160                }
24161
24162                applyOomAdjLocked(app, true, now, nowElapsed);
24163
24164                // Count the number of process types.
24165                switch (app.curProcState) {
24166                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24167                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24168                        mNumCachedHiddenProcs++;
24169                        numCached++;
24170                        if (numCached > cachedProcessLimit) {
24171                            app.kill("cached #" + numCached, true);
24172                        }
24173                        break;
24174                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
24175                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
24176                                && app.lastActivityTime < oldTime) {
24177                            app.kill("empty for "
24178                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
24179                                    / 1000) + "s", true);
24180                        } else {
24181                            numEmpty++;
24182                            if (numEmpty > emptyProcessLimit) {
24183                                app.kill("empty #" + numEmpty, true);
24184                            }
24185                        }
24186                        break;
24187                    default:
24188                        mNumNonCachedProcs++;
24189                        break;
24190                }
24191
24192                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
24193                    // If this is an isolated process, there are no services
24194                    // running in it, and it's not a special process with a
24195                    // custom entry point, then the process is no longer
24196                    // needed.  We agressively kill these because we can by
24197                    // definition not re-use the same process again, and it is
24198                    // good to avoid having whatever code was running in them
24199                    // left sitting around after no longer needed.
24200                    app.kill("isolated not needed", true);
24201                } else {
24202                    // Keeping this process, update its uid.
24203                    final UidRecord uidRec = app.uidRecord;
24204                    if (uidRec != null) {
24205                        uidRec.ephemeral = app.info.isInstantApp();
24206                        if (uidRec.curProcState > app.curProcState) {
24207                            uidRec.curProcState = app.curProcState;
24208                        }
24209                        if (app.foregroundServices) {
24210                            uidRec.foregroundServices = true;
24211                        }
24212                    }
24213                }
24214
24215                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24216                        && !app.killedByAm) {
24217                    numTrimming++;
24218                }
24219            }
24220        }
24221
24222        incrementProcStateSeqAndNotifyAppsLocked();
24223
24224        mNumServiceProcs = mNewNumServiceProcs;
24225
24226        // Now determine the memory trimming level of background processes.
24227        // Unfortunately we need to start at the back of the list to do this
24228        // properly.  We only do this if the number of background apps we
24229        // are managing to keep around is less than half the maximum we desire;
24230        // if we are keeping a good number around, we'll let them use whatever
24231        // memory they want.
24232        final int numCachedAndEmpty = numCached + numEmpty;
24233        int memFactor;
24234        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
24235                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
24236            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
24237                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
24238            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
24239                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
24240            } else {
24241                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
24242            }
24243        } else {
24244            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
24245        }
24246        // We always allow the memory level to go up (better).  We only allow it to go
24247        // down if we are in a state where that is allowed, *and* the total number of processes
24248        // has gone down since last time.
24249        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
24250                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
24251                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
24252        if (memFactor > mLastMemoryLevel) {
24253            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
24254                memFactor = mLastMemoryLevel;
24255                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
24256            }
24257        }
24258        if (memFactor != mLastMemoryLevel) {
24259            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
24260        }
24261        mLastMemoryLevel = memFactor;
24262        mLastNumProcesses = mLruProcesses.size();
24263        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
24264        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
24265        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
24266            if (mLowRamStartTime == 0) {
24267                mLowRamStartTime = now;
24268            }
24269            int step = 0;
24270            int fgTrimLevel;
24271            switch (memFactor) {
24272                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
24273                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
24274                    break;
24275                case ProcessStats.ADJ_MEM_FACTOR_LOW:
24276                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
24277                    break;
24278                default:
24279                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
24280                    break;
24281            }
24282            int factor = numTrimming/3;
24283            int minFactor = 2;
24284            if (mHomeProcess != null) minFactor++;
24285            if (mPreviousProcess != null) minFactor++;
24286            if (factor < minFactor) factor = minFactor;
24287            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
24288            for (int i=N-1; i>=0; i--) {
24289                ProcessRecord app = mLruProcesses.get(i);
24290                if (allChanged || app.procStateChanged) {
24291                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24292                    app.procStateChanged = false;
24293                }
24294                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24295                        && !app.killedByAm) {
24296                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
24297                        try {
24298                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24299                                    "Trimming memory of " + app.processName + " to " + curLevel);
24300                            app.thread.scheduleTrimMemory(curLevel);
24301                        } catch (RemoteException e) {
24302                        }
24303                        if (false) {
24304                            // For now we won't do this; our memory trimming seems
24305                            // to be good enough at this point that destroying
24306                            // activities causes more harm than good.
24307                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
24308                                    && app != mHomeProcess && app != mPreviousProcess) {
24309                                // Need to do this on its own message because the stack may not
24310                                // be in a consistent state at this point.
24311                                // For these apps we will also finish their activities
24312                                // to help them free memory.
24313                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
24314                            }
24315                        }
24316                    }
24317                    app.trimMemoryLevel = curLevel;
24318                    step++;
24319                    if (step >= factor) {
24320                        step = 0;
24321                        switch (curLevel) {
24322                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
24323                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
24324                                break;
24325                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
24326                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24327                                break;
24328                        }
24329                    }
24330                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
24331                        && !app.killedByAm) {
24332                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
24333                            && app.thread != null) {
24334                        try {
24335                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24336                                    "Trimming memory of heavy-weight " + app.processName
24337                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24338                            app.thread.scheduleTrimMemory(
24339                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24340                        } catch (RemoteException e) {
24341                        }
24342                    }
24343                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24344                } else {
24345                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24346                            || app.systemNoUi) && app.pendingUiClean) {
24347                        // If this application is now in the background and it
24348                        // had done UI, then give it the special trim level to
24349                        // have it free UI resources.
24350                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
24351                        if (app.trimMemoryLevel < level && app.thread != null) {
24352                            try {
24353                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24354                                        "Trimming memory of bg-ui " + app.processName
24355                                        + " to " + level);
24356                                app.thread.scheduleTrimMemory(level);
24357                            } catch (RemoteException e) {
24358                            }
24359                        }
24360                        app.pendingUiClean = false;
24361                    }
24362                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
24363                        try {
24364                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24365                                    "Trimming memory of fg " + app.processName
24366                                    + " to " + fgTrimLevel);
24367                            app.thread.scheduleTrimMemory(fgTrimLevel);
24368                        } catch (RemoteException e) {
24369                        }
24370                    }
24371                    app.trimMemoryLevel = fgTrimLevel;
24372                }
24373            }
24374        } else {
24375            if (mLowRamStartTime != 0) {
24376                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
24377                mLowRamStartTime = 0;
24378            }
24379            for (int i=N-1; i>=0; i--) {
24380                ProcessRecord app = mLruProcesses.get(i);
24381                if (allChanged || app.procStateChanged) {
24382                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24383                    app.procStateChanged = false;
24384                }
24385                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24386                        || app.systemNoUi) && app.pendingUiClean) {
24387                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
24388                            && app.thread != null) {
24389                        try {
24390                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24391                                    "Trimming memory of ui hidden " + app.processName
24392                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24393                            app.thread.scheduleTrimMemory(
24394                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24395                        } catch (RemoteException e) {
24396                        }
24397                    }
24398                    app.pendingUiClean = false;
24399                }
24400                app.trimMemoryLevel = 0;
24401            }
24402        }
24403
24404        if (mAlwaysFinishActivities) {
24405            // Need to do this on its own message because the stack may not
24406            // be in a consistent state at this point.
24407            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
24408        }
24409
24410        if (allChanged) {
24411            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
24412        }
24413
24414        ArrayList<UidRecord> becameIdle = null;
24415
24416        // Update from any uid changes.
24417        if (mLocalPowerManager != null) {
24418            mLocalPowerManager.startUidChanges();
24419        }
24420        for (int i=mActiveUids.size()-1; i>=0; i--) {
24421            final UidRecord uidRec = mActiveUids.valueAt(i);
24422            int uidChange = UidRecord.CHANGE_PROCSTATE;
24423            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
24424                    && (uidRec.setProcState != uidRec.curProcState
24425                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
24426                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24427                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
24428                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
24429                        + " to " + uidRec.curWhitelist);
24430                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
24431                        && !uidRec.curWhitelist) {
24432                    // UID is now in the background (and not on the temp whitelist).  Was it
24433                    // previously in the foreground (or on the temp whitelist)?
24434                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
24435                            || uidRec.setWhitelist) {
24436                        uidRec.lastBackgroundTime = nowElapsed;
24437                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
24438                            // Note: the background settle time is in elapsed realtime, while
24439                            // the handler time base is uptime.  All this means is that we may
24440                            // stop background uids later than we had intended, but that only
24441                            // happens because the device was sleeping so we are okay anyway.
24442                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24443                                    mConstants.BACKGROUND_SETTLE_TIME);
24444                        }
24445                    }
24446                    if (uidRec.idle && !uidRec.setIdle) {
24447                        uidChange = UidRecord.CHANGE_IDLE;
24448                        if (becameIdle == null) {
24449                            becameIdle = new ArrayList<>();
24450                        }
24451                        becameIdle.add(uidRec);
24452                    }
24453                } else {
24454                    if (uidRec.idle) {
24455                        uidChange = UidRecord.CHANGE_ACTIVE;
24456                        EventLogTags.writeAmUidActive(uidRec.uid);
24457                        uidRec.idle = false;
24458                    }
24459                    uidRec.lastBackgroundTime = 0;
24460                }
24461                final boolean wasCached = uidRec.setProcState
24462                        > ActivityManager.PROCESS_STATE_RECEIVER;
24463                final boolean isCached = uidRec.curProcState
24464                        > ActivityManager.PROCESS_STATE_RECEIVER;
24465                if (wasCached != isCached ||
24466                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
24467                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
24468                }
24469                uidRec.setProcState = uidRec.curProcState;
24470                uidRec.setWhitelist = uidRec.curWhitelist;
24471                uidRec.setIdle = uidRec.idle;
24472                enqueueUidChangeLocked(uidRec, -1, uidChange);
24473                noteUidProcessState(uidRec.uid, uidRec.curProcState);
24474                if (uidRec.foregroundServices) {
24475                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
24476                }
24477            }
24478        }
24479        if (mLocalPowerManager != null) {
24480            mLocalPowerManager.finishUidChanges();
24481        }
24482
24483        if (becameIdle != null) {
24484            // If we have any new uids that became idle this time, we need to make sure
24485            // they aren't left with running services.
24486            for (int i = becameIdle.size() - 1; i >= 0; i--) {
24487                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
24488            }
24489        }
24490
24491        if (mProcessStats.shouldWriteNowLocked(now)) {
24492            mHandler.post(new Runnable() {
24493                @Override public void run() {
24494                    synchronized (ActivityManagerService.this) {
24495                        mProcessStats.writeStateAsyncLocked();
24496                    }
24497                }
24498            });
24499        }
24500
24501        if (DEBUG_OOM_ADJ) {
24502            final long duration = SystemClock.uptimeMillis() - now;
24503            if (false) {
24504                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
24505                        new RuntimeException("here").fillInStackTrace());
24506            } else {
24507                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
24508            }
24509        }
24510    }
24511
24512    @Override
24513    public void makePackageIdle(String packageName, int userId) {
24514        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
24515                != PackageManager.PERMISSION_GRANTED) {
24516            String msg = "Permission Denial: makePackageIdle() from pid="
24517                    + Binder.getCallingPid()
24518                    + ", uid=" + Binder.getCallingUid()
24519                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
24520            Slog.w(TAG, msg);
24521            throw new SecurityException(msg);
24522        }
24523        final int callingPid = Binder.getCallingPid();
24524        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
24525                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
24526        long callingId = Binder.clearCallingIdentity();
24527        synchronized(this) {
24528            try {
24529                IPackageManager pm = AppGlobals.getPackageManager();
24530                int pkgUid = -1;
24531                try {
24532                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
24533                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
24534                } catch (RemoteException e) {
24535                }
24536                if (pkgUid == -1) {
24537                    throw new IllegalArgumentException("Unknown package name " + packageName);
24538                }
24539
24540                if (mLocalPowerManager != null) {
24541                    mLocalPowerManager.startUidChanges();
24542                }
24543                final int appId = UserHandle.getAppId(pkgUid);
24544                final int N = mActiveUids.size();
24545                for (int i=N-1; i>=0; i--) {
24546                    final UidRecord uidRec = mActiveUids.valueAt(i);
24547                    final long bgTime = uidRec.lastBackgroundTime;
24548                    if (bgTime > 0 && !uidRec.idle) {
24549                        if (UserHandle.getAppId(uidRec.uid) == appId) {
24550                            if (userId == UserHandle.USER_ALL ||
24551                                    userId == UserHandle.getUserId(uidRec.uid)) {
24552                                EventLogTags.writeAmUidIdle(uidRec.uid);
24553                                uidRec.idle = true;
24554                                uidRec.setIdle = true;
24555                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
24556                                        + " from package " + packageName + " user " + userId);
24557                                doStopUidLocked(uidRec.uid, uidRec);
24558                            }
24559                        }
24560                    }
24561                }
24562            } finally {
24563                if (mLocalPowerManager != null) {
24564                    mLocalPowerManager.finishUidChanges();
24565                }
24566                Binder.restoreCallingIdentity(callingId);
24567            }
24568        }
24569    }
24570
24571    final void idleUids() {
24572        synchronized (this) {
24573            final int N = mActiveUids.size();
24574            if (N <= 0) {
24575                return;
24576            }
24577            final long nowElapsed = SystemClock.elapsedRealtime();
24578            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
24579            long nextTime = 0;
24580            if (mLocalPowerManager != null) {
24581                mLocalPowerManager.startUidChanges();
24582            }
24583            for (int i=N-1; i>=0; i--) {
24584                final UidRecord uidRec = mActiveUids.valueAt(i);
24585                final long bgTime = uidRec.lastBackgroundTime;
24586                if (bgTime > 0 && !uidRec.idle) {
24587                    if (bgTime <= maxBgTime) {
24588                        EventLogTags.writeAmUidIdle(uidRec.uid);
24589                        uidRec.idle = true;
24590                        uidRec.setIdle = true;
24591                        doStopUidLocked(uidRec.uid, uidRec);
24592                    } else {
24593                        if (nextTime == 0 || nextTime > bgTime) {
24594                            nextTime = bgTime;
24595                        }
24596                    }
24597                }
24598            }
24599            if (mLocalPowerManager != null) {
24600                mLocalPowerManager.finishUidChanges();
24601            }
24602            if (nextTime > 0) {
24603                mHandler.removeMessages(IDLE_UIDS_MSG);
24604                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24605                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
24606            }
24607        }
24608    }
24609
24610    /**
24611     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
24612     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
24613     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
24614     */
24615    @VisibleForTesting
24616    @GuardedBy("this")
24617    void incrementProcStateSeqAndNotifyAppsLocked() {
24618        if (mWaitForNetworkTimeoutMs <= 0) {
24619            return;
24620        }
24621        // Used for identifying which uids need to block for network.
24622        ArrayList<Integer> blockingUids = null;
24623        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
24624            final UidRecord uidRec = mActiveUids.valueAt(i);
24625            // If the network is not restricted for uid, then nothing to do here.
24626            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
24627                continue;
24628            }
24629            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
24630                continue;
24631            }
24632            // If process state is not changed, then there's nothing to do.
24633            if (uidRec.setProcState == uidRec.curProcState) {
24634                continue;
24635            }
24636            final int blockState = getBlockStateForUid(uidRec);
24637            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
24638            // there's nothing the app needs to do in this scenario.
24639            if (blockState == NETWORK_STATE_NO_CHANGE) {
24640                continue;
24641            }
24642            synchronized (uidRec.networkStateLock) {
24643                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
24644                if (blockState == NETWORK_STATE_BLOCK) {
24645                    if (blockingUids == null) {
24646                        blockingUids = new ArrayList<>();
24647                    }
24648                    blockingUids.add(uidRec.uid);
24649                } else {
24650                    if (DEBUG_NETWORK) {
24651                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
24652                                + " threads for uid: " + uidRec);
24653                    }
24654                    if (uidRec.waitingForNetwork) {
24655                        uidRec.networkStateLock.notifyAll();
24656                    }
24657                }
24658            }
24659        }
24660
24661        // There are no uids that need to block, so nothing more to do.
24662        if (blockingUids == null) {
24663            return;
24664        }
24665
24666        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
24667            final ProcessRecord app = mLruProcesses.get(i);
24668            if (!blockingUids.contains(app.uid)) {
24669                continue;
24670            }
24671            if (!app.killedByAm && app.thread != null) {
24672                final UidRecord uidRec = mActiveUids.get(app.uid);
24673                try {
24674                    if (DEBUG_NETWORK) {
24675                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
24676                                + uidRec);
24677                    }
24678                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
24679                } catch (RemoteException ignored) {
24680                }
24681            }
24682        }
24683    }
24684
24685    /**
24686     * Checks if the uid is coming from background to foreground or vice versa and returns
24687     * appropriate block state based on this.
24688     *
24689     * @return blockState based on whether the uid is coming from background to foreground or
24690     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
24691     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
24692     *         {@link #NETWORK_STATE_NO_CHANGE}.
24693     */
24694    @VisibleForTesting
24695    int getBlockStateForUid(UidRecord uidRec) {
24696        // Denotes whether uid's process state is currently allowed network access.
24697        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
24698                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
24699        // Denotes whether uid's process state was previously allowed network access.
24700        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
24701                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
24702
24703        // When the uid is coming to foreground, AMS should inform the app thread that it should
24704        // block for the network rules to get updated before launching an activity.
24705        if (!wasAllowed && isAllowed) {
24706            return NETWORK_STATE_BLOCK;
24707        }
24708        // When the uid is going to background, AMS should inform the app thread that if an
24709        // activity launch is blocked for the network rules to get updated, it should be unblocked.
24710        if (wasAllowed && !isAllowed) {
24711            return NETWORK_STATE_UNBLOCK;
24712        }
24713        return NETWORK_STATE_NO_CHANGE;
24714    }
24715
24716    final void runInBackgroundDisabled(int uid) {
24717        synchronized (this) {
24718            UidRecord uidRec = mActiveUids.get(uid);
24719            if (uidRec != null) {
24720                // This uid is actually running...  should it be considered background now?
24721                if (uidRec.idle) {
24722                    doStopUidLocked(uidRec.uid, uidRec);
24723                }
24724            } else {
24725                // This uid isn't actually running...  still send a report about it being "stopped".
24726                doStopUidLocked(uid, null);
24727            }
24728        }
24729    }
24730
24731    /**
24732     * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
24733     */
24734    void doStopUidForIdleUidsLocked() {
24735        final int size = mActiveUids.size();
24736        for (int i = 0; i < size; i++) {
24737            final int uid = mActiveUids.keyAt(i);
24738            if (UserHandle.isCore(uid)) {
24739                continue;
24740            }
24741            final UidRecord uidRec = mActiveUids.valueAt(i);
24742            if (!uidRec.idle) {
24743                continue;
24744            }
24745            doStopUidLocked(uidRec.uid, uidRec);
24746        }
24747    }
24748
24749    final void doStopUidLocked(int uid, final UidRecord uidRec) {
24750        mServices.stopInBackgroundLocked(uid);
24751        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
24752    }
24753
24754    /**
24755     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
24756     */
24757    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
24758            long duration, String tag) {
24759        if (DEBUG_WHITELISTS) {
24760            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
24761                    + targetUid + ", " + duration + ")");
24762        }
24763
24764        synchronized (mPidsSelfLocked) {
24765            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
24766            if (pr == null) {
24767                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
24768                        + callerPid);
24769                return;
24770            }
24771            if (!pr.whitelistManager) {
24772                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
24773                        != PackageManager.PERMISSION_GRANTED) {
24774                    if (DEBUG_WHITELISTS) {
24775                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
24776                                + ": pid " + callerPid + " is not allowed");
24777                    }
24778                    return;
24779                }
24780            }
24781        }
24782
24783        tempWhitelistUidLocked(targetUid, duration, tag);
24784    }
24785
24786    /**
24787     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
24788     */
24789    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
24790        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
24791        setUidTempWhitelistStateLocked(targetUid, true);
24792        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
24793    }
24794
24795    void pushTempWhitelist() {
24796        final int N;
24797        final PendingTempWhitelist[] list;
24798
24799        // First copy out the pending changes...  we need to leave them in the map for now,
24800        // in case someone needs to check what is coming up while we don't have the lock held.
24801        synchronized(this) {
24802            N = mPendingTempWhitelist.size();
24803            list = new PendingTempWhitelist[N];
24804            for (int i = 0; i < N; i++) {
24805                list[i] = mPendingTempWhitelist.valueAt(i);
24806            }
24807        }
24808
24809        // Now safely dispatch changes to device idle controller.
24810        for (int i = 0; i < N; i++) {
24811            PendingTempWhitelist ptw = list[i];
24812            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
24813                    ptw.duration, true, ptw.tag);
24814        }
24815
24816        // And now we can safely remove them from the map.
24817        synchronized(this) {
24818            for (int i = 0; i < N; i++) {
24819                PendingTempWhitelist ptw = list[i];
24820                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
24821                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
24822                    mPendingTempWhitelist.removeAt(index);
24823                }
24824            }
24825        }
24826    }
24827
24828    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
24829        boolean changed = false;
24830        for (int i=mActiveUids.size()-1; i>=0; i--) {
24831            final UidRecord uidRec = mActiveUids.valueAt(i);
24832            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
24833                uidRec.curWhitelist = onWhitelist;
24834                changed = true;
24835            }
24836        }
24837        if (changed) {
24838            updateOomAdjLocked();
24839        }
24840    }
24841
24842    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
24843        boolean changed = false;
24844        final UidRecord uidRec = mActiveUids.get(uid);
24845        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
24846            uidRec.curWhitelist = onWhitelist;
24847            updateOomAdjLocked();
24848        }
24849    }
24850
24851    final void trimApplications() {
24852        synchronized (this) {
24853            int i;
24854
24855            // First remove any unused application processes whose package
24856            // has been removed.
24857            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
24858                final ProcessRecord app = mRemovedProcesses.get(i);
24859                if (app.activities.size() == 0 && app.recentTasks.size() == 0
24860                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
24861                    Slog.i(
24862                        TAG, "Exiting empty application process "
24863                        + app.toShortString() + " ("
24864                        + (app.thread != null ? app.thread.asBinder() : null)
24865                        + ")\n");
24866                    if (app.pid > 0 && app.pid != MY_PID) {
24867                        app.kill("empty", false);
24868                    } else if (app.thread != null) {
24869                        try {
24870                            app.thread.scheduleExit();
24871                        } catch (Exception e) {
24872                            // Ignore exceptions.
24873                        }
24874                    }
24875                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
24876                    mRemovedProcesses.remove(i);
24877
24878                    if (app.persistent) {
24879                        addAppLocked(app.info, null, false, null /* ABI override */);
24880                    }
24881                }
24882            }
24883
24884            // Now update the oom adj for all processes.
24885            updateOomAdjLocked();
24886        }
24887    }
24888
24889    /** This method sends the specified signal to each of the persistent apps */
24890    public void signalPersistentProcesses(int sig) throws RemoteException {
24891        if (sig != SIGNAL_USR1) {
24892            throw new SecurityException("Only SIGNAL_USR1 is allowed");
24893        }
24894
24895        synchronized (this) {
24896            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
24897                    != PackageManager.PERMISSION_GRANTED) {
24898                throw new SecurityException("Requires permission "
24899                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
24900            }
24901
24902            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
24903                ProcessRecord r = mLruProcesses.get(i);
24904                if (r.thread != null && r.persistent) {
24905                    sendSignal(r.pid, sig);
24906                }
24907            }
24908        }
24909    }
24910
24911    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
24912        if (proc == null || proc == mProfileProc) {
24913            proc = mProfileProc;
24914            profileType = mProfileType;
24915            clearProfilerLocked();
24916        }
24917        if (proc == null) {
24918            return;
24919        }
24920        try {
24921            proc.thread.profilerControl(false, null, profileType);
24922        } catch (RemoteException e) {
24923            throw new IllegalStateException("Process disappeared");
24924        }
24925    }
24926
24927    private void clearProfilerLocked() {
24928        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
24929            try {
24930                mProfilerInfo.profileFd.close();
24931            } catch (IOException e) {
24932            }
24933        }
24934        mProfileApp = null;
24935        mProfileProc = null;
24936        mProfilerInfo = null;
24937    }
24938
24939    public boolean profileControl(String process, int userId, boolean start,
24940            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
24941
24942        try {
24943            synchronized (this) {
24944                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
24945                // its own permission.
24946                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
24947                        != PackageManager.PERMISSION_GRANTED) {
24948                    throw new SecurityException("Requires permission "
24949                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
24950                }
24951
24952                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
24953                    throw new IllegalArgumentException("null profile info or fd");
24954                }
24955
24956                ProcessRecord proc = null;
24957                if (process != null) {
24958                    proc = findProcessLocked(process, userId, "profileControl");
24959                }
24960
24961                if (start && (proc == null || proc.thread == null)) {
24962                    throw new IllegalArgumentException("Unknown process: " + process);
24963                }
24964
24965                if (start) {
24966                    stopProfilerLocked(null, 0);
24967                    setProfileApp(proc.info, proc.processName, profilerInfo);
24968                    mProfileProc = proc;
24969                    mProfileType = profileType;
24970                    ParcelFileDescriptor fd = profilerInfo.profileFd;
24971                    try {
24972                        fd = fd.dup();
24973                    } catch (IOException e) {
24974                        fd = null;
24975                    }
24976                    profilerInfo.profileFd = fd;
24977                    proc.thread.profilerControl(start, profilerInfo, profileType);
24978                    fd = null;
24979                    try {
24980                        mProfilerInfo.profileFd.close();
24981                    } catch (IOException e) {
24982                    }
24983                    mProfilerInfo.profileFd = null;
24984                } else {
24985                    stopProfilerLocked(proc, profileType);
24986                    if (profilerInfo != null && profilerInfo.profileFd != null) {
24987                        try {
24988                            profilerInfo.profileFd.close();
24989                        } catch (IOException e) {
24990                        }
24991                    }
24992                }
24993
24994                return true;
24995            }
24996        } catch (RemoteException e) {
24997            throw new IllegalStateException("Process disappeared");
24998        } finally {
24999            if (profilerInfo != null && profilerInfo.profileFd != null) {
25000                try {
25001                    profilerInfo.profileFd.close();
25002                } catch (IOException e) {
25003                }
25004            }
25005        }
25006    }
25007
25008    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
25009        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
25010                userId, true, ALLOW_FULL_ONLY, callName, null);
25011        ProcessRecord proc = null;
25012        try {
25013            int pid = Integer.parseInt(process);
25014            synchronized (mPidsSelfLocked) {
25015                proc = mPidsSelfLocked.get(pid);
25016            }
25017        } catch (NumberFormatException e) {
25018        }
25019
25020        if (proc == null) {
25021            ArrayMap<String, SparseArray<ProcessRecord>> all
25022                    = mProcessNames.getMap();
25023            SparseArray<ProcessRecord> procs = all.get(process);
25024            if (procs != null && procs.size() > 0) {
25025                proc = procs.valueAt(0);
25026                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
25027                    for (int i=1; i<procs.size(); i++) {
25028                        ProcessRecord thisProc = procs.valueAt(i);
25029                        if (thisProc.userId == userId) {
25030                            proc = thisProc;
25031                            break;
25032                        }
25033                    }
25034                }
25035            }
25036        }
25037
25038        return proc;
25039    }
25040
25041    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
25042            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
25043
25044        try {
25045            synchronized (this) {
25046                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25047                // its own permission (same as profileControl).
25048                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25049                        != PackageManager.PERMISSION_GRANTED) {
25050                    throw new SecurityException("Requires permission "
25051                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25052                }
25053
25054                if (fd == null) {
25055                    throw new IllegalArgumentException("null fd");
25056                }
25057
25058                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
25059                if (proc == null || proc.thread == null) {
25060                    throw new IllegalArgumentException("Unknown process: " + process);
25061                }
25062
25063                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25064                if (!isDebuggable) {
25065                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25066                        throw new SecurityException("Process not debuggable: " + proc);
25067                    }
25068                }
25069
25070                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
25071                fd = null;
25072                return true;
25073            }
25074        } catch (RemoteException e) {
25075            throw new IllegalStateException("Process disappeared");
25076        } finally {
25077            if (fd != null) {
25078                try {
25079                    fd.close();
25080                } catch (IOException e) {
25081                }
25082            }
25083        }
25084    }
25085
25086    @Override
25087    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
25088            String reportPackage) {
25089        if (processName != null) {
25090            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
25091                    "setDumpHeapDebugLimit()");
25092        } else {
25093            synchronized (mPidsSelfLocked) {
25094                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
25095                if (proc == null) {
25096                    throw new SecurityException("No process found for calling pid "
25097                            + Binder.getCallingPid());
25098                }
25099                if (!Build.IS_DEBUGGABLE
25100                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25101                    throw new SecurityException("Not running a debuggable build");
25102                }
25103                processName = proc.processName;
25104                uid = proc.uid;
25105                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
25106                    throw new SecurityException("Package " + reportPackage + " is not running in "
25107                            + proc);
25108                }
25109            }
25110        }
25111        synchronized (this) {
25112            if (maxMemSize > 0) {
25113                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
25114            } else {
25115                if (uid != 0) {
25116                    mMemWatchProcesses.remove(processName, uid);
25117                } else {
25118                    mMemWatchProcesses.getMap().remove(processName);
25119                }
25120            }
25121        }
25122    }
25123
25124    @Override
25125    public void dumpHeapFinished(String path) {
25126        synchronized (this) {
25127            if (Binder.getCallingPid() != mMemWatchDumpPid) {
25128                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
25129                        + " does not match last pid " + mMemWatchDumpPid);
25130                return;
25131            }
25132            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
25133                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
25134                        + " does not match last path " + mMemWatchDumpFile);
25135                return;
25136            }
25137            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
25138            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
25139
25140            // Forced gc to clean up the remnant hprof fd.
25141            Runtime.getRuntime().gc();
25142        }
25143    }
25144
25145    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
25146    public void monitor() {
25147        synchronized (this) { }
25148    }
25149
25150    void onCoreSettingsChange(Bundle settings) {
25151        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
25152            ProcessRecord processRecord = mLruProcesses.get(i);
25153            try {
25154                if (processRecord.thread != null) {
25155                    processRecord.thread.setCoreSettings(settings);
25156                }
25157            } catch (RemoteException re) {
25158                /* ignore */
25159            }
25160        }
25161    }
25162
25163    // Multi-user methods
25164
25165    /**
25166     * Start user, if its not already running, but don't bring it to foreground.
25167     */
25168    @Override
25169    public boolean startUserInBackground(final int userId) {
25170        return startUserInBackgroundWithListener(userId, null);
25171    }
25172
25173    @Override
25174    public boolean startUserInBackgroundWithListener(final int userId,
25175                @Nullable IProgressListener unlockListener) {
25176        return mUserController.startUser(userId, /* foreground */ false, unlockListener);
25177    }
25178
25179    @Override
25180    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
25181        return mUserController.unlockUser(userId, token, secret, listener);
25182    }
25183
25184    @Override
25185    public boolean switchUser(final int targetUserId) {
25186        return mUserController.switchUser(targetUserId);
25187    }
25188
25189    @Override
25190    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
25191        return mUserController.stopUser(userId, force, callback);
25192    }
25193
25194    @Override
25195    public UserInfo getCurrentUser() {
25196        return mUserController.getCurrentUser();
25197    }
25198
25199    String getStartedUserState(int userId) {
25200        final UserState userState = mUserController.getStartedUserState(userId);
25201        return UserState.stateToString(userState.state);
25202    }
25203
25204    @Override
25205    public boolean isUserRunning(int userId, int flags) {
25206        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
25207                && checkCallingPermission(INTERACT_ACROSS_USERS)
25208                    != PackageManager.PERMISSION_GRANTED) {
25209            String msg = "Permission Denial: isUserRunning() from pid="
25210                    + Binder.getCallingPid()
25211                    + ", uid=" + Binder.getCallingUid()
25212                    + " requires " + INTERACT_ACROSS_USERS;
25213            Slog.w(TAG, msg);
25214            throw new SecurityException(msg);
25215        }
25216        return mUserController.isUserRunning(userId, flags);
25217    }
25218
25219    @Override
25220    public int[] getRunningUserIds() {
25221        if (checkCallingPermission(INTERACT_ACROSS_USERS)
25222                != PackageManager.PERMISSION_GRANTED) {
25223            String msg = "Permission Denial: isUserRunning() from pid="
25224                    + Binder.getCallingPid()
25225                    + ", uid=" + Binder.getCallingUid()
25226                    + " requires " + INTERACT_ACROSS_USERS;
25227            Slog.w(TAG, msg);
25228            throw new SecurityException(msg);
25229        }
25230        return mUserController.getStartedUserArray();
25231    }
25232
25233    @Override
25234    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
25235        mUserController.registerUserSwitchObserver(observer, name);
25236    }
25237
25238    @Override
25239    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
25240        mUserController.unregisterUserSwitchObserver(observer);
25241    }
25242
25243    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
25244        if (info == null) return null;
25245        ApplicationInfo newInfo = new ApplicationInfo(info);
25246        newInfo.initForUser(userId);
25247        return newInfo;
25248    }
25249
25250    public boolean isUserStopped(int userId) {
25251        return mUserController.getStartedUserState(userId) == null;
25252    }
25253
25254    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
25255        if (aInfo == null
25256                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
25257            return aInfo;
25258        }
25259
25260        ActivityInfo info = new ActivityInfo(aInfo);
25261        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
25262        return info;
25263    }
25264
25265    private boolean processSanityChecksLocked(ProcessRecord process) {
25266        if (process == null || process.thread == null) {
25267            return false;
25268        }
25269
25270        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25271        if (!isDebuggable) {
25272            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25273                return false;
25274            }
25275        }
25276
25277        return true;
25278    }
25279
25280    public boolean startBinderTracking() throws RemoteException {
25281        synchronized (this) {
25282            mBinderTransactionTrackingEnabled = true;
25283            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25284            // permission (same as profileControl).
25285            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25286                    != PackageManager.PERMISSION_GRANTED) {
25287                throw new SecurityException("Requires permission "
25288                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25289            }
25290
25291            for (int i = 0; i < mLruProcesses.size(); i++) {
25292                ProcessRecord process = mLruProcesses.get(i);
25293                if (!processSanityChecksLocked(process)) {
25294                    continue;
25295                }
25296                try {
25297                    process.thread.startBinderTracking();
25298                } catch (RemoteException e) {
25299                    Log.v(TAG, "Process disappared");
25300                }
25301            }
25302            return true;
25303        }
25304    }
25305
25306    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
25307        try {
25308            synchronized (this) {
25309                mBinderTransactionTrackingEnabled = false;
25310                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25311                // permission (same as profileControl).
25312                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25313                        != PackageManager.PERMISSION_GRANTED) {
25314                    throw new SecurityException("Requires permission "
25315                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25316                }
25317
25318                if (fd == null) {
25319                    throw new IllegalArgumentException("null fd");
25320                }
25321
25322                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
25323                pw.println("Binder transaction traces for all processes.\n");
25324                for (ProcessRecord process : mLruProcesses) {
25325                    if (!processSanityChecksLocked(process)) {
25326                        continue;
25327                    }
25328
25329                    pw.println("Traces for process: " + process.processName);
25330                    pw.flush();
25331                    try {
25332                        TransferPipe tp = new TransferPipe();
25333                        try {
25334                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
25335                            tp.go(fd.getFileDescriptor());
25336                        } finally {
25337                            tp.kill();
25338                        }
25339                    } catch (IOException e) {
25340                        pw.println("Failure while dumping IPC traces from " + process +
25341                                ".  Exception: " + e);
25342                        pw.flush();
25343                    } catch (RemoteException e) {
25344                        pw.println("Got a RemoteException while dumping IPC traces from " +
25345                                process + ".  Exception: " + e);
25346                        pw.flush();
25347                    }
25348                }
25349                fd = null;
25350                return true;
25351            }
25352        } finally {
25353            if (fd != null) {
25354                try {
25355                    fd.close();
25356                } catch (IOException e) {
25357                }
25358            }
25359        }
25360    }
25361
25362    @VisibleForTesting
25363    final class LocalService extends ActivityManagerInternal {
25364        @Override
25365        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
25366                int targetUserId) {
25367            synchronized (ActivityManagerService.this) {
25368                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
25369                        targetPkg, intent, null, targetUserId);
25370            }
25371        }
25372
25373        @Override
25374        public String checkContentProviderAccess(String authority, int userId) {
25375            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
25376        }
25377
25378        @Override
25379        public void onWakefulnessChanged(int wakefulness) {
25380            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
25381        }
25382
25383        @Override
25384        public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
25385                String processName, String abiOverride, int uid, Runnable crashHandler) {
25386            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
25387                    processName, abiOverride, uid, crashHandler);
25388        }
25389
25390        @Override
25391        public SleepToken acquireSleepToken(String tag, int displayId) {
25392            Preconditions.checkNotNull(tag);
25393            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
25394        }
25395
25396        @Override
25397        public ComponentName getHomeActivityForUser(int userId) {
25398            synchronized (ActivityManagerService.this) {
25399                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
25400                return homeActivity == null ? null : homeActivity.realActivity;
25401            }
25402        }
25403
25404        @Override
25405        public void onUserRemoved(int userId) {
25406            synchronized (ActivityManagerService.this) {
25407                ActivityManagerService.this.onUserStoppedLocked(userId);
25408            }
25409            mBatteryStatsService.onUserRemoved(userId);
25410            mUserController.onUserRemoved(userId);
25411        }
25412
25413        @Override
25414        public void onLocalVoiceInteractionStarted(IBinder activity,
25415                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
25416            synchronized (ActivityManagerService.this) {
25417                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
25418                        voiceSession, voiceInteractor);
25419            }
25420        }
25421
25422        @Override
25423        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
25424            synchronized (ActivityManagerService.this) {
25425                mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
25426                        reasons, timestamp);
25427            }
25428        }
25429
25430        @Override
25431        public void notifyAppTransitionFinished() {
25432            synchronized (ActivityManagerService.this) {
25433                mStackSupervisor.notifyAppTransitionDone();
25434                mKeyguardController.notifyAppTransitionDone();
25435            }
25436        }
25437
25438        @Override
25439        public void notifyAppTransitionCancelled() {
25440            synchronized (ActivityManagerService.this) {
25441                mStackSupervisor.notifyAppTransitionDone();
25442            }
25443        }
25444
25445        @Override
25446        public List<IBinder> getTopVisibleActivities() {
25447            synchronized (ActivityManagerService.this) {
25448                return mStackSupervisor.getTopVisibleActivities();
25449            }
25450        }
25451
25452        @Override
25453        public void notifyDockedStackMinimizedChanged(boolean minimized) {
25454            synchronized (ActivityManagerService.this) {
25455                mStackSupervisor.setDockedStackMinimized(minimized);
25456            }
25457        }
25458
25459        @Override
25460        public void killForegroundAppsForUser(int userHandle) {
25461            synchronized (ActivityManagerService.this) {
25462                final ArrayList<ProcessRecord> procs = new ArrayList<>();
25463                final int NP = mProcessNames.getMap().size();
25464                for (int ip = 0; ip < NP; ip++) {
25465                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
25466                    final int NA = apps.size();
25467                    for (int ia = 0; ia < NA; ia++) {
25468                        final ProcessRecord app = apps.valueAt(ia);
25469                        if (app.persistent) {
25470                            // We don't kill persistent processes.
25471                            continue;
25472                        }
25473                        if (app.removed) {
25474                            procs.add(app);
25475                        } else if (app.userId == userHandle && app.foregroundActivities) {
25476                            app.removed = true;
25477                            procs.add(app);
25478                        }
25479                    }
25480                }
25481
25482                final int N = procs.size();
25483                for (int i = 0; i < N; i++) {
25484                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
25485                }
25486            }
25487        }
25488
25489        @Override
25490        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
25491                long duration) {
25492            if (!(target instanceof PendingIntentRecord)) {
25493                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
25494                return;
25495            }
25496            synchronized (ActivityManagerService.this) {
25497                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
25498            }
25499        }
25500
25501        @Override
25502        public void setDeviceIdleWhitelist(int[] appids) {
25503            synchronized (ActivityManagerService.this) {
25504                mDeviceIdleWhitelist = appids;
25505            }
25506        }
25507
25508        @Override
25509        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
25510            synchronized (ActivityManagerService.this) {
25511                mDeviceIdleTempWhitelist = appids;
25512                setAppIdTempWhitelistStateLocked(changingAppId, adding);
25513            }
25514        }
25515
25516        @Override
25517        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
25518                int userId) {
25519            Preconditions.checkNotNull(values, "Configuration must not be null");
25520            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
25521            synchronized (ActivityManagerService.this) {
25522                updateConfigurationLocked(values, null, false, true, userId,
25523                        false /* deferResume */);
25524            }
25525        }
25526
25527        @Override
25528        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
25529                Bundle bOptions) {
25530            Preconditions.checkNotNull(intents, "intents");
25531            final String[] resolvedTypes = new String[intents.length];
25532            for (int i = 0; i < intents.length; i++) {
25533                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
25534            }
25535
25536            // UID of the package on user userId.
25537            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
25538            // packageUid may not be initialized.
25539            int packageUid = 0;
25540            final long ident = Binder.clearCallingIdentity();
25541            try {
25542                packageUid = AppGlobals.getPackageManager().getPackageUid(
25543                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
25544            } catch (RemoteException e) {
25545                // Shouldn't happen.
25546            } finally {
25547                Binder.restoreCallingIdentity(ident);
25548            }
25549
25550            synchronized (ActivityManagerService.this) {
25551                return mActivityStartController.startActivitiesInPackage(packageUid, packageName,
25552                        intents, resolvedTypes, null /* resultTo */,
25553                        SafeActivityOptions.fromBundle(bOptions), userId);
25554            }
25555        }
25556
25557        @Override
25558        public int getUidProcessState(int uid) {
25559            return getUidState(uid);
25560        }
25561
25562        @Override
25563        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
25564            synchronized (ActivityManagerService.this) {
25565
25566                // We might change the visibilities here, so prepare an empty app transition which
25567                // might be overridden later if we actually change visibilities.
25568                final boolean wasTransitionSet =
25569                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
25570                if (!wasTransitionSet) {
25571                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
25572                            false /* alwaysKeepCurrent */);
25573                }
25574                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
25575
25576                // If there was a transition set already we don't want to interfere with it as we
25577                // might be starting it too early.
25578                if (!wasTransitionSet) {
25579                    mWindowManager.executeAppTransition();
25580                }
25581            }
25582            if (callback != null) {
25583                callback.run();
25584            }
25585        }
25586
25587        @Override
25588        public boolean isSystemReady() {
25589            // no need to synchronize(this) just to read & return the value
25590            return mSystemReady;
25591        }
25592
25593        @Override
25594        public void notifyKeyguardTrustedChanged() {
25595            synchronized (ActivityManagerService.this) {
25596                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
25597                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
25598                }
25599            }
25600        }
25601
25602        /**
25603         * Sets if the given pid has an overlay UI or not.
25604         *
25605         * @param pid The pid we are setting overlay UI for.
25606         * @param hasOverlayUi True if the process has overlay UI.
25607         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
25608         */
25609        @Override
25610        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
25611            synchronized (ActivityManagerService.this) {
25612                final ProcessRecord pr;
25613                synchronized (mPidsSelfLocked) {
25614                    pr = mPidsSelfLocked.get(pid);
25615                    if (pr == null) {
25616                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
25617                        return;
25618                    }
25619                }
25620                if (pr.hasOverlayUi == hasOverlayUi) {
25621                    return;
25622                }
25623                pr.hasOverlayUi = hasOverlayUi;
25624                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
25625                updateOomAdjLocked(pr, true);
25626            }
25627        }
25628
25629        /**
25630         * Called after the network policy rules are updated by
25631         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
25632         * and {@param procStateSeq}.
25633         */
25634        @Override
25635        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
25636            if (DEBUG_NETWORK) {
25637                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
25638                        + uid + " seq: " + procStateSeq);
25639            }
25640            UidRecord record;
25641            synchronized (ActivityManagerService.this) {
25642                record = mActiveUids.get(uid);
25643                if (record == null) {
25644                    if (DEBUG_NETWORK) {
25645                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
25646                                + " procStateSeq: " + procStateSeq);
25647                    }
25648                    return;
25649                }
25650            }
25651            synchronized (record.networkStateLock) {
25652                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
25653                    if (DEBUG_NETWORK) {
25654                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
25655                                + " been handled for uid: " + uid);
25656                    }
25657                    return;
25658                }
25659                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
25660                if (record.curProcStateSeq > procStateSeq) {
25661                    if (DEBUG_NETWORK) {
25662                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
25663                                + ", curProcstateSeq: " + record.curProcStateSeq
25664                                + ", procStateSeq: " + procStateSeq);
25665                    }
25666                    return;
25667                }
25668                if (record.waitingForNetwork) {
25669                    if (DEBUG_NETWORK) {
25670                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
25671                                + ", procStateSeq: " + procStateSeq);
25672                    }
25673                    record.networkStateLock.notifyAll();
25674                }
25675            }
25676        }
25677
25678        @Override
25679        public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
25680            synchronized (ActivityManagerService.this) {
25681                mActiveVoiceInteractionServiceComponent = component;
25682            }
25683        }
25684
25685        /**
25686         * Called after virtual display Id is updated by
25687         * {@link com.android.server.vr.Vr2dDisplay} with a specific
25688         * {@param vrVr2dDisplayId}.
25689         */
25690        @Override
25691        public void setVr2dDisplayId(int vr2dDisplayId) {
25692            if (DEBUG_STACK) {
25693                Slog.d(TAG, "setVr2dDisplayId called for: " +
25694                        vr2dDisplayId);
25695            }
25696            synchronized (ActivityManagerService.this) {
25697                mVr2dDisplayId = vr2dDisplayId;
25698            }
25699        }
25700
25701        @Override
25702        public void saveANRState(String reason) {
25703            synchronized (ActivityManagerService.this) {
25704                final StringWriter sw = new StringWriter();
25705                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
25706                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
25707                if (reason != null) {
25708                    pw.println("  Reason: " + reason);
25709                }
25710                pw.println();
25711                mActivityStartController.dump(pw, "  ", null);
25712                pw.println();
25713                pw.println("-------------------------------------------------------------------------------");
25714                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
25715                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
25716                        "" /* header */);
25717                pw.println();
25718                pw.close();
25719
25720                mLastANRState = sw.toString();
25721            }
25722        }
25723
25724        @Override
25725        public void clearSavedANRState() {
25726            synchronized (ActivityManagerService.this) {
25727                mLastANRState = null;
25728            }
25729        }
25730
25731        @Override
25732        public void setFocusedActivity(IBinder token) {
25733            synchronized (ActivityManagerService.this) {
25734                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
25735                if (r == null) {
25736                    throw new IllegalArgumentException(
25737                            "setFocusedActivity: No activity record matching token=" + token);
25738                }
25739                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
25740                        r, "setFocusedActivity")) {
25741                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
25742                }
25743            }
25744        }
25745
25746        @Override
25747        public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
25748            synchronized (ActivityManagerService.this) {
25749                if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
25750                    ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
25751                    if (types == null) {
25752                        if (uid < 0) {
25753                            return;
25754                        }
25755                        types = new ArrayMap<>();
25756                        mAllowAppSwitchUids.put(userId, types);
25757                    }
25758                    if (uid < 0) {
25759                        types.remove(type);
25760                    } else {
25761                        types.put(type, uid);
25762                    }
25763                }
25764            }
25765        }
25766
25767        @Override
25768        public boolean isRuntimeRestarted() {
25769            return mSystemServiceManager.isRuntimeRestarted();
25770        }
25771
25772        @Override
25773        public boolean hasRunningActivity(int uid, @Nullable String packageName) {
25774            if (packageName == null) return false;
25775
25776            synchronized (ActivityManagerService.this) {
25777                for (int i = 0; i < mLruProcesses.size(); i++) {
25778                    final ProcessRecord processRecord = mLruProcesses.get(i);
25779                    if (processRecord.uid == uid) {
25780                        for (int j = 0; j < processRecord.activities.size(); j++) {
25781                            final ActivityRecord activityRecord = processRecord.activities.get(j);
25782                            if (packageName.equals(activityRecord.packageName)) {
25783                                return true;
25784                            }
25785                        }
25786                    }
25787                }
25788            }
25789            return false;
25790        }
25791
25792        @Override
25793        public void registerScreenObserver(ScreenObserver observer) {
25794            mScreenObservers.add(observer);
25795        }
25796
25797        @Override
25798        public boolean canStartMoreUsers() {
25799            return mUserController.canStartMoreUsers();
25800        }
25801
25802        @Override
25803        public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
25804            mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
25805        }
25806
25807        @Override
25808        public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
25809            mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
25810        }
25811
25812        @Override
25813        public int getMaxRunningUsers() {
25814            return mUserController.mMaxRunningUsers;
25815        }
25816
25817        public boolean isCallerRecents(int callingUid) {
25818            return getRecentTasks().isCallerRecents(callingUid);
25819        }
25820    }
25821
25822    /**
25823     * Called by app main thread to wait for the network policy rules to get updated.
25824     *
25825     * @param procStateSeq The sequence number indicating the process state change that the main
25826     *                     thread is interested in.
25827     */
25828    @Override
25829    public void waitForNetworkStateUpdate(long procStateSeq) {
25830        final int callingUid = Binder.getCallingUid();
25831        if (DEBUG_NETWORK) {
25832            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
25833        }
25834        UidRecord record;
25835        synchronized (this) {
25836            record = mActiveUids.get(callingUid);
25837            if (record == null) {
25838                return;
25839            }
25840        }
25841        synchronized (record.networkStateLock) {
25842            if (record.lastDispatchedProcStateSeq < procStateSeq) {
25843                if (DEBUG_NETWORK) {
25844                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
25845                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
25846                            + " lastProcStateSeqDispatchedToObservers: "
25847                            + record.lastDispatchedProcStateSeq);
25848                }
25849                return;
25850            }
25851            if (record.curProcStateSeq > procStateSeq) {
25852                if (DEBUG_NETWORK) {
25853                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
25854                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
25855                            + ", procStateSeq: " + procStateSeq);
25856                }
25857                return;
25858            }
25859            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
25860                if (DEBUG_NETWORK) {
25861                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
25862                            + procStateSeq + ", so no need to wait. Uid: "
25863                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
25864                            + record.lastNetworkUpdatedProcStateSeq);
25865                }
25866                return;
25867            }
25868            try {
25869                if (DEBUG_NETWORK) {
25870                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
25871                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
25872                }
25873                final long startTime = SystemClock.uptimeMillis();
25874                record.waitingForNetwork = true;
25875                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
25876                record.waitingForNetwork = false;
25877                final long totalTime = SystemClock.uptimeMillis() - startTime;
25878                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
25879                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
25880                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
25881                            + procStateSeq + " UidRec: " + record
25882                            + " validateUidRec: " + mValidateUids.get(callingUid));
25883                }
25884            } catch (InterruptedException e) {
25885                Thread.currentThread().interrupt();
25886            }
25887        }
25888    }
25889
25890    public void waitForBroadcastIdle(PrintWriter pw) {
25891        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
25892        while (true) {
25893            boolean idle = true;
25894            synchronized (this) {
25895                for (BroadcastQueue queue : mBroadcastQueues) {
25896                    if (!queue.isIdle()) {
25897                        final String msg = "Waiting for queue " + queue + " to become idle...";
25898                        pw.println(msg);
25899                        pw.flush();
25900                        Slog.v(TAG, msg);
25901                        idle = false;
25902                    }
25903                }
25904            }
25905
25906            if (idle) {
25907                final String msg = "All broadcast queues are idle!";
25908                pw.println(msg);
25909                pw.flush();
25910                Slog.v(TAG, msg);
25911                return;
25912            } else {
25913                SystemClock.sleep(1000);
25914            }
25915        }
25916    }
25917
25918    /**
25919     * Return the user id of the last resumed activity.
25920     */
25921    @Override
25922    public @UserIdInt int getLastResumedActivityUserId() {
25923        enforceCallingPermission(
25924                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
25925        synchronized (this) {
25926            if (mLastResumedActivity == null) {
25927                return mUserController.getCurrentUserId();
25928            }
25929            return mLastResumedActivity.userId;
25930        }
25931    }
25932
25933    /**
25934     * Kill processes for the user with id userId and that depend on the package named packageName
25935     */
25936    @Override
25937    public void killPackageDependents(String packageName, int userId) {
25938        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
25939        if (packageName == null) {
25940            throw new NullPointerException(
25941                    "Cannot kill the dependents of a package without its name.");
25942        }
25943
25944        long callingId = Binder.clearCallingIdentity();
25945        IPackageManager pm = AppGlobals.getPackageManager();
25946        int pkgUid = -1;
25947        try {
25948            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
25949        } catch (RemoteException e) {
25950        }
25951        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
25952            throw new IllegalArgumentException(
25953                    "Cannot kill dependents of non-existing package " + packageName);
25954        }
25955        try {
25956            synchronized(this) {
25957                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
25958                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
25959                        "dep: " + packageName);
25960            }
25961        } finally {
25962            Binder.restoreCallingIdentity(callingId);
25963        }
25964    }
25965
25966    @Override
25967    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
25968            CharSequence message) throws RemoteException {
25969        if (message != null) {
25970            enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
25971                    "dismissKeyguard()");
25972        }
25973        final long callingId = Binder.clearCallingIdentity();
25974        try {
25975            mKeyguardController.dismissKeyguard(token, callback, message);
25976        } finally {
25977            Binder.restoreCallingIdentity(callingId);
25978        }
25979    }
25980
25981    @Override
25982    public int restartUserInBackground(final int userId) {
25983        return mUserController.restartUser(userId, /* foreground */ false);
25984    }
25985
25986    @Override
25987    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
25988        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
25989                "scheduleApplicationInfoChanged()");
25990
25991        synchronized (this) {
25992            final long origId = Binder.clearCallingIdentity();
25993            try {
25994                updateApplicationInfoLocked(packageNames, userId);
25995            } finally {
25996                Binder.restoreCallingIdentity(origId);
25997            }
25998        }
25999    }
26000
26001    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
26002        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
26003        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
26004            final ProcessRecord app = mLruProcesses.get(i);
26005            if (app.thread == null) {
26006                continue;
26007            }
26008
26009            if (userId != UserHandle.USER_ALL && app.userId != userId) {
26010                continue;
26011            }
26012
26013            final int packageCount = app.pkgList.size();
26014            for (int j = 0; j < packageCount; j++) {
26015                final String packageName = app.pkgList.keyAt(j);
26016                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
26017                    try {
26018                        final ApplicationInfo ai = AppGlobals.getPackageManager()
26019                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
26020                        if (ai != null) {
26021                            app.thread.scheduleApplicationInfoChanged(ai);
26022                        }
26023                    } catch (RemoteException e) {
26024                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
26025                                    packageName, app));
26026                    }
26027                }
26028            }
26029        }
26030        if (updateFrameworkRes) {
26031            // Update system server components that need to know about changed overlays. Because the
26032            // overlay is applied in ActivityThread, we need to serialize through its thread too.
26033            final Executor executor = ActivityThread.currentActivityThread().getExecutor();
26034            final DisplayManagerInternal display =
26035                    LocalServices.getService(DisplayManagerInternal.class);
26036            if (display != null) {
26037                executor.execute(display::onOverlayChanged);
26038            }
26039            if (mWindowManager != null) {
26040                executor.execute(mWindowManager::onOverlayChanged);
26041            }
26042        }
26043    }
26044
26045    /**
26046     * Attach an agent to the specified process (proces name or PID)
26047     */
26048    public void attachAgent(String process, String path) {
26049        try {
26050            synchronized (this) {
26051                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
26052                if (proc == null || proc.thread == null) {
26053                    throw new IllegalArgumentException("Unknown process: " + process);
26054                }
26055
26056                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26057                if (!isDebuggable) {
26058                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26059                        throw new SecurityException("Process not debuggable: " + proc);
26060                    }
26061                }
26062
26063                proc.thread.attachAgent(path);
26064            }
26065        } catch (RemoteException e) {
26066            throw new IllegalStateException("Process disappeared");
26067        }
26068    }
26069
26070    @VisibleForTesting
26071    public static class Injector {
26072        private NetworkManagementInternal mNmi;
26073
26074        public Context getContext() {
26075            return null;
26076        }
26077
26078        public AppOpsService getAppOpsService(File file, Handler handler) {
26079            return new AppOpsService(file, handler);
26080        }
26081
26082        public Handler getUiHandler(ActivityManagerService service) {
26083            return service.new UiHandler();
26084        }
26085
26086        public boolean isNetworkRestrictedForUid(int uid) {
26087            if (ensureHasNetworkManagementInternal()) {
26088                return mNmi.isNetworkRestrictedForUid(uid);
26089            }
26090            return false;
26091        }
26092
26093        private boolean ensureHasNetworkManagementInternal() {
26094            if (mNmi == null) {
26095                mNmi = LocalServices.getService(NetworkManagementInternal.class);
26096            }
26097            return mNmi != null;
26098        }
26099    }
26100
26101    @Override
26102    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
26103            throws RemoteException {
26104        synchronized (this) {
26105            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26106            if (r == null) {
26107                return;
26108            }
26109            final long origId = Binder.clearCallingIdentity();
26110            try {
26111                r.setShowWhenLocked(showWhenLocked);
26112            } finally {
26113                Binder.restoreCallingIdentity(origId);
26114            }
26115        }
26116    }
26117
26118    @Override
26119    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
26120        synchronized (this) {
26121            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26122            if (r == null) {
26123                return;
26124            }
26125            final long origId = Binder.clearCallingIdentity();
26126            try {
26127                r.setTurnScreenOn(turnScreenOn);
26128            } finally {
26129                Binder.restoreCallingIdentity(origId);
26130            }
26131        }
26132    }
26133
26134    @Override
26135    public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
26136            throws RemoteException {
26137        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
26138                "registerRemoteAnimations");
26139        synchronized (this) {
26140            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26141            if (r == null) {
26142                return;
26143            }
26144            final long origId = Binder.clearCallingIdentity();
26145            try {
26146                r.registerRemoteAnimations(definition);
26147            } finally {
26148                Binder.restoreCallingIdentity(origId);
26149            }
26150        }
26151    }
26152}
26153