ActivityManagerService.java revision a9033876de10c6ab6704e6a2fa3e377eefb0bcb6
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
22import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
23import static android.Manifest.permission.INTERACT_ACROSS_USERS;
24import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
25import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
26import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
27import static android.Manifest.permission.READ_FRAME_BUFFER;
28import static android.Manifest.permission.REMOVE_TASKS;
29import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
30import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
31import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
32import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
33import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
34import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT;
35import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA;
36import static android.app.ActivityManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
37import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE;
38import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
39import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
40import static android.app.AppOpsManager.OP_NONE;
41import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
42import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
43import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
44import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
45import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
46import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
47import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
48import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
49import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
50import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
51import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
52import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
53import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
54import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
55import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
56import static android.content.pm.PackageManager.GET_PROVIDERS;
57import static android.content.pm.PackageManager.MATCH_ANY_USER;
58import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
59import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
60import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
61import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
62import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
63import static android.content.pm.PackageManager.PERMISSION_GRANTED;
64import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
65import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
66import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
67import static android.os.Build.VERSION_CODES.N;
68import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
69import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
70import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
71import static android.os.IServiceManager.DUMP_FLAG_PROTO;
72import static android.os.Process.BLUETOOTH_UID;
73import static android.os.Process.FIRST_APPLICATION_UID;
74import static android.os.Process.FIRST_ISOLATED_UID;
75import static android.os.Process.LAST_ISOLATED_UID;
76import static android.os.Process.NFC_UID;
77import static android.os.Process.PHONE_UID;
78import static android.os.Process.PROC_CHAR;
79import static android.os.Process.PROC_OUT_LONG;
80import static android.os.Process.PROC_PARENS;
81import static android.os.Process.PROC_SPACE_TERM;
82import static android.os.Process.ProcessStartResult;
83import static android.os.Process.ROOT_UID;
84import static android.os.Process.SCHED_FIFO;
85import static android.os.Process.SCHED_OTHER;
86import static android.os.Process.SCHED_RESET_ON_FORK;
87import static android.os.Process.SHELL_UID;
88import static android.os.Process.SIGNAL_QUIT;
89import static android.os.Process.SIGNAL_USR1;
90import static android.os.Process.SYSTEM_UID;
91import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
92import static android.os.Process.THREAD_GROUP_DEFAULT;
93import static android.os.Process.THREAD_GROUP_TOP_APP;
94import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
95import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
96import static android.os.Process.getFreeMemory;
97import static android.os.Process.getTotalMemory;
98import static android.os.Process.isThreadInProcess;
99import static android.os.Process.killProcess;
100import static android.os.Process.killProcessQuiet;
101import static android.os.Process.myPid;
102import static android.os.Process.myUid;
103import static android.os.Process.readProcFile;
104import static android.os.Process.removeAllProcessGroups;
105import static android.os.Process.sendSignal;
106import static android.os.Process.setProcessGroup;
107import static android.os.Process.setThreadPriority;
108import static android.os.Process.setThreadScheduler;
109import static android.os.Process.startWebView;
110import static android.os.Process.zygoteProcess;
111import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
112import static android.provider.Settings.Global.DEBUG_APP;
113import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
114import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
115import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
116import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
117import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
118import static android.provider.Settings.System.FONT_SCALE;
119import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
120import static android.text.format.DateUtils.DAY_IN_MILLIS;
121import static android.view.Display.DEFAULT_DISPLAY;
122import static android.view.Display.INVALID_DISPLAY;
123
124import static com.android.internal.util.XmlUtils.readBooleanAttribute;
125import static com.android.internal.util.XmlUtils.readIntAttribute;
126import static com.android.internal.util.XmlUtils.readLongAttribute;
127import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
128import static com.android.internal.util.XmlUtils.writeIntAttribute;
129import static com.android.internal.util.XmlUtils.writeLongAttribute;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
141import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
142import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
143import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
144import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
145import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
146import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
147import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
148import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
149import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
150import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
151import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
152import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
153import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
154import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
155import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
156import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
157import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
158import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
159import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
160import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
161import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
162import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
163import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
164import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
165import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
166import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
167import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
168import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
169import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
170import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
171import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
172import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
173import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
174import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
175import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
176import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
177import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
178import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
179import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
180import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
181import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
182import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
183import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
184import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
185import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
186import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
187import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
188import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
189import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
190import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
191import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
192import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
193import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
194import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
195import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
196import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
197import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
198import static android.view.WindowManager.TRANSIT_NONE;
199import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
200import static android.view.WindowManager.TRANSIT_TASK_OPEN;
201import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
202
203import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
204import static org.xmlpull.v1.XmlPullParser.START_TAG;
205
206import android.Manifest;
207import android.Manifest.permission;
208import android.annotation.NonNull;
209import android.annotation.Nullable;
210import android.annotation.UserIdInt;
211import android.app.Activity;
212import android.app.ActivityManager;
213import android.app.ActivityManager.RunningTaskInfo;
214import android.app.ActivityManager.StackInfo;
215import android.app.ActivityManager.TaskSnapshot;
216import android.app.ActivityManagerInternal;
217import android.app.ActivityManagerInternal.ScreenObserver;
218import android.app.ActivityManagerInternal.SleepToken;
219import android.app.ActivityManagerProto;
220import android.app.ActivityOptions;
221import android.app.ActivityThread;
222import android.app.AlertDialog;
223import android.app.AppGlobals;
224import android.app.AppOpsManager;
225import android.app.ApplicationErrorReport;
226import android.app.ApplicationThreadConstants;
227import android.app.BroadcastOptions;
228import android.app.ContentProviderHolder;
229import android.app.Dialog;
230import android.app.IActivityController;
231import android.app.IActivityManager;
232import android.app.IApplicationThread;
233import android.app.IAssistDataReceiver;
234import android.app.IInstrumentationWatcher;
235import android.app.INotificationManager;
236import android.app.IProcessObserver;
237import android.app.IServiceConnection;
238import android.app.IStopUserCallback;
239import android.app.ITaskStackListener;
240import android.app.IUiAutomationConnection;
241import android.app.IUidObserver;
242import android.app.IUserSwitchObserver;
243import android.app.Instrumentation;
244import android.app.Notification;
245import android.app.NotificationManager;
246import android.app.PendingIntent;
247import android.app.PictureInPictureParams;
248import android.app.ProfilerInfo;
249import android.app.RemoteAction;
250import android.app.WaitResult;
251import android.app.WindowConfiguration.ActivityType;
252import android.app.WindowConfiguration.WindowingMode;
253import android.app.admin.DevicePolicyManager;
254import android.app.assist.AssistContent;
255import android.app.assist.AssistStructure;
256import android.app.backup.IBackupManager;
257import android.app.servertransaction.ConfigurationChangeItem;
258import android.app.usage.UsageEvents;
259import android.app.usage.UsageStatsManagerInternal;
260import android.appwidget.AppWidgetManager;
261import android.content.ActivityNotFoundException;
262import android.content.BroadcastReceiver;
263import android.content.ClipData;
264import android.content.ComponentCallbacks2;
265import android.content.ComponentName;
266import android.content.ContentProvider;
267import android.content.ContentResolver;
268import android.content.Context;
269import android.content.DialogInterface;
270import android.content.IContentProvider;
271import android.content.IIntentReceiver;
272import android.content.IIntentSender;
273import android.content.Intent;
274import android.content.IntentFilter;
275import android.content.pm.ActivityInfo;
276import android.content.pm.ApplicationInfo;
277import android.content.pm.ConfigurationInfo;
278import android.content.pm.IPackageDataObserver;
279import android.content.pm.IPackageManager;
280import android.content.pm.InstrumentationInfo;
281import android.content.pm.PackageInfo;
282import android.content.pm.PackageManager;
283import android.content.pm.PackageManager.NameNotFoundException;
284import android.content.pm.PackageManagerInternal;
285import android.content.pm.ParceledListSlice;
286import android.content.pm.PathPermission;
287import android.content.pm.PermissionInfo;
288import android.content.pm.ProviderInfo;
289import android.content.pm.ResolveInfo;
290import android.content.pm.SELinuxUtil;
291import android.content.pm.ServiceInfo;
292import android.content.pm.UserInfo;
293import android.content.res.CompatibilityInfo;
294import android.content.res.Configuration;
295import android.content.res.Resources;
296import android.database.ContentObserver;
297import android.graphics.Bitmap;
298import android.graphics.Point;
299import android.graphics.Rect;
300import android.hardware.display.DisplayManagerInternal;
301import android.location.LocationManager;
302import android.media.audiofx.AudioEffect;
303import android.metrics.LogMaker;
304import android.net.Proxy;
305import android.net.ProxyInfo;
306import android.net.Uri;
307import android.os.BatteryStats;
308import android.os.Binder;
309import android.os.Build;
310import android.os.Bundle;
311import android.os.Debug;
312import android.os.DropBoxManager;
313import android.os.Environment;
314import android.os.FactoryTest;
315import android.os.FileObserver;
316import android.os.FileUtils;
317import android.os.Handler;
318import android.os.IBinder;
319import android.os.IDeviceIdentifiersPolicyService;
320import android.os.IPermissionController;
321import android.os.IProcessInfoService;
322import android.os.IProgressListener;
323import android.os.LocaleList;
324import android.os.Looper;
325import android.os.Message;
326import android.os.Parcel;
327import android.os.ParcelFileDescriptor;
328import android.os.PersistableBundle;
329import android.os.PowerManager;
330import android.os.PowerManager.ServiceType;
331import android.os.PowerManagerInternal;
332import android.os.Process;
333import android.os.RemoteCallbackList;
334import android.os.RemoteException;
335import android.os.ResultReceiver;
336import android.os.ServiceManager;
337import android.os.ShellCallback;
338import android.os.StrictMode;
339import android.os.SystemClock;
340import android.os.SystemProperties;
341import android.os.Trace;
342import android.os.TransactionTooLargeException;
343import android.os.UpdateLock;
344import android.os.UserHandle;
345import android.os.UserManager;
346import android.os.WorkSource;
347import android.os.storage.IStorageManager;
348import android.os.storage.StorageManager;
349import android.os.storage.StorageManagerInternal;
350import android.provider.Downloads;
351import android.provider.Settings;
352import android.service.voice.IVoiceInteractionSession;
353import android.service.voice.VoiceInteractionManagerInternal;
354import android.telecom.TelecomManager;
355import android.text.TextUtils;
356import android.text.format.DateUtils;
357import android.text.format.Time;
358import android.text.style.SuggestionSpan;
359import android.util.ArrayMap;
360import android.util.ArraySet;
361import android.util.AtomicFile;
362import android.util.DebugUtils;
363import android.util.EventLog;
364import android.util.Log;
365import android.util.LongSparseArray;
366import android.util.Pair;
367import android.util.PrintWriterPrinter;
368import android.util.Slog;
369import android.util.SparseArray;
370import android.util.SparseIntArray;
371import android.util.StatsLog;
372import android.util.TimeUtils;
373import android.util.TimingsTraceLog;
374import android.util.Xml;
375import android.util.proto.ProtoOutputStream;
376import android.util.proto.ProtoUtils;
377import android.view.Gravity;
378import android.view.LayoutInflater;
379import android.view.RemoteAnimationDefinition;
380import android.view.View;
381import android.view.WindowManager;
382
383import com.android.internal.R;
384import com.android.internal.annotations.GuardedBy;
385import com.android.internal.annotations.VisibleForTesting;
386import com.android.internal.app.AssistUtils;
387import com.android.internal.app.DumpHeapActivity;
388import com.android.internal.app.IAppOpsCallback;
389import com.android.internal.app.IAppOpsService;
390import com.android.internal.app.IVoiceInteractor;
391import com.android.internal.app.ProcessMap;
392import com.android.internal.app.SystemUserHomeActivity;
393import com.android.internal.app.procstats.ProcessStats;
394import com.android.internal.logging.MetricsLogger;
395import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
396import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
397import com.android.internal.notification.SystemNotificationChannels;
398import com.android.internal.os.BackgroundThread;
399import com.android.internal.os.BatteryStatsImpl;
400import com.android.internal.os.BinderInternal;
401import com.android.internal.os.logging.MetricsLoggerWrapper;
402import com.android.internal.os.ByteTransferPipe;
403import com.android.internal.os.IResultReceiver;
404import com.android.internal.os.ProcessCpuTracker;
405import com.android.internal.os.TransferPipe;
406import com.android.internal.os.Zygote;
407import com.android.internal.policy.IKeyguardDismissCallback;
408import com.android.internal.policy.KeyguardDismissCallback;
409import com.android.internal.telephony.TelephonyIntents;
410import com.android.internal.util.ArrayUtils;
411import com.android.internal.util.DumpUtils;
412import com.android.internal.util.FastPrintWriter;
413import com.android.internal.util.FastXmlSerializer;
414import com.android.internal.util.MemInfoReader;
415import com.android.internal.util.Preconditions;
416import com.android.server.AlarmManagerInternal;
417import com.android.server.AppOpsService;
418import com.android.server.AttributeCache;
419import com.android.server.DeviceIdleController;
420import com.android.server.IntentResolver;
421import com.android.server.IoThread;
422import com.android.server.LocalServices;
423import com.android.server.LockGuard;
424import com.android.server.NetworkManagementInternal;
425import com.android.server.RescueParty;
426import com.android.server.ServiceThread;
427import com.android.server.SystemConfig;
428import com.android.server.SystemService;
429import com.android.server.SystemServiceManager;
430import com.android.server.ThreadPriorityBooster;
431import com.android.server.Watchdog;
432import com.android.server.am.ActivityStack.ActivityState;
433import com.android.server.am.proto.ActivityManagerServiceProto;
434import com.android.server.am.proto.BroadcastProto;
435import com.android.server.am.proto.GrantUriProto;
436import com.android.server.am.proto.ImportanceTokenProto;
437import com.android.server.am.proto.MemInfoProto;
438import com.android.server.am.proto.NeededUriGrantsProto;
439import com.android.server.am.proto.ProcessOomProto;
440import com.android.server.am.proto.ProcessToGcProto;
441import com.android.server.am.proto.ProcessesProto;
442import com.android.server.am.proto.ProcessesProto.UidObserverRegistrationProto;
443import com.android.server.am.proto.StickyBroadcastProto;
444import com.android.server.firewall.IntentFirewall;
445import com.android.server.job.JobSchedulerInternal;
446import com.android.server.pm.Installer;
447import com.android.server.pm.Installer.InstallerException;
448import com.android.server.utils.PriorityDump;
449import com.android.server.vr.VrManagerInternal;
450import com.android.server.wm.PinnedStackWindowController;
451import com.android.server.wm.WindowManagerService;
452
453import dalvik.system.VMRuntime;
454
455import libcore.io.IoUtils;
456import libcore.util.EmptyArray;
457
458import com.google.android.collect.Lists;
459import com.google.android.collect.Maps;
460
461import org.xmlpull.v1.XmlPullParser;
462import org.xmlpull.v1.XmlPullParserException;
463import org.xmlpull.v1.XmlSerializer;
464
465import java.io.File;
466import java.io.FileDescriptor;
467import java.io.FileInputStream;
468import java.io.FileNotFoundException;
469import java.io.FileOutputStream;
470import java.io.IOException;
471import java.io.InputStreamReader;
472import java.io.PrintWriter;
473import java.io.StringWriter;
474import java.io.UnsupportedEncodingException;
475import java.lang.ref.WeakReference;
476import java.nio.charset.StandardCharsets;
477import java.text.DateFormat;
478import java.text.SimpleDateFormat;
479import java.util.ArrayList;
480import java.util.Arrays;
481import java.util.Collections;
482import java.util.Comparator;
483import java.util.Date;
484import java.util.HashMap;
485import java.util.HashSet;
486import java.util.Iterator;
487import java.util.List;
488import java.util.Locale;
489import java.util.Map;
490import java.util.Objects;
491import java.util.Set;
492import java.util.concurrent.CountDownLatch;
493import java.util.concurrent.Executor;
494import java.util.concurrent.atomic.AtomicBoolean;
495import java.util.concurrent.atomic.AtomicLong;
496
497public class ActivityManagerService extends IActivityManager.Stub
498        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
499
500    /**
501     * Priority we boost main thread and RT of top app to.
502     */
503    public static final int TOP_APP_PRIORITY_BOOST = -10;
504
505    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
506    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
507    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
508    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
509    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
510    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
511    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
512    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
513    private static final String TAG_LRU = TAG + POSTFIX_LRU;
514    private static final String TAG_MU = TAG + POSTFIX_MU;
515    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
516    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
517    private static final String TAG_POWER = TAG + POSTFIX_POWER;
518    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
519    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
520    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
521    private static final String TAG_PSS = TAG + POSTFIX_PSS;
522    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
523    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
524    private static final String TAG_STACK = TAG + POSTFIX_STACK;
525    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
526    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
527    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
528    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
529
530    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
531    // here so that while the job scheduler can depend on AMS, the other way around
532    // need not be the case.
533    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
534
535    /** Control over CPU and battery monitoring */
536    // write battery stats every 30 minutes.
537    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
538    static final boolean MONITOR_CPU_USAGE = true;
539    // don't sample cpu less than every 5 seconds.
540    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
541    // wait possibly forever for next cpu sample.
542    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
543    static final boolean MONITOR_THREAD_CPU_USAGE = false;
544
545    // The flags that are set for all calls we make to the package manager.
546    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
547
548    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
549
550    // Amount of time after a call to stopAppSwitches() during which we will
551    // prevent further untrusted switches from happening.
552    static final long APP_SWITCH_DELAY_TIME = 5*1000;
553
554    // How long we wait for a launched process to attach to the activity manager
555    // before we decide it's never going to come up for real.
556    static final int PROC_START_TIMEOUT = 10*1000;
557    // How long we wait for an attached process to publish its content providers
558    // before we decide it must be hung.
559    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
560
561    // How long we wait for a launched process to attach to the activity manager
562    // before we decide it's never going to come up for real, when the process was
563    // started with a wrapper for instrumentation (such as Valgrind) because it
564    // could take much longer than usual.
565    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
566
567    // How long we allow a receiver to run before giving up on it.
568    static final int BROADCAST_FG_TIMEOUT = 10*1000;
569    static final int BROADCAST_BG_TIMEOUT = 60*1000;
570
571    // How long we wait until we timeout on key dispatching.
572    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
573
574    // How long we wait until we timeout on key dispatching during instrumentation.
575    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
576
577    // How long to wait in getAssistContextExtras for the activity and foreground services
578    // to respond with the result.
579    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
580
581    // How long top wait when going through the modern assist (which doesn't need to block
582    // on getting this result before starting to launch its UI).
583    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
584
585    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
586    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
587
588    // Maximum number of persisted Uri grants a package is allowed
589    static final int MAX_PERSISTED_URI_GRANTS = 128;
590
591    static final int MY_PID = myPid();
592
593    static final String[] EMPTY_STRING_ARRAY = new String[0];
594
595    // How many bytes to write into the dropbox log before truncating
596    static final int DROPBOX_MAX_SIZE = 192 * 1024;
597    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
598    // as one line, but close enough for now.
599    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
600
601    // Access modes for handleIncomingUser.
602    static final int ALLOW_NON_FULL = 0;
603    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
604    static final int ALLOW_FULL_ONLY = 2;
605
606    // Necessary ApplicationInfo flags to mark an app as persistent
607    private static final int PERSISTENT_MASK =
608            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
609
610    // Intent sent when remote bugreport collection has been completed
611    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
612            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
613
614    // Used to indicate that an app transition should be animated.
615    static final boolean ANIMATE = true;
616
617    // Determines whether to take full screen screenshots
618    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
619
620    /**
621     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
622     */
623    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
624
625    /**
626     * State indicating that there is no need for any blocking for network.
627     */
628    @VisibleForTesting
629    static final int NETWORK_STATE_NO_CHANGE = 0;
630
631    /**
632     * State indicating that the main thread needs to be informed about the network wait.
633     */
634    @VisibleForTesting
635    static final int NETWORK_STATE_BLOCK = 1;
636
637    /**
638     * State indicating that any threads waiting for network state to get updated can be unblocked.
639     */
640    @VisibleForTesting
641    static final int NETWORK_STATE_UNBLOCK = 2;
642
643    // Max character limit for a notification title. If the notification title is larger than this
644    // the notification will not be legible to the user.
645    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
646
647    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
648
649    /** All system services */
650    SystemServiceManager mSystemServiceManager;
651
652    // Wrapper around VoiceInteractionServiceManager
653    private AssistUtils mAssistUtils;
654
655    // Keeps track of the active voice interaction service component, notified from
656    // VoiceInteractionManagerService
657    ComponentName mActiveVoiceInteractionServiceComponent;
658
659    private Installer mInstaller;
660
661    /** Run all ActivityStacks through this */
662    final ActivityStackSupervisor mStackSupervisor;
663    private final KeyguardController mKeyguardController;
664
665    private final ActivityStartController mActivityStartController;
666
667    final ClientLifecycleManager mLifecycleManager;
668
669    final TaskChangeNotificationController mTaskChangeNotificationController;
670
671    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
672
673    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
674
675    public final IntentFirewall mIntentFirewall;
676
677    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
678    // default action automatically.  Important for devices without direct input
679    // devices.
680    private boolean mShowDialogs = true;
681
682    private final VrController mVrController;
683
684    // VR Vr2d Display Id.
685    int mVr2dDisplayId = INVALID_DISPLAY;
686
687    // Whether we should use SCHED_FIFO for UI and RenderThreads.
688    private boolean mUseFifoUiScheduling = false;
689
690    BroadcastQueue mFgBroadcastQueue;
691    BroadcastQueue mBgBroadcastQueue;
692    // Convenient for easy iteration over the queues. Foreground is first
693    // so that dispatch of foreground broadcasts gets precedence.
694    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
695
696    BroadcastStats mLastBroadcastStats;
697    BroadcastStats mCurBroadcastStats;
698
699    BroadcastQueue broadcastQueueForIntent(Intent intent) {
700        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
701        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
702                "Broadcast intent " + intent + " on "
703                + (isFg ? "foreground" : "background") + " queue");
704        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
705    }
706
707    /**
708     * The last resumed activity. This is identical to the current resumed activity most
709     * of the time but could be different when we're pausing one activity before we resume
710     * another activity.
711     */
712    private ActivityRecord mLastResumedActivity;
713
714    /**
715     * If non-null, we are tracking the time the user spends in the currently focused app.
716     */
717    private AppTimeTracker mCurAppTimeTracker;
718
719    /**
720     * List of intents that were used to start the most recent tasks.
721     */
722    private final RecentTasks mRecentTasks;
723
724    /**
725     * For addAppTask: cached of the last activity component that was added.
726     */
727    ComponentName mLastAddedTaskComponent;
728
729    /**
730     * For addAppTask: cached of the last activity uid that was added.
731     */
732    int mLastAddedTaskUid;
733
734    /**
735     * For addAppTask: cached of the last ActivityInfo that was added.
736     */
737    ActivityInfo mLastAddedTaskActivity;
738
739    /**
740     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
741     */
742    String mDeviceOwnerName;
743
744    /**
745     * The controller for all operations related to locktask.
746     */
747    final LockTaskController mLockTaskController;
748
749    final UserController mUserController;
750
751    /**
752     * Packages that are being allowed to perform unrestricted app switches.  Mapping is
753     * User -> Type -> uid.
754     */
755    final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
756
757    final AppErrors mAppErrors;
758
759    final AppWarnings mAppWarnings;
760
761    /**
762     * Dump of the activity state at the time of the last ANR. Cleared after
763     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
764     */
765    String mLastANRState;
766
767    /**
768     * Indicates the maximum time spent waiting for the network rules to get updated.
769     */
770    @VisibleForTesting
771    long mWaitForNetworkTimeoutMs;
772
773    /**
774     * Helper class which parses out priority arguments and dumps sections according to their
775     * priority. If priority arguments are omitted, function calls the legacy dump command.
776     */
777    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
778        @Override
779        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
780                boolean asProto) {
781            if (asProto) return;
782            doDump(fd, pw, new String[]{"activities"}, asProto);
783        }
784
785        @Override
786        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
787            if (asProto) {
788                doDump(fd, pw, new String[0], asProto);
789            } else {
790                doDump(fd, pw, new String[]{"settings"}, asProto);
791                doDump(fd, pw, new String[]{"intents"}, asProto);
792                doDump(fd, pw, new String[]{"broadcasts"}, asProto);
793                doDump(fd, pw, new String[]{"providers"}, asProto);
794                doDump(fd, pw, new String[]{"permissions"}, asProto);
795                doDump(fd, pw, new String[]{"services"}, asProto);
796                doDump(fd, pw, new String[]{"recents"}, asProto);
797                doDump(fd, pw, new String[]{"lastanr"}, asProto);
798                doDump(fd, pw, new String[]{"starter"}, asProto);
799                if (mAssociations.size() > 0) {
800                    doDump(fd, pw, new String[]{"associations"}, asProto);
801                }
802                doDump(fd, pw, new String[]{"processes"}, asProto);
803            }
804        }
805
806        @Override
807        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
808            doDump(fd, pw, args, asProto);
809        }
810    };
811
812    public boolean canShowErrorDialogs() {
813        return mShowDialogs && !mSleeping && !mShuttingDown
814                && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
815                && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
816                        mUserController.getCurrentUserId())
817                && !(UserManager.isDeviceInDemoMode(mContext)
818                        && mUserController.getCurrentUser().isDemo());
819    }
820
821    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
822            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
823
824    static void boostPriorityForLockedSection() {
825        sThreadPriorityBooster.boost();
826    }
827
828    static void resetPriorityAfterLockedSection() {
829        sThreadPriorityBooster.reset();
830    }
831
832    public class PendingAssistExtras extends Binder implements Runnable {
833        public final ActivityRecord activity;
834        public boolean isHome;
835        public final Bundle extras;
836        public final Intent intent;
837        public final String hint;
838        public final IAssistDataReceiver receiver;
839        public final int userHandle;
840        public boolean haveResult = false;
841        public Bundle result = null;
842        public AssistStructure structure = null;
843        public AssistContent content = null;
844        public Bundle receiverExtras;
845
846        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
847                String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
848                int _userHandle) {
849            activity = _activity;
850            extras = _extras;
851            intent = _intent;
852            hint = _hint;
853            receiver = _receiver;
854            receiverExtras = _receiverExtras;
855            userHandle = _userHandle;
856        }
857
858        @Override
859        public void run() {
860            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
861            synchronized (this) {
862                haveResult = true;
863                notifyAll();
864            }
865            pendingAssistExtrasTimedOut(this);
866        }
867    }
868
869    final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
870
871    /**
872     * Process management.
873     */
874    final ProcessList mProcessList = new ProcessList();
875
876    /**
877     * All of the applications we currently have running organized by name.
878     * The keys are strings of the application package name (as
879     * returned by the package manager), and the keys are ApplicationRecord
880     * objects.
881     */
882    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
883
884    /**
885     * Tracking long-term execution of processes to look for abuse and other
886     * bad app behavior.
887     */
888    final ProcessStatsService mProcessStats;
889
890    /**
891     * The currently running isolated processes.
892     */
893    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
894
895    /**
896     * Counter for assigning isolated process uids, to avoid frequently reusing the
897     * same ones.
898     */
899    int mNextIsolatedProcessUid = 0;
900
901    /**
902     * The currently running heavy-weight process, if any.
903     */
904    ProcessRecord mHeavyWeightProcess = null;
905
906    /**
907     * Non-persistent appId whitelist for background restrictions
908     */
909    int[] mBackgroundAppIdWhitelist = new int[] {
910            BLUETOOTH_UID
911    };
912
913    /**
914     * Broadcast actions that will always be deliverable to unlaunched/background apps
915     */
916    ArraySet<String> mBackgroundLaunchBroadcasts;
917
918    /**
919     * All of the processes we currently have running organized by pid.
920     * The keys are the pid running the application.
921     *
922     * <p>NOTE: This object is protected by its own lock, NOT the global
923     * activity manager lock!
924     */
925    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
926
927    /**
928     * All of the processes that have been forced to be important.  The key
929     * is the pid of the caller who requested it (we hold a death
930     * link on it).
931     */
932    abstract class ImportanceToken implements IBinder.DeathRecipient {
933        final int pid;
934        final IBinder token;
935        final String reason;
936
937        ImportanceToken(int _pid, IBinder _token, String _reason) {
938            pid = _pid;
939            token = _token;
940            reason = _reason;
941        }
942
943        @Override
944        public String toString() {
945            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
946                    + " " + reason + " " + pid + " " + token + " }";
947        }
948
949        void writeToProto(ProtoOutputStream proto, long fieldId) {
950            final long pToken = proto.start(fieldId);
951            proto.write(ImportanceTokenProto.PID, pid);
952            if (token != null) {
953                proto.write(ImportanceTokenProto.TOKEN, token.toString());
954            }
955            proto.write(ImportanceTokenProto.REASON, reason);
956            proto.end(pToken);
957        }
958    }
959    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
960
961    /**
962     * List of records for processes that someone had tried to start before the
963     * system was ready.  We don't start them at that point, but ensure they
964     * are started by the time booting is complete.
965     */
966    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
967
968    /**
969     * List of persistent applications that are in the process
970     * of being started.
971     */
972    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
973
974    /**
975     * Processes that are being forcibly torn down.
976     */
977    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
978
979    /**
980     * List of running applications, sorted by recent usage.
981     * The first entry in the list is the least recently used.
982     */
983    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
984
985    /**
986     * Where in mLruProcesses that the processes hosting activities start.
987     */
988    int mLruProcessActivityStart = 0;
989
990    /**
991     * Where in mLruProcesses that the processes hosting services start.
992     * This is after (lower index) than mLruProcessesActivityStart.
993     */
994    int mLruProcessServiceStart = 0;
995
996    /**
997     * List of processes that should gc as soon as things are idle.
998     */
999    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
1000
1001    /**
1002     * Processes we want to collect PSS data from.
1003     */
1004    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
1005
1006    private boolean mBinderTransactionTrackingEnabled = false;
1007
1008    /**
1009     * Last time we requested PSS data of all processes.
1010     */
1011    long mLastFullPssTime = SystemClock.uptimeMillis();
1012
1013    /**
1014     * If set, the next time we collect PSS data we should do a full collection
1015     * with data from native processes and the kernel.
1016     */
1017    boolean mFullPssPending = false;
1018
1019    /**
1020     * This is the process holding what we currently consider to be
1021     * the "home" activity.
1022     */
1023    ProcessRecord mHomeProcess;
1024
1025    /**
1026     * This is the process holding the activity the user last visited that
1027     * is in a different process from the one they are currently in.
1028     */
1029    ProcessRecord mPreviousProcess;
1030
1031    /**
1032     * The time at which the previous process was last visible.
1033     */
1034    long mPreviousProcessVisibleTime;
1035
1036    /**
1037     * Track all uids that have actively running processes.
1038     */
1039    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1040
1041    /**
1042     * This is for verifying the UID report flow.
1043     */
1044    static final boolean VALIDATE_UID_STATES = true;
1045    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1046
1047    /**
1048     * Packages that the user has asked to have run in screen size
1049     * compatibility mode instead of filling the screen.
1050     */
1051    final CompatModePackages mCompatModePackages;
1052
1053    /**
1054     * Set of IntentSenderRecord objects that are currently active.
1055     */
1056    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1057            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1058
1059    /**
1060     * Fingerprints (hashCode()) of stack traces that we've
1061     * already logged DropBox entries for.  Guarded by itself.  If
1062     * something (rogue user app) forces this over
1063     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1064     */
1065    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1066    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1067
1068    /**
1069     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1070     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1071     */
1072    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1073
1074    /**
1075     * Resolver for broadcast intents to registered receivers.
1076     * Holds BroadcastFilter (subclass of IntentFilter).
1077     */
1078    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1079            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1080        @Override
1081        protected boolean allowFilterResult(
1082                BroadcastFilter filter, List<BroadcastFilter> dest) {
1083            IBinder target = filter.receiverList.receiver.asBinder();
1084            for (int i = dest.size() - 1; i >= 0; i--) {
1085                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1086                    return false;
1087                }
1088            }
1089            return true;
1090        }
1091
1092        @Override
1093        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1094            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1095                    || userId == filter.owningUserId) {
1096                return super.newResult(filter, match, userId);
1097            }
1098            return null;
1099        }
1100
1101        @Override
1102        protected BroadcastFilter[] newArray(int size) {
1103            return new BroadcastFilter[size];
1104        }
1105
1106        @Override
1107        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1108            return packageName.equals(filter.packageName);
1109        }
1110    };
1111
1112    /**
1113     * State of all active sticky broadcasts per user.  Keys are the action of the
1114     * sticky Intent, values are an ArrayList of all broadcasted intents with
1115     * that action (which should usually be one).  The SparseArray is keyed
1116     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1117     * for stickies that are sent to all users.
1118     */
1119    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1120            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1121
1122    final ActiveServices mServices;
1123
1124    final static class Association {
1125        final int mSourceUid;
1126        final String mSourceProcess;
1127        final int mTargetUid;
1128        final ComponentName mTargetComponent;
1129        final String mTargetProcess;
1130
1131        int mCount;
1132        long mTime;
1133
1134        int mNesting;
1135        long mStartTime;
1136
1137        // states of the source process when the bind occurred.
1138        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1139        long mLastStateUptime;
1140        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1141                - ActivityManager.MIN_PROCESS_STATE+1];
1142
1143        Association(int sourceUid, String sourceProcess, int targetUid,
1144                ComponentName targetComponent, String targetProcess) {
1145            mSourceUid = sourceUid;
1146            mSourceProcess = sourceProcess;
1147            mTargetUid = targetUid;
1148            mTargetComponent = targetComponent;
1149            mTargetProcess = targetProcess;
1150        }
1151    }
1152
1153    /**
1154     * When service association tracking is enabled, this is all of the associations we
1155     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1156     * -> association data.
1157     */
1158    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1159            mAssociations = new SparseArray<>();
1160    boolean mTrackingAssociations;
1161
1162    /**
1163     * Backup/restore process management
1164     */
1165    String mBackupAppName = null;
1166    BackupRecord mBackupTarget = null;
1167
1168    final ProviderMap mProviderMap;
1169
1170    /**
1171     * List of content providers who have clients waiting for them.  The
1172     * application is currently being launched and the provider will be
1173     * removed from this list once it is published.
1174     */
1175    final ArrayList<ContentProviderRecord> mLaunchingProviders
1176            = new ArrayList<ContentProviderRecord>();
1177
1178    /**
1179     * File storing persisted {@link #mGrantedUriPermissions}.
1180     */
1181    private final AtomicFile mGrantFile;
1182
1183    /** XML constants used in {@link #mGrantFile} */
1184    private static final String TAG_URI_GRANTS = "uri-grants";
1185    private static final String TAG_URI_GRANT = "uri-grant";
1186    private static final String ATTR_USER_HANDLE = "userHandle";
1187    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1188    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1189    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1190    private static final String ATTR_TARGET_PKG = "targetPkg";
1191    private static final String ATTR_URI = "uri";
1192    private static final String ATTR_MODE_FLAGS = "modeFlags";
1193    private static final String ATTR_CREATED_TIME = "createdTime";
1194    private static final String ATTR_PREFIX = "prefix";
1195
1196    /**
1197     * Global set of specific {@link Uri} permissions that have been granted.
1198     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1199     * to {@link UriPermission#uri} to {@link UriPermission}.
1200     */
1201    @GuardedBy("this")
1202    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1203            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1204
1205    public static class GrantUri {
1206        public final int sourceUserId;
1207        public final Uri uri;
1208        public boolean prefix;
1209
1210        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1211            this.sourceUserId = sourceUserId;
1212            this.uri = uri;
1213            this.prefix = prefix;
1214        }
1215
1216        @Override
1217        public int hashCode() {
1218            int hashCode = 1;
1219            hashCode = 31 * hashCode + sourceUserId;
1220            hashCode = 31 * hashCode + uri.hashCode();
1221            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1222            return hashCode;
1223        }
1224
1225        @Override
1226        public boolean equals(Object o) {
1227            if (o instanceof GrantUri) {
1228                GrantUri other = (GrantUri) o;
1229                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1230                        && prefix == other.prefix;
1231            }
1232            return false;
1233        }
1234
1235        @Override
1236        public String toString() {
1237            String result = uri.toString() + " [user " + sourceUserId + "]";
1238            if (prefix) result += " [prefix]";
1239            return result;
1240        }
1241
1242        public String toSafeString() {
1243            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1244            if (prefix) result += " [prefix]";
1245            return result;
1246        }
1247
1248        public void writeToProto(ProtoOutputStream proto, long fieldId) {
1249            long token = proto.start(fieldId);
1250            proto.write(GrantUriProto.URI, uri.toString());
1251            proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
1252            proto.end(token);
1253        }
1254
1255        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1256            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1257                    ContentProvider.getUriWithoutUserId(uri), false);
1258        }
1259    }
1260
1261    CoreSettingsObserver mCoreSettingsObserver;
1262
1263    FontScaleSettingObserver mFontScaleSettingObserver;
1264
1265    private final class FontScaleSettingObserver extends ContentObserver {
1266        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1267
1268        public FontScaleSettingObserver() {
1269            super(mHandler);
1270            ContentResolver resolver = mContext.getContentResolver();
1271            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1272        }
1273
1274        @Override
1275        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1276            if (mFontScaleUri.equals(uri)) {
1277                updateFontScaleIfNeeded(userId);
1278            }
1279        }
1280    }
1281
1282    /**
1283     * Thread-local storage used to carry caller permissions over through
1284     * indirect content-provider access.
1285     */
1286    private class Identity {
1287        public final IBinder token;
1288        public final int pid;
1289        public final int uid;
1290
1291        Identity(IBinder _token, int _pid, int _uid) {
1292            token = _token;
1293            pid = _pid;
1294            uid = _uid;
1295        }
1296    }
1297
1298    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1299
1300    /**
1301     * All information we have collected about the runtime performance of
1302     * any user id that can impact battery performance.
1303     */
1304    final BatteryStatsService mBatteryStatsService;
1305
1306    /**
1307     * Information about component usage
1308     */
1309    UsageStatsManagerInternal mUsageStatsService;
1310
1311    /**
1312     * Access to DeviceIdleController service.
1313     */
1314    DeviceIdleController.LocalService mLocalDeviceIdleController;
1315
1316    /**
1317     * Set of app ids that are whitelisted for device idle and thus background check.
1318     */
1319    int[] mDeviceIdleWhitelist = new int[0];
1320
1321    /**
1322     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1323     */
1324    int[] mDeviceIdleTempWhitelist = new int[0];
1325
1326    static final class PendingTempWhitelist {
1327        final int targetUid;
1328        final long duration;
1329        final String tag;
1330
1331        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1332            targetUid = _targetUid;
1333            duration = _duration;
1334            tag = _tag;
1335        }
1336
1337        void writeToProto(ProtoOutputStream proto, long fieldId) {
1338            final long token = proto.start(fieldId);
1339            proto.write(ProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
1340            proto.write(ProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
1341            proto.write(ProcessesProto.PendingTempWhitelist.TAG, tag);
1342            proto.end(token);
1343        }
1344    }
1345
1346    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1347
1348    /**
1349     * Information about and control over application operations
1350     */
1351    final AppOpsService mAppOpsService;
1352
1353    /** Current sequencing integer of the configuration, for skipping old configurations. */
1354    private int mConfigurationSeq;
1355
1356    /**
1357     * Temp object used when global and/or display override configuration is updated. It is also
1358     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1359     * anyone...
1360     */
1361    private Configuration mTempConfig = new Configuration();
1362
1363    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1364            new UpdateConfigurationResult();
1365    private static final class UpdateConfigurationResult {
1366        // Configuration changes that were updated.
1367        int changes;
1368        // If the activity was relaunched to match the new configuration.
1369        boolean activityRelaunched;
1370
1371        void reset() {
1372            changes = 0;
1373            activityRelaunched = false;
1374        }
1375    }
1376
1377    boolean mSuppressResizeConfigChanges;
1378
1379    /**
1380     * Hardware-reported OpenGLES version.
1381     */
1382    final int GL_ES_VERSION;
1383
1384    /**
1385     * List of initialization arguments to pass to all processes when binding applications to them.
1386     * For example, references to the commonly used services.
1387     */
1388    HashMap<String, IBinder> mAppBindArgs;
1389    HashMap<String, IBinder> mIsolatedAppBindArgs;
1390
1391    /**
1392     * Temporary to avoid allocations.  Protected by main lock.
1393     */
1394    final StringBuilder mStringBuilder = new StringBuilder(256);
1395
1396    /**
1397     * Used to control how we initialize the service.
1398     */
1399    ComponentName mTopComponent;
1400    String mTopAction = Intent.ACTION_MAIN;
1401    String mTopData;
1402
1403    volatile boolean mProcessesReady = false;
1404    volatile boolean mSystemReady = false;
1405    volatile boolean mOnBattery = false;
1406    volatile int mFactoryTest;
1407
1408    @GuardedBy("this") boolean mBooting = false;
1409    @GuardedBy("this") boolean mCallFinishBooting = false;
1410    @GuardedBy("this") boolean mBootAnimationComplete = false;
1411    @GuardedBy("this") boolean mLaunchWarningShown = false;
1412    private @GuardedBy("this") boolean mCheckedForSetup = false;
1413
1414    final Context mContext;
1415
1416    /**
1417     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1418     * change at runtime. Use mContext for non-UI purposes.
1419     */
1420    final Context mUiContext;
1421
1422    /**
1423     * The time at which we will allow normal application switches again,
1424     * after a call to {@link #stopAppSwitches()}.
1425     */
1426    long mAppSwitchesAllowedTime;
1427
1428    /**
1429     * This is set to true after the first switch after mAppSwitchesAllowedTime
1430     * is set; any switches after that will clear the time.
1431     */
1432    boolean mDidAppSwitch;
1433
1434    /**
1435     * Last time (in uptime) at which we checked for power usage.
1436     */
1437    long mLastPowerCheckUptime;
1438
1439    /**
1440     * Set while we are wanting to sleep, to prevent any
1441     * activities from being started/resumed.
1442     *
1443     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1444     *
1445     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1446     * while in the sleep state until there is a pending transition out of sleep, in which case
1447     * mSleeping is set to false, and remains false while awake.
1448     *
1449     * Whether mSleeping can quickly toggled between true/false without the device actually
1450     * display changing states is undefined.
1451     */
1452    private boolean mSleeping = false;
1453
1454    /**
1455     * The process state used for processes that are running the top activities.
1456     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1457     */
1458    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1459
1460    /**
1461     * Set while we are running a voice interaction.  This overrides
1462     * sleeping while it is active.
1463     */
1464    IVoiceInteractionSession mRunningVoice;
1465
1466    /**
1467     * For some direct access we need to power manager.
1468     */
1469    PowerManagerInternal mLocalPowerManager;
1470
1471    /**
1472     * We want to hold a wake lock while running a voice interaction session, since
1473     * this may happen with the screen off and we need to keep the CPU running to
1474     * be able to continue to interact with the user.
1475     */
1476    PowerManager.WakeLock mVoiceWakeLock;
1477
1478    /**
1479     * State of external calls telling us if the device is awake or asleep.
1480     */
1481    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1482
1483    /**
1484     * Set if we are shutting down the system, similar to sleeping.
1485     */
1486    boolean mShuttingDown = false;
1487
1488    /**
1489     * Current sequence id for oom_adj computation traversal.
1490     */
1491    int mAdjSeq = 0;
1492
1493    /**
1494     * Current sequence id for process LRU updating.
1495     */
1496    int mLruSeq = 0;
1497
1498    /**
1499     * Keep track of the non-cached/empty process we last found, to help
1500     * determine how to distribute cached/empty processes next time.
1501     */
1502    int mNumNonCachedProcs = 0;
1503
1504    /**
1505     * Keep track of the number of cached hidden procs, to balance oom adj
1506     * distribution between those and empty procs.
1507     */
1508    int mNumCachedHiddenProcs = 0;
1509
1510    /**
1511     * Keep track of the number of service processes we last found, to
1512     * determine on the next iteration which should be B services.
1513     */
1514    int mNumServiceProcs = 0;
1515    int mNewNumAServiceProcs = 0;
1516    int mNewNumServiceProcs = 0;
1517
1518    /**
1519     * Allow the current computed overall memory level of the system to go down?
1520     * This is set to false when we are killing processes for reasons other than
1521     * memory management, so that the now smaller process list will not be taken as
1522     * an indication that memory is tighter.
1523     */
1524    boolean mAllowLowerMemLevel = false;
1525
1526    /**
1527     * The last computed memory level, for holding when we are in a state that
1528     * processes are going away for other reasons.
1529     */
1530    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1531
1532    /**
1533     * The last total number of process we have, to determine if changes actually look
1534     * like a shrinking number of process due to lower RAM.
1535     */
1536    int mLastNumProcesses;
1537
1538    /**
1539     * The uptime of the last time we performed idle maintenance.
1540     */
1541    long mLastIdleTime = SystemClock.uptimeMillis();
1542
1543    /**
1544     * Total time spent with RAM that has been added in the past since the last idle time.
1545     */
1546    long mLowRamTimeSinceLastIdle = 0;
1547
1548    /**
1549     * If RAM is currently low, when that horrible situation started.
1550     */
1551    long mLowRamStartTime = 0;
1552
1553    /**
1554     * For reporting to battery stats the current top application.
1555     */
1556    private String mCurResumedPackage = null;
1557    private int mCurResumedUid = -1;
1558
1559    /**
1560     * For reporting to battery stats the apps currently running foreground
1561     * service.  The ProcessMap is package/uid tuples; each of these contain
1562     * an array of the currently foreground processes.
1563     */
1564    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1565            = new ProcessMap<ArrayList<ProcessRecord>>();
1566
1567    /**
1568     * Set if the systemServer made a call to enterSafeMode.
1569     */
1570    boolean mSafeMode;
1571
1572    /**
1573     * If true, we are running under a test environment so will sample PSS from processes
1574     * much more rapidly to try to collect better data when the tests are rapidly
1575     * running through apps.
1576     */
1577    boolean mTestPssMode = false;
1578
1579    String mDebugApp = null;
1580    boolean mWaitForDebugger = false;
1581    boolean mDebugTransient = false;
1582    String mOrigDebugApp = null;
1583    boolean mOrigWaitForDebugger = false;
1584    boolean mAlwaysFinishActivities = false;
1585    boolean mForceResizableActivities;
1586    /**
1587     * Flag that indicates if multi-window is enabled.
1588     *
1589     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1590     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1591     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1592     * At least one of the forms of multi-window must be enabled in order for this flag to be
1593     * initialized to 'true'.
1594     *
1595     * @see #mSupportsSplitScreenMultiWindow
1596     * @see #mSupportsFreeformWindowManagement
1597     * @see #mSupportsPictureInPicture
1598     * @see #mSupportsMultiDisplay
1599     */
1600    boolean mSupportsMultiWindow;
1601    boolean mSupportsSplitScreenMultiWindow;
1602    boolean mSupportsFreeformWindowManagement;
1603    boolean mSupportsPictureInPicture;
1604    boolean mSupportsMultiDisplay;
1605    boolean mSupportsLeanbackOnly;
1606    IActivityController mController = null;
1607    boolean mControllerIsAMonkey = false;
1608    String mProfileApp = null;
1609    ProcessRecord mProfileProc = null;
1610    ProfilerInfo mProfilerInfo = null;
1611    int mProfileType = 0;
1612    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1613    String mMemWatchDumpProcName;
1614    String mMemWatchDumpFile;
1615    int mMemWatchDumpPid;
1616    int mMemWatchDumpUid;
1617    String mTrackAllocationApp = null;
1618    String mNativeDebuggingApp = null;
1619
1620    final long[] mTmpLong = new long[2];
1621
1622    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1623
1624    /**
1625     * A global counter for generating sequence numbers.
1626     * This value will be used when incrementing sequence numbers in individual uidRecords.
1627     *
1628     * Having a global counter ensures that seq numbers are monotonically increasing for a
1629     * particular uid even when the uidRecord is re-created.
1630     */
1631    @GuardedBy("this")
1632    @VisibleForTesting
1633    long mProcStateSeqCounter = 0;
1634
1635    /**
1636     * A global counter for generating sequence numbers to uniquely identify pending process starts.
1637     */
1638    @GuardedBy("this")
1639    private long mProcStartSeqCounter = 0;
1640
1641    /**
1642     * Contains {@link ProcessRecord} objects for pending process starts.
1643     *
1644     * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1645     */
1646    @GuardedBy("this")
1647    private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1648
1649    private final Injector mInjector;
1650
1651    static final class ProcessChangeItem {
1652        static final int CHANGE_ACTIVITIES = 1<<0;
1653        int changes;
1654        int uid;
1655        int pid;
1656        int processState;
1657        boolean foregroundActivities;
1658    }
1659
1660    static final class UidObserverRegistration {
1661        final int uid;
1662        final String pkg;
1663        final int which;
1664        final int cutpoint;
1665
1666        final SparseIntArray lastProcStates;
1667
1668        // Please keep the enum lists in sync
1669        private static int[] ORIG_ENUMS = new int[]{
1670                ActivityManager.UID_OBSERVER_IDLE,
1671                ActivityManager.UID_OBSERVER_ACTIVE,
1672                ActivityManager.UID_OBSERVER_GONE,
1673                ActivityManager.UID_OBSERVER_PROCSTATE,
1674        };
1675        private static int[] PROTO_ENUMS = new int[]{
1676                ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
1677                ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
1678                ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
1679                ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
1680        };
1681
1682        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1683            uid = _uid;
1684            pkg = _pkg;
1685            which = _which;
1686            cutpoint = _cutpoint;
1687            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1688                lastProcStates = new SparseIntArray();
1689            } else {
1690                lastProcStates = null;
1691            }
1692        }
1693
1694        void writeToProto(ProtoOutputStream proto, long fieldId) {
1695            final long token = proto.start(fieldId);
1696            proto.write(UidObserverRegistrationProto.UID, uid);
1697            proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
1698            ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
1699                    which, ORIG_ENUMS, PROTO_ENUMS);
1700            proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
1701            if (lastProcStates != null) {
1702                final int NI = lastProcStates.size();
1703                for (int i=0; i<NI; i++) {
1704                    final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
1705                    proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
1706                    proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
1707                    proto.end(pToken);
1708                }
1709            }
1710            proto.end(token);
1711        }
1712    }
1713
1714    final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1715
1716    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1717    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1718
1719    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1720    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1721
1722    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1723    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1724
1725    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1726    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1727
1728    OomAdjObserver mCurOomAdjObserver;
1729    int mCurOomAdjUid;
1730
1731    interface OomAdjObserver {
1732        void onOomAdjMessage(String msg);
1733    }
1734
1735    /**
1736     * Runtime CPU use collection thread.  This object's lock is used to
1737     * perform synchronization with the thread (notifying it to run).
1738     */
1739    final Thread mProcessCpuThread;
1740
1741    /**
1742     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1743     * Must acquire this object's lock when accessing it.
1744     * NOTE: this lock will be held while doing long operations (trawling
1745     * through all processes in /proc), so it should never be acquired by
1746     * any critical paths such as when holding the main activity manager lock.
1747     */
1748    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1749            MONITOR_THREAD_CPU_USAGE);
1750    final AtomicLong mLastCpuTime = new AtomicLong(0);
1751    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1752    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1753
1754    long mLastWriteTime = 0;
1755
1756    /**
1757     * Used to retain an update lock when the foreground activity is in
1758     * immersive mode.
1759     */
1760    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1761
1762    /**
1763     * Set to true after the system has finished booting.
1764     */
1765    boolean mBooted = false;
1766
1767    WindowManagerService mWindowManager;
1768    final ActivityThread mSystemThread;
1769
1770    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1771        final ProcessRecord mApp;
1772        final int mPid;
1773        final IApplicationThread mAppThread;
1774
1775        AppDeathRecipient(ProcessRecord app, int pid,
1776                IApplicationThread thread) {
1777            if (DEBUG_ALL) Slog.v(
1778                TAG, "New death recipient " + this
1779                + " for thread " + thread.asBinder());
1780            mApp = app;
1781            mPid = pid;
1782            mAppThread = thread;
1783        }
1784
1785        @Override
1786        public void binderDied() {
1787            if (DEBUG_ALL) Slog.v(
1788                TAG, "Death received in " + this
1789                + " for thread " + mAppThread.asBinder());
1790            synchronized(ActivityManagerService.this) {
1791                appDiedLocked(mApp, mPid, mAppThread, true);
1792            }
1793        }
1794    }
1795
1796    static final int SHOW_ERROR_UI_MSG = 1;
1797    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1798    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1799    static final int UPDATE_CONFIGURATION_MSG = 4;
1800    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1801    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1802    static final int SERVICE_TIMEOUT_MSG = 12;
1803    static final int UPDATE_TIME_ZONE = 13;
1804    static final int SHOW_UID_ERROR_UI_MSG = 14;
1805    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1806    static final int PROC_START_TIMEOUT_MSG = 20;
1807    static final int KILL_APPLICATION_MSG = 22;
1808    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1809    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1810    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1811    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1812    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1813    static final int CLEAR_DNS_CACHE_MSG = 28;
1814    static final int UPDATE_HTTP_PROXY_MSG = 29;
1815    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1816    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1817    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1818    static final int REPORT_MEM_USAGE_MSG = 33;
1819    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1820    static final int PERSIST_URI_GRANTS_MSG = 38;
1821    static final int REQUEST_ALL_PSS_MSG = 39;
1822    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1823    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1824    static final int FINISH_BOOTING_MSG = 45;
1825    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1826    static final int DISMISS_DIALOG_UI_MSG = 48;
1827    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1828    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1829    static final int DELETE_DUMPHEAP_MSG = 51;
1830    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1831    static final int REPORT_TIME_TRACKER_MSG = 54;
1832    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1833    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1834    static final int IDLE_UIDS_MSG = 58;
1835    static final int LOG_STACK_STATE = 60;
1836    static final int VR_MODE_CHANGE_MSG = 61;
1837    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1838    static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
1839    static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
1840    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1841    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1842    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1843    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1844    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1845
1846    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1847    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1848    static final int FIRST_COMPAT_MODE_MSG = 300;
1849    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1850
1851    static ServiceThread sKillThread = null;
1852    static KillHandler sKillHandler = null;
1853
1854    CompatModeDialog mCompatModeDialog;
1855    long mLastMemUsageReportTime = 0;
1856
1857    /**
1858     * Flag whether the current user is a "monkey", i.e. whether
1859     * the UI is driven by a UI automation tool.
1860     */
1861    private boolean mUserIsMonkey;
1862
1863    /** The dimensions of the thumbnails in the Recents UI. */
1864    int mThumbnailWidth;
1865    int mThumbnailHeight;
1866    float mFullscreenThumbnailScale;
1867
1868    final ServiceThread mHandlerThread;
1869    final MainHandler mHandler;
1870    final Handler mUiHandler;
1871    final ServiceThread mProcStartHandlerThread;
1872    final Handler mProcStartHandler;
1873
1874    final ActivityManagerConstants mConstants;
1875
1876    PackageManagerInternal mPackageManagerInt;
1877
1878    // VoiceInteraction session ID that changes for each new request except when
1879    // being called for multiwindow assist in a single session.
1880    private int mViSessionId = 1000;
1881
1882    final boolean mPermissionReviewRequired;
1883
1884    /**
1885     * Whether to force background check on all apps (for battery saver) or not.
1886     */
1887    boolean mForceBackgroundCheck;
1888
1889    private static String sTheRealBuildSerial = Build.UNKNOWN;
1890
1891    /**
1892     * Current global configuration information. Contains general settings for the entire system,
1893     * also corresponds to the merged configuration of the default display.
1894     */
1895    Configuration getGlobalConfiguration() {
1896        return mStackSupervisor.getConfiguration();
1897    }
1898
1899    final class KillHandler extends Handler {
1900        static final int KILL_PROCESS_GROUP_MSG = 4000;
1901
1902        public KillHandler(Looper looper) {
1903            super(looper, null, true);
1904        }
1905
1906        @Override
1907        public void handleMessage(Message msg) {
1908            switch (msg.what) {
1909                case KILL_PROCESS_GROUP_MSG:
1910                {
1911                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1912                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1913                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1914                }
1915                break;
1916
1917                default:
1918                    super.handleMessage(msg);
1919            }
1920        }
1921    }
1922
1923    final class UiHandler extends Handler {
1924        public UiHandler() {
1925            super(com.android.server.UiThread.get().getLooper(), null, true);
1926        }
1927
1928        @Override
1929        public void handleMessage(Message msg) {
1930            switch (msg.what) {
1931            case SHOW_ERROR_UI_MSG: {
1932                mAppErrors.handleShowAppErrorUi(msg);
1933                ensureBootCompleted();
1934            } break;
1935            case SHOW_NOT_RESPONDING_UI_MSG: {
1936                mAppErrors.handleShowAnrUi(msg);
1937                ensureBootCompleted();
1938            } break;
1939            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1940                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1941                synchronized (ActivityManagerService.this) {
1942                    ProcessRecord proc = (ProcessRecord) data.get("app");
1943                    if (proc == null) {
1944                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1945                        break;
1946                    }
1947                    if (proc.crashDialog != null) {
1948                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1949                        return;
1950                    }
1951                    AppErrorResult res = (AppErrorResult) data.get("result");
1952                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1953                        Dialog d = new StrictModeViolationDialog(mUiContext,
1954                                ActivityManagerService.this, res, proc);
1955                        d.show();
1956                        proc.crashDialog = d;
1957                    } else {
1958                        // The device is asleep, so just pretend that the user
1959                        // saw a crash dialog and hit "force quit".
1960                        res.set(0);
1961                    }
1962                }
1963                ensureBootCompleted();
1964            } break;
1965            case SHOW_FACTORY_ERROR_UI_MSG: {
1966                Dialog d = new FactoryErrorDialog(
1967                        mUiContext, msg.getData().getCharSequence("msg"));
1968                d.show();
1969                ensureBootCompleted();
1970            } break;
1971            case WAIT_FOR_DEBUGGER_UI_MSG: {
1972                synchronized (ActivityManagerService.this) {
1973                    ProcessRecord app = (ProcessRecord)msg.obj;
1974                    if (msg.arg1 != 0) {
1975                        if (!app.waitedForDebugger) {
1976                            Dialog d = new AppWaitingForDebuggerDialog(
1977                                    ActivityManagerService.this,
1978                                    mUiContext, app);
1979                            app.waitDialog = d;
1980                            app.waitedForDebugger = true;
1981                            d.show();
1982                        }
1983                    } else {
1984                        if (app.waitDialog != null) {
1985                            app.waitDialog.dismiss();
1986                            app.waitDialog = null;
1987                        }
1988                    }
1989                }
1990            } break;
1991            case SHOW_UID_ERROR_UI_MSG: {
1992                if (mShowDialogs) {
1993                    AlertDialog d = new BaseErrorDialog(mUiContext);
1994                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1995                    d.setCancelable(false);
1996                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1997                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1998                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1999                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2000                    d.show();
2001                }
2002            } break;
2003            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
2004                if (mShowDialogs) {
2005                    AlertDialog d = new BaseErrorDialog(mUiContext);
2006                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2007                    d.setCancelable(false);
2008                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2009                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
2010                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2011                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2012                    d.show();
2013                }
2014            } break;
2015            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
2016                synchronized (ActivityManagerService.this) {
2017                    ActivityRecord ar = (ActivityRecord) msg.obj;
2018                    if (mCompatModeDialog != null) {
2019                        if (mCompatModeDialog.mAppInfo.packageName.equals(
2020                                ar.info.applicationInfo.packageName)) {
2021                            return;
2022                        }
2023                        mCompatModeDialog.dismiss();
2024                        mCompatModeDialog = null;
2025                    }
2026                    if (ar != null && false) {
2027                        if (mCompatModePackages.getPackageAskCompatModeLocked(
2028                                ar.packageName)) {
2029                            int mode = mCompatModePackages.computeCompatModeLocked(
2030                                    ar.info.applicationInfo);
2031                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
2032                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
2033                                mCompatModeDialog = new CompatModeDialog(
2034                                        ActivityManagerService.this, mUiContext,
2035                                        ar.info.applicationInfo);
2036                                mCompatModeDialog.show();
2037                            }
2038                        }
2039                    }
2040                }
2041                break;
2042            }
2043            case DISMISS_DIALOG_UI_MSG: {
2044                final Dialog d = (Dialog) msg.obj;
2045                d.dismiss();
2046                break;
2047            }
2048            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
2049                dispatchProcessesChanged();
2050                break;
2051            }
2052            case DISPATCH_PROCESS_DIED_UI_MSG: {
2053                final int pid = msg.arg1;
2054                final int uid = msg.arg2;
2055                dispatchProcessDied(pid, uid);
2056                break;
2057            }
2058            case DISPATCH_UIDS_CHANGED_UI_MSG: {
2059                dispatchUidsChanged();
2060            } break;
2061            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
2062                dispatchOomAdjObserver((String)msg.obj);
2063            } break;
2064            case PUSH_TEMP_WHITELIST_UI_MSG: {
2065                pushTempWhitelist();
2066            } break;
2067            }
2068        }
2069    }
2070
2071    final class MainHandler extends Handler {
2072        public MainHandler(Looper looper) {
2073            super(looper, null, true);
2074        }
2075
2076        @Override
2077        public void handleMessage(Message msg) {
2078            switch (msg.what) {
2079            case UPDATE_CONFIGURATION_MSG: {
2080                final ContentResolver resolver = mContext.getContentResolver();
2081                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
2082                        msg.arg1);
2083            } break;
2084            case GC_BACKGROUND_PROCESSES_MSG: {
2085                synchronized (ActivityManagerService.this) {
2086                    performAppGcsIfAppropriateLocked();
2087                }
2088            } break;
2089            case SERVICE_TIMEOUT_MSG: {
2090                mServices.serviceTimeout((ProcessRecord)msg.obj);
2091            } break;
2092            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
2093                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
2094            } break;
2095            case SERVICE_FOREGROUND_CRASH_MSG: {
2096                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
2097            } break;
2098            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
2099                RemoteCallbackList<IResultReceiver> callbacks
2100                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
2101                int N = callbacks.beginBroadcast();
2102                for (int i = 0; i < N; i++) {
2103                    try {
2104                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2105                    } catch (RemoteException e) {
2106                    }
2107                }
2108                callbacks.finishBroadcast();
2109            } break;
2110            case UPDATE_TIME_ZONE: {
2111                synchronized (ActivityManagerService.this) {
2112                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2113                        ProcessRecord r = mLruProcesses.get(i);
2114                        if (r.thread != null) {
2115                            try {
2116                                r.thread.updateTimeZone();
2117                            } catch (RemoteException ex) {
2118                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2119                            }
2120                        }
2121                    }
2122                }
2123            } break;
2124            case CLEAR_DNS_CACHE_MSG: {
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.clearDnsCache();
2131                            } catch (RemoteException ex) {
2132                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2133                            }
2134                        }
2135                    }
2136                }
2137            } break;
2138            case UPDATE_HTTP_PROXY_MSG: {
2139                ProxyInfo proxy = (ProxyInfo)msg.obj;
2140                String host = "";
2141                String port = "";
2142                String exclList = "";
2143                Uri pacFileUrl = Uri.EMPTY;
2144                if (proxy != null) {
2145                    host = proxy.getHost();
2146                    port = Integer.toString(proxy.getPort());
2147                    exclList = proxy.getExclusionListAsString();
2148                    pacFileUrl = proxy.getPacFileUrl();
2149                }
2150                synchronized (ActivityManagerService.this) {
2151                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2152                        ProcessRecord r = mLruProcesses.get(i);
2153                        // Don't dispatch to isolated processes as they can't access
2154                        // ConnectivityManager and don't have network privileges anyway.
2155                        if (r.thread != null && !r.isolated) {
2156                            try {
2157                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2158                            } catch (RemoteException ex) {
2159                                Slog.w(TAG, "Failed to update http proxy for: " +
2160                                        r.info.processName);
2161                            }
2162                        }
2163                    }
2164                }
2165            } break;
2166            case PROC_START_TIMEOUT_MSG: {
2167                ProcessRecord app = (ProcessRecord)msg.obj;
2168                synchronized (ActivityManagerService.this) {
2169                    processStartTimedOutLocked(app);
2170                }
2171            } break;
2172            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2173                ProcessRecord app = (ProcessRecord)msg.obj;
2174                synchronized (ActivityManagerService.this) {
2175                    processContentProviderPublishTimedOutLocked(app);
2176                }
2177            } break;
2178            case KILL_APPLICATION_MSG: {
2179                synchronized (ActivityManagerService.this) {
2180                    final int appId = msg.arg1;
2181                    final int userId = msg.arg2;
2182                    Bundle bundle = (Bundle)msg.obj;
2183                    String pkg = bundle.getString("pkg");
2184                    String reason = bundle.getString("reason");
2185                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2186                            false, userId, reason);
2187                }
2188            } break;
2189            case FINALIZE_PENDING_INTENT_MSG: {
2190                ((PendingIntentRecord)msg.obj).completeFinalize();
2191            } break;
2192            case POST_HEAVY_NOTIFICATION_MSG: {
2193                INotificationManager inm = NotificationManager.getService();
2194                if (inm == null) {
2195                    return;
2196                }
2197
2198                ActivityRecord root = (ActivityRecord)msg.obj;
2199                ProcessRecord process = root.app;
2200                if (process == null) {
2201                    return;
2202                }
2203
2204                try {
2205                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2206                    String text = mContext.getString(R.string.heavy_weight_notification,
2207                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2208                    Notification notification =
2209                            new Notification.Builder(context,
2210                                    SystemNotificationChannels.HEAVY_WEIGHT_APP)
2211                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2212                            .setWhen(0)
2213                            .setOngoing(true)
2214                            .setTicker(text)
2215                            .setColor(mContext.getColor(
2216                                    com.android.internal.R.color.system_notification_accent_color))
2217                            .setContentTitle(text)
2218                            .setContentText(
2219                                    mContext.getText(R.string.heavy_weight_notification_detail))
2220                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2221                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2222                                    new UserHandle(root.userId)))
2223                            .build();
2224                    try {
2225                        inm.enqueueNotificationWithTag("android", "android", null,
2226                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2227                                notification, root.userId);
2228                    } catch (RuntimeException e) {
2229                        Slog.w(ActivityManagerService.TAG,
2230                                "Error showing notification for heavy-weight app", e);
2231                    } catch (RemoteException e) {
2232                    }
2233                } catch (NameNotFoundException e) {
2234                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2235                }
2236            } break;
2237            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2238                INotificationManager inm = NotificationManager.getService();
2239                if (inm == null) {
2240                    return;
2241                }
2242                try {
2243                    inm.cancelNotificationWithTag("android", null,
2244                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2245                } catch (RuntimeException e) {
2246                    Slog.w(ActivityManagerService.TAG,
2247                            "Error canceling notification for service", e);
2248                } catch (RemoteException e) {
2249                }
2250            } break;
2251            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2252                synchronized (ActivityManagerService.this) {
2253                    checkExcessivePowerUsageLocked();
2254                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2255                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2256                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2257                }
2258            } break;
2259            case REPORT_MEM_USAGE_MSG: {
2260                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2261                Thread thread = new Thread() {
2262                    @Override public void run() {
2263                        reportMemUsage(memInfos);
2264                    }
2265                };
2266                thread.start();
2267                break;
2268            }
2269            case IMMERSIVE_MODE_LOCK_MSG: {
2270                final boolean nextState = (msg.arg1 != 0);
2271                if (mUpdateLock.isHeld() != nextState) {
2272                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2273                            "Applying new update lock state '" + nextState
2274                            + "' for " + (ActivityRecord)msg.obj);
2275                    if (nextState) {
2276                        mUpdateLock.acquire();
2277                    } else {
2278                        mUpdateLock.release();
2279                    }
2280                }
2281                break;
2282            }
2283            case PERSIST_URI_GRANTS_MSG: {
2284                writeGrantedUriPermissions();
2285                break;
2286            }
2287            case REQUEST_ALL_PSS_MSG: {
2288                synchronized (ActivityManagerService.this) {
2289                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2290                }
2291                break;
2292            }
2293            case UPDATE_TIME_PREFERENCE_MSG: {
2294                // The user's time format preference might have changed.
2295                // For convenience we re-use the Intent extra values.
2296                synchronized (ActivityManagerService.this) {
2297                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2298                        ProcessRecord r = mLruProcesses.get(i);
2299                        if (r.thread != null) {
2300                            try {
2301                                r.thread.updateTimePrefs(msg.arg1);
2302                            } catch (RemoteException ex) {
2303                                Slog.w(TAG, "Failed to update preferences for: "
2304                                        + r.info.processName);
2305                            }
2306                        }
2307                    }
2308                }
2309                break;
2310            }
2311            case ENTER_ANIMATION_COMPLETE_MSG: {
2312                synchronized (ActivityManagerService.this) {
2313                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2314                    if (r != null && r.app != null && r.app.thread != null) {
2315                        try {
2316                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2317                        } catch (RemoteException e) {
2318                        }
2319                    }
2320                }
2321                break;
2322            }
2323            case FINISH_BOOTING_MSG: {
2324                if (msg.arg1 != 0) {
2325                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2326                    finishBooting();
2327                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2328                }
2329                if (msg.arg2 != 0) {
2330                    enableScreenAfterBoot();
2331                }
2332                break;
2333            }
2334            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2335                try {
2336                    Locale l = (Locale) msg.obj;
2337                    IBinder service = ServiceManager.getService("mount");
2338                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2339                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2340                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2341                } catch (RemoteException e) {
2342                    Log.e(TAG, "Error storing locale for decryption UI", e);
2343                }
2344                break;
2345            }
2346            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2347                final int uid = msg.arg1;
2348                final byte[] firstPacket = (byte[]) msg.obj;
2349
2350                synchronized (mPidsSelfLocked) {
2351                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2352                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2353                        if (p.uid == uid) {
2354                            try {
2355                                p.thread.notifyCleartextNetwork(firstPacket);
2356                            } catch (RemoteException ignored) {
2357                            }
2358                        }
2359                    }
2360                }
2361                break;
2362            }
2363            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2364                final String procName;
2365                final int uid;
2366                final long memLimit;
2367                final String reportPackage;
2368                synchronized (ActivityManagerService.this) {
2369                    procName = mMemWatchDumpProcName;
2370                    uid = mMemWatchDumpUid;
2371                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2372                    if (val == null) {
2373                        val = mMemWatchProcesses.get(procName, 0);
2374                    }
2375                    if (val != null) {
2376                        memLimit = val.first;
2377                        reportPackage = val.second;
2378                    } else {
2379                        memLimit = 0;
2380                        reportPackage = null;
2381                    }
2382                }
2383                if (procName == null) {
2384                    return;
2385                }
2386
2387                if (DEBUG_PSS) Slog.d(TAG_PSS,
2388                        "Showing dump heap notification from " + procName + "/" + uid);
2389
2390                INotificationManager inm = NotificationManager.getService();
2391                if (inm == null) {
2392                    return;
2393                }
2394
2395                String text = mContext.getString(R.string.dump_heap_notification, procName);
2396
2397
2398                Intent deleteIntent = new Intent();
2399                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2400                Intent intent = new Intent();
2401                intent.setClassName("android", DumpHeapActivity.class.getName());
2402                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2403                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2404                if (reportPackage != null) {
2405                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2406                }
2407                int userId = UserHandle.getUserId(uid);
2408                Notification notification =
2409                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2410                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2411                        .setWhen(0)
2412                        .setOngoing(true)
2413                        .setAutoCancel(true)
2414                        .setTicker(text)
2415                        .setColor(mContext.getColor(
2416                                com.android.internal.R.color.system_notification_accent_color))
2417                        .setContentTitle(text)
2418                        .setContentText(
2419                                mContext.getText(R.string.dump_heap_notification_detail))
2420                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2421                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2422                                new UserHandle(userId)))
2423                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2424                                deleteIntent, 0, UserHandle.SYSTEM))
2425                        .build();
2426
2427                try {
2428                    inm.enqueueNotificationWithTag("android", "android", null,
2429                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2430                            notification, userId);
2431                } catch (RuntimeException e) {
2432                    Slog.w(ActivityManagerService.TAG,
2433                            "Error showing notification for dump heap", e);
2434                } catch (RemoteException e) {
2435                }
2436            } break;
2437            case DELETE_DUMPHEAP_MSG: {
2438                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2439                        null, DumpHeapActivity.JAVA_URI,
2440                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2441                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2442                        UserHandle.myUserId());
2443                synchronized (ActivityManagerService.this) {
2444                    mMemWatchDumpFile = null;
2445                    mMemWatchDumpProcName = null;
2446                    mMemWatchDumpPid = -1;
2447                    mMemWatchDumpUid = -1;
2448                }
2449            } break;
2450            case REPORT_TIME_TRACKER_MSG: {
2451                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2452                tracker.deliverResult(mContext);
2453            } break;
2454            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2455                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2456                try {
2457                    connection.shutdown();
2458                } catch (RemoteException e) {
2459                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2460                }
2461                // Only a UiAutomation can set this flag and now that
2462                // it is finished we make sure it is reset to its default.
2463                mUserIsMonkey = false;
2464            } break;
2465            case IDLE_UIDS_MSG: {
2466                idleUids();
2467            } break;
2468            case VR_MODE_CHANGE_MSG: {
2469                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2470                    return;
2471                }
2472                synchronized (ActivityManagerService.this) {
2473                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2474                    mWindowManager.disableNonVrUi(disableNonVrUi);
2475                    if (disableNonVrUi) {
2476                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2477                        // then remove the pinned stack.
2478                        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2479                    }
2480                }
2481            } break;
2482            case DISPATCH_SCREEN_AWAKE_MSG: {
2483                final boolean isAwake = msg.arg1 != 0;
2484                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2485                    mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2486                }
2487            } break;
2488            case DISPATCH_SCREEN_KEYGUARD_MSG: {
2489                final boolean isShowing = msg.arg1 != 0;
2490                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2491                    mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2492                }
2493            } break;
2494            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2495                synchronized (ActivityManagerService.this) {
2496                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2497                        ProcessRecord r = mLruProcesses.get(i);
2498                        if (r.thread != null) {
2499                            try {
2500                                r.thread.handleTrustStorageUpdate();
2501                            } catch (RemoteException ex) {
2502                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2503                                        r.info.processName);
2504                            }
2505                        }
2506                    }
2507                }
2508            } break;
2509            }
2510        }
2511    };
2512
2513    static final int COLLECT_PSS_BG_MSG = 1;
2514
2515    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2516        @Override
2517        public void handleMessage(Message msg) {
2518            switch (msg.what) {
2519            case COLLECT_PSS_BG_MSG: {
2520                long start = SystemClock.uptimeMillis();
2521                MemInfoReader memInfo = null;
2522                synchronized (ActivityManagerService.this) {
2523                    if (mFullPssPending) {
2524                        mFullPssPending = false;
2525                        memInfo = new MemInfoReader();
2526                    }
2527                }
2528                if (memInfo != null) {
2529                    updateCpuStatsNow();
2530                    long nativeTotalPss = 0;
2531                    final List<ProcessCpuTracker.Stats> stats;
2532                    synchronized (mProcessCpuTracker) {
2533                        stats = mProcessCpuTracker.getStats( (st)-> {
2534                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2535                        });
2536                    }
2537                    final int N = stats.size();
2538                    for (int j = 0; j < N; j++) {
2539                        synchronized (mPidsSelfLocked) {
2540                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2541                                // This is one of our own processes; skip it.
2542                                continue;
2543                            }
2544                        }
2545                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2546                    }
2547                    memInfo.readMemInfo();
2548                    synchronized (ActivityManagerService.this) {
2549                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2550                                + (SystemClock.uptimeMillis()-start) + "ms");
2551                        final long cachedKb = memInfo.getCachedSizeKb();
2552                        final long freeKb = memInfo.getFreeSizeKb();
2553                        final long zramKb = memInfo.getZramTotalSizeKb();
2554                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2555                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2556                                kernelKb*1024, nativeTotalPss*1024);
2557                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2558                                nativeTotalPss);
2559                    }
2560                }
2561
2562                int num = 0;
2563                long[] tmp = new long[2];
2564                do {
2565                    ProcessRecord proc;
2566                    int procState;
2567                    int pid;
2568                    long lastPssTime;
2569                    synchronized (ActivityManagerService.this) {
2570                        if (mPendingPssProcesses.size() <= 0) {
2571                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2572                                    "Collected PSS of " + num + " processes in "
2573                                    + (SystemClock.uptimeMillis() - start) + "ms");
2574                            mPendingPssProcesses.clear();
2575                            return;
2576                        }
2577                        proc = mPendingPssProcesses.remove(0);
2578                        procState = proc.pssProcState;
2579                        lastPssTime = proc.lastPssTime;
2580                        if (proc.thread != null && procState == proc.setProcState
2581                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2582                                        < SystemClock.uptimeMillis()) {
2583                            pid = proc.pid;
2584                        } else {
2585                            proc = null;
2586                            pid = 0;
2587                        }
2588                    }
2589                    if (proc != null) {
2590                        long startTime = SystemClock.currentThreadTimeMillis();
2591                        long pss = Debug.getPss(pid, tmp, null);
2592                        long endTime = SystemClock.currentThreadTimeMillis();
2593                        synchronized (ActivityManagerService.this) {
2594                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2595                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2596                                num++;
2597                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2598                                        endTime-startTime, SystemClock.uptimeMillis());
2599                            }
2600                        }
2601                    }
2602                } while (true);
2603            }
2604            }
2605        }
2606    };
2607
2608    public void setSystemProcess() {
2609        try {
2610            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
2611                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
2612            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2613            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
2614                    DUMP_FLAG_PRIORITY_HIGH);
2615            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2616            ServiceManager.addService("dbinfo", new DbBinder(this));
2617            if (MONITOR_CPU_USAGE) {
2618                ServiceManager.addService("cpuinfo", new CpuBinder(this),
2619                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
2620            }
2621            ServiceManager.addService("permission", new PermissionController(this));
2622            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2623
2624            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2625                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2626            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2627
2628            synchronized (this) {
2629                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2630                app.persistent = true;
2631                app.pid = MY_PID;
2632                app.maxAdj = ProcessList.SYSTEM_ADJ;
2633                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2634                synchronized (mPidsSelfLocked) {
2635                    mPidsSelfLocked.put(app.pid, app);
2636                }
2637                updateLruProcessLocked(app, false, null);
2638                updateOomAdjLocked();
2639            }
2640        } catch (PackageManager.NameNotFoundException e) {
2641            throw new RuntimeException(
2642                    "Unable to find android system package", e);
2643        }
2644    }
2645
2646    public void setWindowManager(WindowManagerService wm) {
2647        synchronized (this) {
2648            mWindowManager = wm;
2649            mStackSupervisor.setWindowManager(wm);
2650            mLockTaskController.setWindowManager(wm);
2651        }
2652    }
2653
2654    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2655        mUsageStatsService = usageStatsManager;
2656    }
2657
2658    public void startObservingNativeCrashes() {
2659        final NativeCrashListener ncl = new NativeCrashListener(this);
2660        ncl.start();
2661    }
2662
2663    public IAppOpsService getAppOpsService() {
2664        return mAppOpsService;
2665    }
2666
2667    static class MemBinder extends Binder {
2668        ActivityManagerService mActivityManagerService;
2669        private final PriorityDump.PriorityDumper mPriorityDumper =
2670                new PriorityDump.PriorityDumper() {
2671            @Override
2672            public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
2673                    boolean asProto) {
2674                dump(fd, pw, new String[] {"-a"}, asProto);
2675            }
2676
2677            @Override
2678            public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
2679                mActivityManagerService.dumpApplicationMemoryUsage(
2680                        fd, pw, "  ", args, false, null, asProto);
2681            }
2682        };
2683
2684        MemBinder(ActivityManagerService activityManagerService) {
2685            mActivityManagerService = activityManagerService;
2686        }
2687
2688        @Override
2689        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2690            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2691                    "meminfo", pw)) return;
2692            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2693        }
2694    }
2695
2696    static class GraphicsBinder extends Binder {
2697        ActivityManagerService mActivityManagerService;
2698        GraphicsBinder(ActivityManagerService activityManagerService) {
2699            mActivityManagerService = activityManagerService;
2700        }
2701
2702        @Override
2703        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2704            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2705                    "gfxinfo", pw)) return;
2706            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2707        }
2708    }
2709
2710    static class DbBinder extends Binder {
2711        ActivityManagerService mActivityManagerService;
2712        DbBinder(ActivityManagerService activityManagerService) {
2713            mActivityManagerService = activityManagerService;
2714        }
2715
2716        @Override
2717        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2718            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2719                    "dbinfo", pw)) return;
2720            mActivityManagerService.dumpDbInfo(fd, pw, args);
2721        }
2722    }
2723
2724    static class CpuBinder extends Binder {
2725        ActivityManagerService mActivityManagerService;
2726        private final PriorityDump.PriorityDumper mPriorityDumper =
2727                new PriorityDump.PriorityDumper() {
2728            @Override
2729            public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
2730                    boolean asProto) {
2731                if (asProto) return;
2732                if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2733                        "cpuinfo", pw)) return;
2734                synchronized (mActivityManagerService.mProcessCpuTracker) {
2735                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2736                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2737                            SystemClock.uptimeMillis()));
2738                }
2739            }
2740        };
2741
2742        CpuBinder(ActivityManagerService activityManagerService) {
2743            mActivityManagerService = activityManagerService;
2744        }
2745
2746        @Override
2747        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2748            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2749        }
2750    }
2751
2752    public static final class Lifecycle extends SystemService {
2753        private final ActivityManagerService mService;
2754
2755        public Lifecycle(Context context) {
2756            super(context);
2757            mService = new ActivityManagerService(context);
2758        }
2759
2760        @Override
2761        public void onStart() {
2762            mService.start();
2763        }
2764
2765        @Override
2766        public void onBootPhase(int phase) {
2767            if (phase == PHASE_SYSTEM_SERVICES_READY) {
2768                mService.mBatteryStatsService.systemServicesReady();
2769            }
2770        }
2771
2772        @Override
2773        public void onCleanupUser(int userId) {
2774            mService.mBatteryStatsService.onCleanupUser(userId);
2775        }
2776
2777        public ActivityManagerService getService() {
2778            return mService;
2779        }
2780    }
2781
2782    @VisibleForTesting
2783    public ActivityManagerService(Injector injector) {
2784        mInjector = injector;
2785        mContext = mInjector.getContext();
2786        mUiContext = null;
2787        GL_ES_VERSION = 0;
2788        mActivityStartController = null;
2789        mAppErrors = null;
2790        mAppWarnings = null;
2791        mAppOpsService = mInjector.getAppOpsService(null, null);
2792        mBatteryStatsService = null;
2793        mCompatModePackages = null;
2794        mConstants = null;
2795        mGrantFile = null;
2796        mHandler = null;
2797        mHandlerThread = null;
2798        mIntentFirewall = null;
2799        mKeyguardController = null;
2800        mPermissionReviewRequired = false;
2801        mProcessCpuThread = null;
2802        mProcessStats = null;
2803        mProviderMap = null;
2804        mRecentTasks = null;
2805        mServices = null;
2806        mStackSupervisor = null;
2807        mSystemThread = null;
2808        mTaskChangeNotificationController = null;
2809        mUiHandler = injector.getUiHandler(null);
2810        mUserController = null;
2811        mVrController = null;
2812        mLockTaskController = null;
2813        mLifecycleManager = null;
2814        mProcStartHandlerThread = null;
2815        mProcStartHandler = null;
2816    }
2817
2818    // Note: This method is invoked on the main thread but may need to attach various
2819    // handlers to other threads.  So take care to be explicit about the looper.
2820    public ActivityManagerService(Context systemContext) {
2821        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2822        mInjector = new Injector();
2823        mContext = systemContext;
2824
2825        mFactoryTest = FactoryTest.getMode();
2826        mSystemThread = ActivityThread.currentActivityThread();
2827        mUiContext = mSystemThread.getSystemUiContext();
2828
2829        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2830
2831        mPermissionReviewRequired = mContext.getResources().getBoolean(
2832                com.android.internal.R.bool.config_permissionReviewRequired);
2833
2834        mHandlerThread = new ServiceThread(TAG,
2835                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2836        mHandlerThread.start();
2837        mHandler = new MainHandler(mHandlerThread.getLooper());
2838        mUiHandler = mInjector.getUiHandler(this);
2839
2840        mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
2841                THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
2842        mProcStartHandlerThread.start();
2843        mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
2844
2845        mConstants = new ActivityManagerConstants(this, mHandler);
2846
2847        /* static; one-time init here */
2848        if (sKillHandler == null) {
2849            sKillThread = new ServiceThread(TAG + ":kill",
2850                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2851            sKillThread.start();
2852            sKillHandler = new KillHandler(sKillThread.getLooper());
2853        }
2854
2855        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2856                "foreground", BROADCAST_FG_TIMEOUT, false);
2857        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2858                "background", BROADCAST_BG_TIMEOUT, true);
2859        mBroadcastQueues[0] = mFgBroadcastQueue;
2860        mBroadcastQueues[1] = mBgBroadcastQueue;
2861
2862        mServices = new ActiveServices(this);
2863        mProviderMap = new ProviderMap(this);
2864        mAppErrors = new AppErrors(mUiContext, this);
2865
2866        File dataDir = Environment.getDataDirectory();
2867        File systemDir = new File(dataDir, "system");
2868        systemDir.mkdirs();
2869
2870        mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
2871
2872        // TODO: Move creation of battery stats service outside of activity manager service.
2873        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2874        mBatteryStatsService.getActiveStatistics().readLocked();
2875        mBatteryStatsService.scheduleWriteToDisk();
2876        mOnBattery = DEBUG_POWER ? true
2877                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2878        mBatteryStatsService.getActiveStatistics().setCallback(this);
2879
2880        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2881
2882        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2883        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2884                new IAppOpsCallback.Stub() {
2885                    @Override public void opChanged(int op, int uid, String packageName) {
2886                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2887                            if (mAppOpsService.checkOperation(op, uid, packageName)
2888                                    != AppOpsManager.MODE_ALLOWED) {
2889                                runInBackgroundDisabled(uid);
2890                            }
2891                        }
2892                    }
2893                });
2894
2895        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2896
2897        mUserController = new UserController(this);
2898
2899        mVrController = new VrController(this);
2900
2901        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2902            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2903
2904        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2905            mUseFifoUiScheduling = true;
2906        }
2907
2908        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2909        mTempConfig.setToDefaults();
2910        mTempConfig.setLocales(LocaleList.getDefault());
2911        mConfigurationSeq = mTempConfig.seq = 1;
2912        mStackSupervisor = createStackSupervisor();
2913        mStackSupervisor.onConfigurationChanged(mTempConfig);
2914        mKeyguardController = mStackSupervisor.getKeyguardController();
2915        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2916        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2917        mTaskChangeNotificationController =
2918                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2919        mActivityStartController = new ActivityStartController(this);
2920        mRecentTasks = createRecentTasks();
2921        mStackSupervisor.setRecentTasks(mRecentTasks);
2922        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
2923        mLifecycleManager = new ClientLifecycleManager();
2924
2925        mProcessCpuThread = new Thread("CpuTracker") {
2926            @Override
2927            public void run() {
2928                synchronized (mProcessCpuTracker) {
2929                    mProcessCpuInitLatch.countDown();
2930                    mProcessCpuTracker.init();
2931                }
2932                while (true) {
2933                    try {
2934                        try {
2935                            synchronized(this) {
2936                                final long now = SystemClock.uptimeMillis();
2937                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2938                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2939                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2940                                //        + ", write delay=" + nextWriteDelay);
2941                                if (nextWriteDelay < nextCpuDelay) {
2942                                    nextCpuDelay = nextWriteDelay;
2943                                }
2944                                if (nextCpuDelay > 0) {
2945                                    mProcessCpuMutexFree.set(true);
2946                                    this.wait(nextCpuDelay);
2947                                }
2948                            }
2949                        } catch (InterruptedException e) {
2950                        }
2951                        updateCpuStatsNow();
2952                    } catch (Exception e) {
2953                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2954                    }
2955                }
2956            }
2957        };
2958
2959        Watchdog.getInstance().addMonitor(this);
2960        Watchdog.getInstance().addThread(mHandler);
2961    }
2962
2963    protected ActivityStackSupervisor createStackSupervisor() {
2964        final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
2965        supervisor.initialize();
2966        return supervisor;
2967    }
2968
2969    protected RecentTasks createRecentTasks() {
2970        return new RecentTasks(this, mStackSupervisor);
2971    }
2972
2973    RecentTasks getRecentTasks() {
2974        return mRecentTasks;
2975    }
2976
2977    public void setSystemServiceManager(SystemServiceManager mgr) {
2978        mSystemServiceManager = mgr;
2979    }
2980
2981    public void setInstaller(Installer installer) {
2982        mInstaller = installer;
2983    }
2984
2985    private void start() {
2986        removeAllProcessGroups();
2987        mProcessCpuThread.start();
2988
2989        mBatteryStatsService.publish();
2990        mAppOpsService.publish(mContext);
2991        Slog.d("AppOps", "AppOpsService published");
2992        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2993        // Wait for the synchronized block started in mProcessCpuThread,
2994        // so that any other acccess to mProcessCpuTracker from main thread
2995        // will be blocked during mProcessCpuTracker initialization.
2996        try {
2997            mProcessCpuInitLatch.await();
2998        } catch (InterruptedException e) {
2999            Slog.wtf(TAG, "Interrupted wait during start", e);
3000            Thread.currentThread().interrupt();
3001            throw new IllegalStateException("Interrupted wait during start");
3002        }
3003    }
3004
3005    void onUserStoppedLocked(int userId) {
3006        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
3007        mAllowAppSwitchUids.remove(userId);
3008    }
3009
3010    public void initPowerManagement() {
3011        mStackSupervisor.initPowerManagement();
3012        mBatteryStatsService.initPowerManagement();
3013        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
3014        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
3015        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
3016        mVoiceWakeLock.setReferenceCounted(false);
3017    }
3018
3019    private ArraySet<String> getBackgroundLaunchBroadcasts() {
3020        if (mBackgroundLaunchBroadcasts == null) {
3021            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
3022        }
3023        return mBackgroundLaunchBroadcasts;
3024    }
3025
3026    @Override
3027    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3028            throws RemoteException {
3029        if (code == SYSPROPS_TRANSACTION) {
3030            // We need to tell all apps about the system property change.
3031            ArrayList<IBinder> procs = new ArrayList<IBinder>();
3032            synchronized(this) {
3033                final int NP = mProcessNames.getMap().size();
3034                for (int ip=0; ip<NP; ip++) {
3035                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3036                    final int NA = apps.size();
3037                    for (int ia=0; ia<NA; ia++) {
3038                        ProcessRecord app = apps.valueAt(ia);
3039                        if (app.thread != null) {
3040                            procs.add(app.thread.asBinder());
3041                        }
3042                    }
3043                }
3044            }
3045
3046            int N = procs.size();
3047            for (int i=0; i<N; i++) {
3048                Parcel data2 = Parcel.obtain();
3049                try {
3050                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
3051                            Binder.FLAG_ONEWAY);
3052                } catch (RemoteException e) {
3053                }
3054                data2.recycle();
3055            }
3056        }
3057        try {
3058            return super.onTransact(code, data, reply, flags);
3059        } catch (RuntimeException e) {
3060            // The activity manager only throws certain exceptions intentionally, so let's
3061            // log all others.
3062            if (!(e instanceof SecurityException
3063                    || e instanceof IllegalArgumentException
3064                    || e instanceof IllegalStateException)) {
3065                Slog.wtf(TAG, "Activity Manager Crash."
3066                        + " UID:" + Binder.getCallingUid()
3067                        + " PID:" + Binder.getCallingPid()
3068                        + " TRANS:" + code, e);
3069            }
3070            throw e;
3071        }
3072    }
3073
3074    void updateCpuStats() {
3075        final long now = SystemClock.uptimeMillis();
3076        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3077            return;
3078        }
3079        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3080            synchronized (mProcessCpuThread) {
3081                mProcessCpuThread.notify();
3082            }
3083        }
3084    }
3085
3086    void updateCpuStatsNow() {
3087        synchronized (mProcessCpuTracker) {
3088            mProcessCpuMutexFree.set(false);
3089            final long now = SystemClock.uptimeMillis();
3090            boolean haveNewCpuStats = false;
3091
3092            if (MONITOR_CPU_USAGE &&
3093                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3094                mLastCpuTime.set(now);
3095                mProcessCpuTracker.update();
3096                if (mProcessCpuTracker.hasGoodLastStats()) {
3097                    haveNewCpuStats = true;
3098                    //Slog.i(TAG, mProcessCpu.printCurrentState());
3099                    //Slog.i(TAG, "Total CPU usage: "
3100                    //        + mProcessCpu.getTotalCpuPercent() + "%");
3101
3102                    // Slog the cpu usage if the property is set.
3103                    if ("true".equals(SystemProperties.get("events.cpu"))) {
3104                        int user = mProcessCpuTracker.getLastUserTime();
3105                        int system = mProcessCpuTracker.getLastSystemTime();
3106                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
3107                        int irq = mProcessCpuTracker.getLastIrqTime();
3108                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3109                        int idle = mProcessCpuTracker.getLastIdleTime();
3110
3111                        int total = user + system + iowait + irq + softIrq + idle;
3112                        if (total == 0) total = 1;
3113
3114                        EventLog.writeEvent(EventLogTags.CPU,
3115                                ((user+system+iowait+irq+softIrq) * 100) / total,
3116                                (user * 100) / total,
3117                                (system * 100) / total,
3118                                (iowait * 100) / total,
3119                                (irq * 100) / total,
3120                                (softIrq * 100) / total);
3121                    }
3122                }
3123            }
3124
3125            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3126            synchronized(bstats) {
3127                synchronized(mPidsSelfLocked) {
3128                    if (haveNewCpuStats) {
3129                        if (bstats.startAddingCpuLocked()) {
3130                            int totalUTime = 0;
3131                            int totalSTime = 0;
3132                            final int N = mProcessCpuTracker.countStats();
3133                            for (int i=0; i<N; i++) {
3134                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3135                                if (!st.working) {
3136                                    continue;
3137                                }
3138                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3139                                totalUTime += st.rel_utime;
3140                                totalSTime += st.rel_stime;
3141                                if (pr != null) {
3142                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3143                                    if (ps == null || !ps.isActive()) {
3144                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3145                                                pr.info.uid, pr.processName);
3146                                    }
3147                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3148                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3149                                    if (pr.lastCpuTime == 0) {
3150                                        pr.lastCpuTime = pr.curCpuTime;
3151                                    }
3152                                } else {
3153                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3154                                    if (ps == null || !ps.isActive()) {
3155                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3156                                                bstats.mapUid(st.uid), st.name);
3157                                    }
3158                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3159                                }
3160                            }
3161                            final int userTime = mProcessCpuTracker.getLastUserTime();
3162                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3163                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3164                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3165                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3166                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3167                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3168                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3169                        }
3170                    }
3171                }
3172
3173                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3174                    mLastWriteTime = now;
3175                    mBatteryStatsService.scheduleWriteToDisk();
3176                }
3177            }
3178        }
3179    }
3180
3181    @Override
3182    public void batteryNeedsCpuUpdate() {
3183        updateCpuStatsNow();
3184    }
3185
3186    @Override
3187    public void batteryPowerChanged(boolean onBattery) {
3188        // When plugging in, update the CPU stats first before changing
3189        // the plug state.
3190        updateCpuStatsNow();
3191        synchronized (this) {
3192            synchronized(mPidsSelfLocked) {
3193                mOnBattery = DEBUG_POWER ? true : onBattery;
3194            }
3195        }
3196    }
3197
3198    @Override
3199    public void batterySendBroadcast(Intent intent) {
3200        synchronized (this) {
3201            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3202                    OP_NONE, null, false, false,
3203                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3204        }
3205    }
3206
3207    /**
3208     * Initialize the application bind args. These are passed to each
3209     * process when the bindApplication() IPC is sent to the process. They're
3210     * lazily setup to make sure the services are running when they're asked for.
3211     */
3212    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3213        // Isolated processes won't get this optimization, so that we don't
3214        // violate the rules about which services they have access to.
3215        if (isolated) {
3216            if (mIsolatedAppBindArgs == null) {
3217                mIsolatedAppBindArgs = new HashMap<>();
3218                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3219            }
3220            return mIsolatedAppBindArgs;
3221        }
3222
3223        if (mAppBindArgs == null) {
3224            mAppBindArgs = new HashMap<>();
3225
3226            // Setup the application init args
3227            mAppBindArgs.put("package", ServiceManager.getService("package"));
3228            mAppBindArgs.put("window", ServiceManager.getService("window"));
3229            mAppBindArgs.put(Context.ALARM_SERVICE,
3230                    ServiceManager.getService(Context.ALARM_SERVICE));
3231        }
3232        return mAppBindArgs;
3233    }
3234
3235    /**
3236     * Update AMS states when an activity is resumed. This should only be called by
3237     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3238     */
3239    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3240        final TaskRecord task = r.getTask();
3241        if (task.isActivityTypeStandard()) {
3242            if (mCurAppTimeTracker != r.appTimeTracker) {
3243                // We are switching app tracking.  Complete the current one.
3244                if (mCurAppTimeTracker != null) {
3245                    mCurAppTimeTracker.stop();
3246                    mHandler.obtainMessage(
3247                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3248                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3249                    mCurAppTimeTracker = null;
3250                }
3251                if (r.appTimeTracker != null) {
3252                    mCurAppTimeTracker = r.appTimeTracker;
3253                    startTimeTrackingFocusedActivityLocked();
3254                }
3255            } else {
3256                startTimeTrackingFocusedActivityLocked();
3257            }
3258        } else {
3259            r.appTimeTracker = null;
3260        }
3261        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3262        // TODO: Probably not, because we don't want to resume voice on switching
3263        // back to this activity
3264        if (task.voiceInteractor != null) {
3265            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3266        } else {
3267            finishRunningVoiceLocked();
3268
3269            if (mLastResumedActivity != null) {
3270                final IVoiceInteractionSession session;
3271
3272                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3273                if (lastResumedActivityTask != null
3274                        && lastResumedActivityTask.voiceSession != null) {
3275                    session = lastResumedActivityTask.voiceSession;
3276                } else {
3277                    session = mLastResumedActivity.voiceSession;
3278                }
3279
3280                if (session != null) {
3281                    // We had been in a voice interaction session, but now focused has
3282                    // move to something different.  Just finish the session, we can't
3283                    // return to it and retain the proper state and synchronization with
3284                    // the voice interaction service.
3285                    finishVoiceTask(session);
3286                }
3287            }
3288        }
3289
3290        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3291            mUserController.sendForegroundProfileChanged(r.userId);
3292        }
3293        mLastResumedActivity = r;
3294
3295        mWindowManager.setFocusedApp(r.appToken, true);
3296
3297        applyUpdateLockStateLocked(r);
3298        applyUpdateVrModeLocked(r);
3299
3300        EventLogTags.writeAmSetResumedActivity(
3301                r == null ? -1 : r.userId,
3302                r == null ? "NULL" : r.shortComponentName,
3303                reason);
3304    }
3305
3306    @Override
3307    public void setFocusedStack(int stackId) {
3308        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3309        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3310        final long callingId = Binder.clearCallingIdentity();
3311        try {
3312            synchronized (this) {
3313                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3314                if (stack == null) {
3315                    Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3316                    return;
3317                }
3318                final ActivityRecord r = stack.topRunningActivityLocked();
3319                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3320                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3321                }
3322            }
3323        } finally {
3324            Binder.restoreCallingIdentity(callingId);
3325        }
3326    }
3327
3328    @Override
3329    public void setFocusedTask(int taskId) {
3330        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3331        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3332        final long callingId = Binder.clearCallingIdentity();
3333        try {
3334            synchronized (this) {
3335                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3336                if (task == null) {
3337                    return;
3338                }
3339                final ActivityRecord r = task.topRunningActivityLocked();
3340                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3341                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3342                }
3343            }
3344        } finally {
3345            Binder.restoreCallingIdentity(callingId);
3346        }
3347    }
3348
3349    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3350    @Override
3351    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3352        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3353                "registerTaskStackListener()");
3354        mTaskChangeNotificationController.registerTaskStackListener(listener);
3355    }
3356
3357    /**
3358     * Unregister a task stack listener so that it stops receiving callbacks.
3359     */
3360    @Override
3361    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3362        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3363                "unregisterTaskStackListener()");
3364         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3365     }
3366
3367    @Override
3368    public void notifyActivityDrawn(IBinder token) {
3369        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3370        synchronized (this) {
3371            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3372            if (r != null) {
3373                r.getStack().notifyActivityDrawnLocked(r);
3374            }
3375        }
3376    }
3377
3378    final void applyUpdateLockStateLocked(ActivityRecord r) {
3379        // Modifications to the UpdateLock state are done on our handler, outside
3380        // the activity manager's locks.  The new state is determined based on the
3381        // state *now* of the relevant activity record.  The object is passed to
3382        // the handler solely for logging detail, not to be consulted/modified.
3383        final boolean nextState = r != null && r.immersive;
3384        mHandler.sendMessage(
3385                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3386    }
3387
3388    final void applyUpdateVrModeLocked(ActivityRecord r) {
3389        // VR apps are expected to run in a main display. If an app is turning on VR for
3390        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3391        // fullscreen stack before enabling VR Mode.
3392        // TODO: The goal of this code is to keep the VR app on the main display. When the
3393        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3394        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3395        // option would be a better choice here.
3396        if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3397            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3398                    + " to main stack for VR");
3399            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3400                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3401            moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3402        }
3403        mHandler.sendMessage(
3404                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3405    }
3406
3407    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3408        Message msg = Message.obtain();
3409        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3410        msg.obj = r.getTask().askedCompatMode ? null : r;
3411        mUiHandler.sendMessage(msg);
3412    }
3413
3414    final AppWarnings getAppWarningsLocked() {
3415        return mAppWarnings;
3416    }
3417
3418    /**
3419     * Shows app warning dialogs, if necessary.
3420     *
3421     * @param r activity record for which the warnings may be displayed
3422     */
3423    final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3424        mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3425        mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3426    }
3427
3428    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3429            String what, Object obj, ProcessRecord srcApp) {
3430        app.lastActivityTime = now;
3431
3432        if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3433            // Don't want to touch dependent processes that are hosting activities.
3434            return index;
3435        }
3436
3437        int lrui = mLruProcesses.lastIndexOf(app);
3438        if (lrui < 0) {
3439            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3440                    + what + " " + obj + " from " + srcApp);
3441            return index;
3442        }
3443
3444        if (lrui >= index) {
3445            // Don't want to cause this to move dependent processes *back* in the
3446            // list as if they were less frequently used.
3447            return index;
3448        }
3449
3450        if (lrui >= mLruProcessActivityStart) {
3451            // Don't want to touch dependent processes that are hosting activities.
3452            return index;
3453        }
3454
3455        mLruProcesses.remove(lrui);
3456        if (index > 0) {
3457            index--;
3458        }
3459        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3460                + " in LRU list: " + app);
3461        mLruProcesses.add(index, app);
3462        return index;
3463    }
3464
3465    static void killProcessGroup(int uid, int pid) {
3466        if (sKillHandler != null) {
3467            sKillHandler.sendMessage(
3468                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3469        } else {
3470            Slog.w(TAG, "Asked to kill process group before system bringup!");
3471            Process.killProcessGroup(uid, pid);
3472        }
3473    }
3474
3475    final void removeLruProcessLocked(ProcessRecord app) {
3476        int lrui = mLruProcesses.lastIndexOf(app);
3477        if (lrui >= 0) {
3478            if (!app.killed) {
3479                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3480                if (app.pid > 0) {
3481                    killProcessQuiet(app.pid);
3482                    killProcessGroup(app.uid, app.pid);
3483                } else {
3484                    app.pendingStart = false;
3485                }
3486            }
3487            if (lrui <= mLruProcessActivityStart) {
3488                mLruProcessActivityStart--;
3489            }
3490            if (lrui <= mLruProcessServiceStart) {
3491                mLruProcessServiceStart--;
3492            }
3493            mLruProcesses.remove(lrui);
3494        }
3495    }
3496
3497    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3498            ProcessRecord client) {
3499        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3500                || app.treatLikeActivity || app.recentTasks.size() > 0;
3501        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3502        if (!activityChange && hasActivity) {
3503            // The process has activities, so we are only allowing activity-based adjustments
3504            // to move it.  It should be kept in the front of the list with other
3505            // processes that have activities, and we don't want those to change their
3506            // order except due to activity operations.
3507            return;
3508        }
3509
3510        mLruSeq++;
3511        final long now = SystemClock.uptimeMillis();
3512        app.lastActivityTime = now;
3513
3514        // First a quick reject: if the app is already at the position we will
3515        // put it, then there is nothing to do.
3516        if (hasActivity) {
3517            final int N = mLruProcesses.size();
3518            if (N > 0 && mLruProcesses.get(N-1) == app) {
3519                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3520                return;
3521            }
3522        } else {
3523            if (mLruProcessServiceStart > 0
3524                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3525                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3526                return;
3527            }
3528        }
3529
3530        int lrui = mLruProcesses.lastIndexOf(app);
3531
3532        if (app.persistent && lrui >= 0) {
3533            // We don't care about the position of persistent processes, as long as
3534            // they are in the list.
3535            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3536            return;
3537        }
3538
3539        /* In progress: compute new position first, so we can avoid doing work
3540           if the process is not actually going to move.  Not yet working.
3541        int addIndex;
3542        int nextIndex;
3543        boolean inActivity = false, inService = false;
3544        if (hasActivity) {
3545            // Process has activities, put it at the very tipsy-top.
3546            addIndex = mLruProcesses.size();
3547            nextIndex = mLruProcessServiceStart;
3548            inActivity = true;
3549        } else if (hasService) {
3550            // Process has services, put it at the top of the service list.
3551            addIndex = mLruProcessActivityStart;
3552            nextIndex = mLruProcessServiceStart;
3553            inActivity = true;
3554            inService = true;
3555        } else  {
3556            // Process not otherwise of interest, it goes to the top of the non-service area.
3557            addIndex = mLruProcessServiceStart;
3558            if (client != null) {
3559                int clientIndex = mLruProcesses.lastIndexOf(client);
3560                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3561                        + app);
3562                if (clientIndex >= 0 && addIndex > clientIndex) {
3563                    addIndex = clientIndex;
3564                }
3565            }
3566            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3567        }
3568
3569        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3570                + mLruProcessActivityStart + "): " + app);
3571        */
3572
3573        if (lrui >= 0) {
3574            if (lrui < mLruProcessActivityStart) {
3575                mLruProcessActivityStart--;
3576            }
3577            if (lrui < mLruProcessServiceStart) {
3578                mLruProcessServiceStart--;
3579            }
3580            /*
3581            if (addIndex > lrui) {
3582                addIndex--;
3583            }
3584            if (nextIndex > lrui) {
3585                nextIndex--;
3586            }
3587            */
3588            mLruProcesses.remove(lrui);
3589        }
3590
3591        /*
3592        mLruProcesses.add(addIndex, app);
3593        if (inActivity) {
3594            mLruProcessActivityStart++;
3595        }
3596        if (inService) {
3597            mLruProcessActivityStart++;
3598        }
3599        */
3600
3601        int nextIndex;
3602        if (hasActivity) {
3603            final int N = mLruProcesses.size();
3604            if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
3605                    && mLruProcessActivityStart < (N - 1)) {
3606                // Process doesn't have activities, but has clients with
3607                // activities...  move it up, but one below the top (the top
3608                // should always have a real activity).
3609                if (DEBUG_LRU) Slog.d(TAG_LRU,
3610                        "Adding to second-top of LRU activity list: " + app);
3611                mLruProcesses.add(N - 1, app);
3612                // To keep it from spamming the LRU list (by making a bunch of clients),
3613                // we will push down any other entries owned by the app.
3614                final int uid = app.info.uid;
3615                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3616                    ProcessRecord subProc = mLruProcesses.get(i);
3617                    if (subProc.info.uid == uid) {
3618                        // We want to push this one down the list.  If the process after
3619                        // it is for the same uid, however, don't do so, because we don't
3620                        // want them internally to be re-ordered.
3621                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3622                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3623                                    "Pushing uid " + uid + " swapping at " + i + ": "
3624                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3625                            ProcessRecord tmp = mLruProcesses.get(i);
3626                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3627                            mLruProcesses.set(i - 1, tmp);
3628                            i--;
3629                        }
3630                    } else {
3631                        // A gap, we can stop here.
3632                        break;
3633                    }
3634                }
3635            } else {
3636                // Process has activities, put it at the very tipsy-top.
3637                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3638                mLruProcesses.add(app);
3639            }
3640            nextIndex = mLruProcessServiceStart;
3641        } else if (hasService) {
3642            // Process has services, put it at the top of the service list.
3643            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3644            mLruProcesses.add(mLruProcessActivityStart, app);
3645            nextIndex = mLruProcessServiceStart;
3646            mLruProcessActivityStart++;
3647        } else  {
3648            // Process not otherwise of interest, it goes to the top of the non-service area.
3649            int index = mLruProcessServiceStart;
3650            if (client != null) {
3651                // If there is a client, don't allow the process to be moved up higher
3652                // in the list than that client.
3653                int clientIndex = mLruProcesses.lastIndexOf(client);
3654                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3655                        + " when updating " + app);
3656                if (clientIndex <= lrui) {
3657                    // Don't allow the client index restriction to push it down farther in the
3658                    // list than it already is.
3659                    clientIndex = lrui;
3660                }
3661                if (clientIndex >= 0 && index > clientIndex) {
3662                    index = clientIndex;
3663                }
3664            }
3665            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3666            mLruProcesses.add(index, app);
3667            nextIndex = index-1;
3668            mLruProcessActivityStart++;
3669            mLruProcessServiceStart++;
3670        }
3671
3672        // If the app is currently using a content provider or service,
3673        // bump those processes as well.
3674        for (int j=app.connections.size()-1; j>=0; j--) {
3675            ConnectionRecord cr = app.connections.valueAt(j);
3676            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3677                    && cr.binding.service.app != null
3678                    && cr.binding.service.app.lruSeq != mLruSeq
3679                    && !cr.binding.service.app.persistent) {
3680                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3681                        "service connection", cr, app);
3682            }
3683        }
3684        for (int j=app.conProviders.size()-1; j>=0; j--) {
3685            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3686            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3687                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3688                        "provider reference", cpr, app);
3689            }
3690        }
3691    }
3692
3693    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3694        if (uid == SYSTEM_UID) {
3695            // The system gets to run in any process.  If there are multiple
3696            // processes with the same uid, just pick the first (this
3697            // should never happen).
3698            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3699            if (procs == null) return null;
3700            final int procCount = procs.size();
3701            for (int i = 0; i < procCount; i++) {
3702                final int procUid = procs.keyAt(i);
3703                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3704                    // Don't use an app process or different user process for system component.
3705                    continue;
3706                }
3707                return procs.valueAt(i);
3708            }
3709        }
3710        ProcessRecord proc = mProcessNames.get(processName, uid);
3711        if (false && proc != null && !keepIfLarge
3712                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3713                && proc.lastCachedPss >= 4000) {
3714            // Turn this condition on to cause killing to happen regularly, for testing.
3715            if (proc.baseProcessTracker != null) {
3716                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3717            }
3718            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3719        } else if (proc != null && !keepIfLarge
3720                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3721                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3722            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3723            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3724                if (proc.baseProcessTracker != null) {
3725                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3726                }
3727                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3728            }
3729        }
3730        return proc;
3731    }
3732
3733    void notifyPackageUse(String packageName, int reason) {
3734        synchronized(this) {
3735            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3736        }
3737    }
3738
3739    boolean isNextTransitionForward() {
3740        int transit = mWindowManager.getPendingAppTransition();
3741        return transit == TRANSIT_ACTIVITY_OPEN
3742                || transit == TRANSIT_TASK_OPEN
3743                || transit == TRANSIT_TASK_TO_FRONT;
3744    }
3745
3746    boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3747            String processName, String abiOverride, int uid, Runnable crashHandler) {
3748        synchronized(this) {
3749            ApplicationInfo info = new ApplicationInfo();
3750            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3751            // For isolated processes, the former contains the parent's uid and the latter the
3752            // actual uid of the isolated process.
3753            // In the special case introduced by this method (which is, starting an isolated
3754            // process directly from the SystemServer without an actual parent app process) the
3755            // closest thing to a parent's uid is SYSTEM_UID.
3756            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3757            // the |isolated| logic in the ProcessRecord constructor.
3758            info.uid = SYSTEM_UID;
3759            info.processName = processName;
3760            info.className = entryPoint;
3761            info.packageName = "android";
3762            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3763            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3764                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3765                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3766                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3767                    crashHandler);
3768            return proc != null;
3769        }
3770    }
3771
3772    final ProcessRecord startProcessLocked(String processName,
3773            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3774            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3775            boolean isolated, boolean keepIfLarge) {
3776        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3777                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3778                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3779                null /* crashHandler */);
3780    }
3781
3782    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3783            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3784            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3785            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3786        long startTime = SystemClock.elapsedRealtime();
3787        ProcessRecord app;
3788        if (!isolated) {
3789            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3790            checkTime(startTime, "startProcess: after getProcessRecord");
3791
3792            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3793                // If we are in the background, then check to see if this process
3794                // is bad.  If so, we will just silently fail.
3795                if (mAppErrors.isBadProcessLocked(info)) {
3796                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3797                            + "/" + info.processName);
3798                    return null;
3799                }
3800            } else {
3801                // When the user is explicitly starting a process, then clear its
3802                // crash count so that we won't make it bad until they see at
3803                // least one crash dialog again, and make the process good again
3804                // if it had been bad.
3805                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3806                        + "/" + info.processName);
3807                mAppErrors.resetProcessCrashTimeLocked(info);
3808                if (mAppErrors.isBadProcessLocked(info)) {
3809                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3810                            UserHandle.getUserId(info.uid), info.uid,
3811                            info.processName);
3812                    mAppErrors.clearBadProcessLocked(info);
3813                    if (app != null) {
3814                        app.bad = false;
3815                    }
3816                }
3817            }
3818        } else {
3819            // If this is an isolated process, it can't re-use an existing process.
3820            app = null;
3821        }
3822
3823        // We don't have to do anything more if:
3824        // (1) There is an existing application record; and
3825        // (2) The caller doesn't think it is dead, OR there is no thread
3826        //     object attached to it so we know it couldn't have crashed; and
3827        // (3) There is a pid assigned to it, so it is either starting or
3828        //     already running.
3829        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3830                + " app=" + app + " knownToBeDead=" + knownToBeDead
3831                + " thread=" + (app != null ? app.thread : null)
3832                + " pid=" + (app != null ? app.pid : -1));
3833        if (app != null && app.pid > 0) {
3834            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3835                // We already have the app running, or are waiting for it to
3836                // come up (we have a pid but not yet its thread), so keep it.
3837                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3838                // If this is a new package in the process, add the package to the list
3839                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3840                checkTime(startTime, "startProcess: done, added package to proc");
3841                return app;
3842            }
3843
3844            // An application record is attached to a previous process,
3845            // clean it up now.
3846            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3847            checkTime(startTime, "startProcess: bad proc running, killing");
3848            killProcessGroup(app.uid, app.pid);
3849            handleAppDiedLocked(app, true, true);
3850            checkTime(startTime, "startProcess: done killing old proc");
3851        }
3852
3853        String hostingNameStr = hostingName != null
3854                ? hostingName.flattenToShortString() : null;
3855
3856        if (app == null) {
3857            checkTime(startTime, "startProcess: creating new process record");
3858            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3859            if (app == null) {
3860                Slog.w(TAG, "Failed making new process record for "
3861                        + processName + "/" + info.uid + " isolated=" + isolated);
3862                return null;
3863            }
3864            app.crashHandler = crashHandler;
3865            app.isolatedEntryPoint = entryPoint;
3866            app.isolatedEntryPointArgs = entryPointArgs;
3867            checkTime(startTime, "startProcess: done creating new process record");
3868        } else {
3869            // If this is a new package in the process, add the package to the list
3870            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3871            checkTime(startTime, "startProcess: added package to existing proc");
3872        }
3873
3874        // If the system is not ready yet, then hold off on starting this
3875        // process until it is.
3876        if (!mProcessesReady
3877                && !isAllowedWhileBooting(info)
3878                && !allowWhileBooting) {
3879            if (!mProcessesOnHold.contains(app)) {
3880                mProcessesOnHold.add(app);
3881            }
3882            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3883                    "System not ready, putting on hold: " + app);
3884            checkTime(startTime, "startProcess: returning with proc on hold");
3885            return app;
3886        }
3887
3888        checkTime(startTime, "startProcess: stepping in to startProcess");
3889        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
3890        checkTime(startTime, "startProcess: done starting proc!");
3891        return success ? app : null;
3892    }
3893
3894    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3895        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3896    }
3897
3898    private final void startProcessLocked(ProcessRecord app,
3899            String hostingType, String hostingNameStr) {
3900        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
3901    }
3902
3903    /**
3904     * @return {@code true} if process start is successful, false otherwise.
3905     */
3906    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
3907            String hostingNameStr, String abiOverride) {
3908        if (app.pendingStart) {
3909            return true;
3910        }
3911        long startTime = SystemClock.elapsedRealtime();
3912        if (app.pid > 0 && app.pid != MY_PID) {
3913            checkTime(startTime, "startProcess: removing from pids map");
3914            synchronized (mPidsSelfLocked) {
3915                mPidsSelfLocked.remove(app.pid);
3916                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3917            }
3918            checkTime(startTime, "startProcess: done removing from pids map");
3919            app.setPid(0);
3920        }
3921
3922        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3923                "startProcessLocked removing on hold: " + app);
3924        mProcessesOnHold.remove(app);
3925
3926        checkTime(startTime, "startProcess: starting to update cpu stats");
3927        updateCpuStats();
3928        checkTime(startTime, "startProcess: done updating cpu stats");
3929
3930        try {
3931            try {
3932                final int userId = UserHandle.getUserId(app.uid);
3933                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3934            } catch (RemoteException e) {
3935                throw e.rethrowAsRuntimeException();
3936            }
3937
3938            int uid = app.uid;
3939            int[] gids = null;
3940            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3941            if (!app.isolated) {
3942                int[] permGids = null;
3943                try {
3944                    checkTime(startTime, "startProcess: getting gids from package manager");
3945                    final IPackageManager pm = AppGlobals.getPackageManager();
3946                    permGids = pm.getPackageGids(app.info.packageName,
3947                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3948                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3949                            StorageManagerInternal.class);
3950                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3951                            app.info.packageName);
3952                } catch (RemoteException e) {
3953                    throw e.rethrowAsRuntimeException();
3954                }
3955
3956                /*
3957                 * Add shared application and profile GIDs so applications can share some
3958                 * resources like shared libraries and access user-wide resources
3959                 */
3960                if (ArrayUtils.isEmpty(permGids)) {
3961                    gids = new int[3];
3962                } else {
3963                    gids = new int[permGids.length + 3];
3964                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3965                }
3966                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3967                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3968                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3969
3970                // Replace any invalid GIDs
3971                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
3972                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
3973            }
3974            checkTime(startTime, "startProcess: building args");
3975            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3976                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3977                        && mTopComponent != null
3978                        && app.processName.equals(mTopComponent.getPackageName())) {
3979                    uid = 0;
3980                }
3981                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3982                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3983                    uid = 0;
3984                }
3985            }
3986            int runtimeFlags = 0;
3987            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3988                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
3989                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3990                // Also turn on CheckJNI for debuggable apps. It's quite
3991                // awkward to turn on otherwise.
3992                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3993            }
3994            // Run the app in safe mode if its manifest requests so or the
3995            // system is booted in safe mode.
3996            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3997                mSafeMode == true) {
3998                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3999            }
4000            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4001                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4002            }
4003            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4004            if ("true".equals(genDebugInfoProperty)) {
4005                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4006            }
4007            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4008                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4009            }
4010            if ("1".equals(SystemProperties.get("debug.assert"))) {
4011                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
4012            }
4013            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
4014                // Enable all debug flags required by the native debugger.
4015                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
4016                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
4017                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
4018                mNativeDebuggingApp = null;
4019            }
4020
4021            if (app.info.isPrivilegedApp() &&
4022                    SystemProperties.getBoolean("pm.dexopt.priv-apps-oob", false)) {
4023                runtimeFlags |= Zygote.DISABLE_VERIFIER;
4024                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
4025            }
4026
4027            String invokeWith = null;
4028            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4029                // Debuggable apps may include a wrapper script with their library directory.
4030                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
4031                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4032                try {
4033                    if (new File(wrapperFileName).exists()) {
4034                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4035                    }
4036                } finally {
4037                    StrictMode.setThreadPolicy(oldPolicy);
4038                }
4039            }
4040
4041            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4042            if (requiredAbi == null) {
4043                requiredAbi = Build.SUPPORTED_ABIS[0];
4044            }
4045
4046            String instructionSet = null;
4047            if (app.info.primaryCpuAbi != null) {
4048                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4049            }
4050
4051            app.gids = gids;
4052            app.requiredAbi = requiredAbi;
4053            app.instructionSet = instructionSet;
4054
4055            // the per-user SELinux context must be set
4056            if (TextUtils.isEmpty(app.info.seInfoUser)) {
4057                Slog.wtf(TAG, "SELinux tag not defined",
4058                        new IllegalStateException("SELinux tag not defined for "
4059                        + app.info.packageName + " (uid " + app.uid + ")"));
4060            }
4061            final String seInfo = app.info.seInfo
4062                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
4063            // Start the process.  It will either succeed and return a result containing
4064            // the PID of the new process, or else throw a RuntimeException.
4065            final String entryPoint = "android.app.ActivityThread";
4066
4067            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4068                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4069                    startTime);
4070        } catch (RuntimeException e) {
4071            Slog.e(TAG, "Failure starting process " + app.processName, e);
4072
4073            // Something went very wrong while trying to start this process; one
4074            // common case is when the package is frozen due to an active
4075            // upgrade. To recover, clean up any active bookkeeping related to
4076            // starting this process. (We already invoked this method once when
4077            // the package was initially frozen through KILL_APPLICATION_MSG, so
4078            // it doesn't hurt to use it again.)
4079            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4080                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4081            return false;
4082        }
4083    }
4084
4085    @GuardedBy("this")
4086    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4087            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4088            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4089            long startTime) {
4090        app.pendingStart = true;
4091        app.killedByAm = false;
4092        app.removed = false;
4093        app.killed = false;
4094        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4095        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4096        if (mConstants.FLAG_PROCESS_START_ASYNC) {
4097            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4098                    "Posting procStart msg for " + app.toShortString());
4099            mProcStartHandler.post(() -> {
4100                try {
4101                    synchronized (ActivityManagerService.this) {
4102                        final String reason = isProcStartValidLocked(app, startSeq);
4103                        if (reason != null) {
4104                            Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4105                                    + " don't start process, " + reason);
4106                            app.pendingStart = false;
4107                            return;
4108                        }
4109                        app.usingWrapper = invokeWith != null
4110                                || SystemProperties.get("wrap." + app.processName) != null;
4111                        mPendingStarts.put(startSeq, app);
4112                    }
4113                    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4114                            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4115                            requiredAbi, instructionSet, invokeWith, app.startTime);
4116                    synchronized (ActivityManagerService.this) {
4117                        handleProcessStartedLocked(app, startResult, startSeq);
4118                    }
4119                } catch (RuntimeException e) {
4120                    synchronized (ActivityManagerService.this) {
4121                        Slog.e(TAG, "Failure starting process " + app.processName, e);
4122                        mPendingStarts.remove(startSeq);
4123                        app.pendingStart = false;
4124                        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4125                                false, false, true, false, false,
4126                                UserHandle.getUserId(app.userId), "start failure");
4127                    }
4128                }
4129            });
4130            return true;
4131        } else {
4132            try {
4133                final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4134                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4135                        invokeWith, startTime);
4136                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4137                        startSeq, false);
4138            } catch (RuntimeException e) {
4139                Slog.e(TAG, "Failure starting process " + app.processName, e);
4140                app.pendingStart = false;
4141                forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4142                        false, false, true, false, false,
4143                        UserHandle.getUserId(app.userId), "start failure");
4144            }
4145            return app.pid > 0;
4146        }
4147    }
4148
4149    private ProcessStartResult startProcess(String hostingType, String entryPoint,
4150            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4151            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4152            long startTime) {
4153        try {
4154            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4155                    app.processName);
4156            checkTime(startTime, "startProcess: asking zygote to start proc");
4157            final ProcessStartResult startResult;
4158            if (hostingType.equals("webview_service")) {
4159                startResult = startWebView(entryPoint,
4160                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4161                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4162                        app.info.dataDir, null,
4163                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4164            } else {
4165                startResult = Process.start(entryPoint,
4166                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4167                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4168                        app.info.dataDir, invokeWith,
4169                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4170            }
4171            checkTime(startTime, "startProcess: returned from zygote!");
4172            return startResult;
4173        } finally {
4174            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4175        }
4176    }
4177
4178    @GuardedBy("this")
4179    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4180        StringBuilder sb = null;
4181        if (app.killedByAm) {
4182            if (sb == null) sb = new StringBuilder();
4183            sb.append("killedByAm=true;");
4184        }
4185        if (mProcessNames.get(app.processName, app.uid) != app) {
4186            if (sb == null) sb = new StringBuilder();
4187            sb.append("No entry in mProcessNames;");
4188        }
4189        if (!app.pendingStart) {
4190            if (sb == null) sb = new StringBuilder();
4191            sb.append("pendingStart=false;");
4192        }
4193        if (app.startSeq > expectedStartSeq) {
4194            if (sb == null) sb = new StringBuilder();
4195            sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4196        }
4197        return sb == null ? null : sb.toString();
4198    }
4199
4200    @GuardedBy("this")
4201    private boolean handleProcessStartedLocked(ProcessRecord pending,
4202            ProcessStartResult startResult, long expectedStartSeq) {
4203        // Indicates that this process start has been taken care of.
4204        if (mPendingStarts.get(expectedStartSeq) == null) {
4205            if (pending.pid == startResult.pid) {
4206                pending.usingWrapper = startResult.usingWrapper;
4207                // TODO: Update already existing clients of usingWrapper
4208            }
4209            return false;
4210        }
4211        return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4212                expectedStartSeq, false);
4213    }
4214
4215    @GuardedBy("this")
4216    private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4217            long expectedStartSeq, boolean procAttached) {
4218        mPendingStarts.remove(expectedStartSeq);
4219        final String reason = isProcStartValidLocked(app, expectedStartSeq);
4220        if (reason != null) {
4221            Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4222                    + ", " + reason);
4223            app.pendingStart = false;
4224            Process.killProcessQuiet(pid);
4225            Process.killProcessGroup(app.uid, app.pid);
4226            return false;
4227        }
4228        mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4229        checkTime(app.startTime, "startProcess: done updating battery stats");
4230
4231        EventLog.writeEvent(EventLogTags.AM_PROC_START,
4232                UserHandle.getUserId(app.startUid), pid, app.startUid,
4233                app.processName, app.hostingType,
4234                app.hostingNameStr != null ? app.hostingNameStr : "");
4235
4236        try {
4237            AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4238                    app.seInfo, app.info.sourceDir, pid);
4239        } catch (RemoteException ex) {
4240            // Ignore
4241        }
4242
4243        if (app.persistent) {
4244            Watchdog.getInstance().processStarted(app.processName, pid);
4245        }
4246
4247        checkTime(app.startTime, "startProcess: building log message");
4248        StringBuilder buf = mStringBuilder;
4249        buf.setLength(0);
4250        buf.append("Start proc ");
4251        buf.append(pid);
4252        buf.append(':');
4253        buf.append(app.processName);
4254        buf.append('/');
4255        UserHandle.formatUid(buf, app.startUid);
4256        if (app.isolatedEntryPoint != null) {
4257            buf.append(" [");
4258            buf.append(app.isolatedEntryPoint);
4259            buf.append("]");
4260        }
4261        buf.append(" for ");
4262        buf.append(app.hostingType);
4263        if (app.hostingNameStr != null) {
4264            buf.append(" ");
4265            buf.append(app.hostingNameStr);
4266        }
4267        Slog.i(TAG, buf.toString());
4268        app.setPid(pid);
4269        app.usingWrapper = usingWrapper;
4270        app.pendingStart = false;
4271        checkTime(app.startTime, "startProcess: starting to update pids map");
4272        ProcessRecord oldApp;
4273        synchronized (mPidsSelfLocked) {
4274            oldApp = mPidsSelfLocked.get(pid);
4275        }
4276        // If there is already an app occupying that pid that hasn't been cleaned up
4277        if (oldApp != null && !app.isolated) {
4278            // Clean up anything relating to this pid first
4279            Slog.w(TAG, "Reusing pid " + pid
4280                    + " while app is still mapped to it");
4281            cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4282                    true /*replacingPid*/);
4283        }
4284        synchronized (mPidsSelfLocked) {
4285            this.mPidsSelfLocked.put(pid, app);
4286            if (!procAttached) {
4287                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4288                msg.obj = app;
4289                mHandler.sendMessageDelayed(msg, usingWrapper
4290                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4291            }
4292        }
4293        checkTime(app.startTime, "startProcess: done updating pids map");
4294        return true;
4295    }
4296
4297    void updateUsageStats(ActivityRecord component, boolean resumed) {
4298        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4299                "updateUsageStats: comp=" + component + "res=" + resumed);
4300        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4301        StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4302            component.userId, component.realActivity.getPackageName(),
4303            component.realActivity.getShortClassName(), resumed ? 1 : 0);
4304        if (resumed) {
4305            if (mUsageStatsService != null) {
4306                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4307                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4308
4309            }
4310            synchronized (stats) {
4311                stats.noteActivityResumedLocked(component.app.uid);
4312            }
4313        } else {
4314            if (mUsageStatsService != null) {
4315                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4316                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4317            }
4318            synchronized (stats) {
4319                stats.noteActivityPausedLocked(component.app.uid);
4320            }
4321        }
4322    }
4323
4324    Intent getHomeIntent() {
4325        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4326        intent.setComponent(mTopComponent);
4327        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4328        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4329            intent.addCategory(Intent.CATEGORY_HOME);
4330        }
4331        return intent;
4332    }
4333
4334    boolean startHomeActivityLocked(int userId, String reason) {
4335        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4336                && mTopAction == null) {
4337            // We are running in factory test mode, but unable to find
4338            // the factory test app, so just sit around displaying the
4339            // error message and don't try to start anything.
4340            return false;
4341        }
4342        Intent intent = getHomeIntent();
4343        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4344        if (aInfo != null) {
4345            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4346            // Don't do this if the home app is currently being
4347            // instrumented.
4348            aInfo = new ActivityInfo(aInfo);
4349            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4350            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4351                    aInfo.applicationInfo.uid, true);
4352            if (app == null || app.instr == null) {
4353                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4354                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4355                // For ANR debugging to verify if the user activity is the one that actually
4356                // launched.
4357                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4358                mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4359            }
4360        } else {
4361            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4362        }
4363
4364        return true;
4365    }
4366
4367    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4368        ActivityInfo ai = null;
4369        ComponentName comp = intent.getComponent();
4370        try {
4371            if (comp != null) {
4372                // Factory test.
4373                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4374            } else {
4375                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4376                        intent,
4377                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4378                        flags, userId);
4379
4380                if (info != null) {
4381                    ai = info.activityInfo;
4382                }
4383            }
4384        } catch (RemoteException e) {
4385            // ignore
4386        }
4387
4388        return ai;
4389    }
4390
4391    boolean getCheckedForSetup() {
4392        return mCheckedForSetup;
4393    }
4394
4395    void setCheckedForSetup(boolean checked) {
4396        mCheckedForSetup = checked;
4397    }
4398
4399    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4400        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4401    }
4402
4403    void enforceNotIsolatedCaller(String caller) {
4404        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4405            throw new SecurityException("Isolated process not allowed to call " + caller);
4406        }
4407    }
4408
4409    @Override
4410    public int getFrontActivityScreenCompatMode() {
4411        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4412        synchronized (this) {
4413            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4414        }
4415    }
4416
4417    @Override
4418    public void setFrontActivityScreenCompatMode(int mode) {
4419        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4420                "setFrontActivityScreenCompatMode");
4421        synchronized (this) {
4422            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4423        }
4424    }
4425
4426    @Override
4427    public int getPackageScreenCompatMode(String packageName) {
4428        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4429        synchronized (this) {
4430            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4431        }
4432    }
4433
4434    @Override
4435    public void setPackageScreenCompatMode(String packageName, int mode) {
4436        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4437                "setPackageScreenCompatMode");
4438        synchronized (this) {
4439            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4440        }
4441    }
4442
4443    @Override
4444    public boolean getPackageAskScreenCompat(String packageName) {
4445        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4446        synchronized (this) {
4447            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4448        }
4449    }
4450
4451    @Override
4452    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4453        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4454                "setPackageAskScreenCompat");
4455        synchronized (this) {
4456            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4457        }
4458    }
4459
4460    private boolean hasUsageStatsPermission(String callingPackage) {
4461        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4462                Binder.getCallingUid(), callingPackage);
4463        if (mode == AppOpsManager.MODE_DEFAULT) {
4464            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4465                    == PackageManager.PERMISSION_GRANTED;
4466        }
4467        return mode == AppOpsManager.MODE_ALLOWED;
4468    }
4469
4470    @Override
4471    public int getPackageProcessState(String packageName, String callingPackage) {
4472        if (!hasUsageStatsPermission(callingPackage)) {
4473            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4474                    "getPackageProcessState");
4475        }
4476
4477        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4478        synchronized (this) {
4479            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4480                final ProcessRecord proc = mLruProcesses.get(i);
4481                if (procState > proc.setProcState) {
4482                    if (proc.pkgList.containsKey(packageName) ||
4483                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4484                        procState = proc.setProcState;
4485                    }
4486                }
4487            }
4488        }
4489        return procState;
4490    }
4491
4492    @Override
4493    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4494            throws RemoteException {
4495        synchronized (this) {
4496            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4497            if (app == null) {
4498                throw new IllegalArgumentException("Unknown process: " + process);
4499            }
4500            if (app.thread == null) {
4501                throw new IllegalArgumentException("Process has no app thread");
4502            }
4503            if (app.trimMemoryLevel >= level) {
4504                throw new IllegalArgumentException(
4505                        "Unable to set a higher trim level than current level");
4506            }
4507            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4508                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4509                throw new IllegalArgumentException("Unable to set a background trim level "
4510                    + "on a foreground process");
4511            }
4512            app.thread.scheduleTrimMemory(level);
4513            app.trimMemoryLevel = level;
4514            return true;
4515        }
4516    }
4517
4518    private void dispatchProcessesChanged() {
4519        int N;
4520        synchronized (this) {
4521            N = mPendingProcessChanges.size();
4522            if (mActiveProcessChanges.length < N) {
4523                mActiveProcessChanges = new ProcessChangeItem[N];
4524            }
4525            mPendingProcessChanges.toArray(mActiveProcessChanges);
4526            mPendingProcessChanges.clear();
4527            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4528                    "*** Delivering " + N + " process changes");
4529        }
4530
4531        int i = mProcessObservers.beginBroadcast();
4532        while (i > 0) {
4533            i--;
4534            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4535            if (observer != null) {
4536                try {
4537                    for (int j=0; j<N; j++) {
4538                        ProcessChangeItem item = mActiveProcessChanges[j];
4539                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4540                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4541                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4542                                    + item.uid + ": " + item.foregroundActivities);
4543                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4544                                    item.foregroundActivities);
4545                        }
4546                    }
4547                } catch (RemoteException e) {
4548                }
4549            }
4550        }
4551        mProcessObservers.finishBroadcast();
4552
4553        synchronized (this) {
4554            for (int j=0; j<N; j++) {
4555                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4556            }
4557        }
4558    }
4559
4560    private void dispatchProcessDied(int pid, int uid) {
4561        int i = mProcessObservers.beginBroadcast();
4562        while (i > 0) {
4563            i--;
4564            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4565            if (observer != null) {
4566                try {
4567                    observer.onProcessDied(pid, uid);
4568                } catch (RemoteException e) {
4569                }
4570            }
4571        }
4572        mProcessObservers.finishBroadcast();
4573    }
4574
4575    @VisibleForTesting
4576    void dispatchUidsChanged() {
4577        int N;
4578        synchronized (this) {
4579            N = mPendingUidChanges.size();
4580            if (mActiveUidChanges.length < N) {
4581                mActiveUidChanges = new UidRecord.ChangeItem[N];
4582            }
4583            for (int i=0; i<N; i++) {
4584                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4585                mActiveUidChanges[i] = change;
4586                if (change.uidRecord != null) {
4587                    change.uidRecord.pendingChange = null;
4588                    change.uidRecord = null;
4589                }
4590            }
4591            mPendingUidChanges.clear();
4592            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4593                    "*** Delivering " + N + " uid changes");
4594        }
4595
4596        int i = mUidObservers.beginBroadcast();
4597        while (i > 0) {
4598            i--;
4599            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4600                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4601        }
4602        mUidObservers.finishBroadcast();
4603
4604        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4605            for (int j = 0; j < N; ++j) {
4606                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4607                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4608                    mValidateUids.remove(item.uid);
4609                } else {
4610                    UidRecord validateUid = mValidateUids.get(item.uid);
4611                    if (validateUid == null) {
4612                        validateUid = new UidRecord(item.uid);
4613                        mValidateUids.put(item.uid, validateUid);
4614                    }
4615                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4616                        validateUid.idle = true;
4617                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4618                        validateUid.idle = false;
4619                    }
4620                    validateUid.curProcState = validateUid.setProcState = item.processState;
4621                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4622                }
4623            }
4624        }
4625
4626        synchronized (this) {
4627            for (int j = 0; j < N; j++) {
4628                mAvailUidChanges.add(mActiveUidChanges[j]);
4629            }
4630        }
4631    }
4632
4633    private void dispatchUidsChangedForObserver(IUidObserver observer,
4634            UidObserverRegistration reg, int changesSize) {
4635        if (observer == null) {
4636            return;
4637        }
4638        try {
4639            for (int j = 0; j < changesSize; j++) {
4640                UidRecord.ChangeItem item = mActiveUidChanges[j];
4641                final int change = item.change;
4642                if (change == UidRecord.CHANGE_PROCSTATE &&
4643                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4644                    // No-op common case: no significant change, the observer is not
4645                    // interested in all proc state changes.
4646                    continue;
4647                }
4648                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4649                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4650                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4651                                "UID idle uid=" + item.uid);
4652                        observer.onUidIdle(item.uid, item.ephemeral);
4653                    }
4654                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4655                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4656                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4657                                "UID active uid=" + item.uid);
4658                        observer.onUidActive(item.uid);
4659                    }
4660                }
4661                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4662                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4663                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4664                                "UID cached uid=" + item.uid);
4665                        observer.onUidCachedChanged(item.uid, true);
4666                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4667                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4668                                "UID active uid=" + item.uid);
4669                        observer.onUidCachedChanged(item.uid, false);
4670                    }
4671                }
4672                if ((change & UidRecord.CHANGE_GONE) != 0) {
4673                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4674                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4675                                "UID gone uid=" + item.uid);
4676                        observer.onUidGone(item.uid, item.ephemeral);
4677                    }
4678                    if (reg.lastProcStates != null) {
4679                        reg.lastProcStates.delete(item.uid);
4680                    }
4681                } else {
4682                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4683                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4684                                "UID CHANGED uid=" + item.uid
4685                                        + ": " + item.processState);
4686                        boolean doReport = true;
4687                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4688                            final int lastState = reg.lastProcStates.get(item.uid,
4689                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4690                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4691                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4692                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4693                                doReport = lastAboveCut != newAboveCut;
4694                            } else {
4695                                doReport = item.processState
4696                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4697                            }
4698                        }
4699                        if (doReport) {
4700                            if (reg.lastProcStates != null) {
4701                                reg.lastProcStates.put(item.uid, item.processState);
4702                            }
4703                            observer.onUidStateChanged(item.uid, item.processState,
4704                                    item.procStateSeq);
4705                        }
4706                    }
4707                }
4708            }
4709        } catch (RemoteException e) {
4710        }
4711    }
4712
4713    void dispatchOomAdjObserver(String msg) {
4714        OomAdjObserver observer;
4715        synchronized (this) {
4716            observer = mCurOomAdjObserver;
4717        }
4718
4719        if (observer != null) {
4720            observer.onOomAdjMessage(msg);
4721        }
4722    }
4723
4724    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4725        synchronized (this) {
4726            mCurOomAdjUid = uid;
4727            mCurOomAdjObserver = observer;
4728        }
4729    }
4730
4731    void clearOomAdjObserver() {
4732        synchronized (this) {
4733            mCurOomAdjUid = -1;
4734            mCurOomAdjObserver = null;
4735        }
4736    }
4737
4738    void reportOomAdjMessageLocked(String tag, String msg) {
4739        Slog.d(tag, msg);
4740        if (mCurOomAdjObserver != null) {
4741            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4742        }
4743    }
4744
4745    @Override
4746    public final int startActivity(IApplicationThread caller, String callingPackage,
4747            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4748            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4749        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4750                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4751                UserHandle.getCallingUserId());
4752    }
4753
4754    @Override
4755    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4756            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4757            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4758        enforceNotIsolatedCaller("startActivity");
4759        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4760                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4761        // TODO: Switch to user app stacks here.
4762        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
4763                .setCaller(caller)
4764                .setCallingPackage(callingPackage)
4765                .setResolvedType(resolvedType)
4766                .setResultTo(resultTo)
4767                .setResultWho(resultWho)
4768                .setRequestCode(requestCode)
4769                .setStartFlags(startFlags)
4770                .setProfilerInfo(profilerInfo)
4771                .setActivityOptions(bOptions)
4772                .setMayWait(userId)
4773                .execute();
4774
4775    }
4776
4777    @Override
4778    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4779            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4780            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4781            int userId) {
4782
4783        // This is very dangerous -- it allows you to perform a start activity (including
4784        // permission grants) as any app that may launch one of your own activities.  So
4785        // we will only allow this to be done from activities that are part of the core framework,
4786        // and then only when they are running as the system.
4787        final ActivityRecord sourceRecord;
4788        final int targetUid;
4789        final String targetPackage;
4790        synchronized (this) {
4791            if (resultTo == null) {
4792                throw new SecurityException("Must be called from an activity");
4793            }
4794            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4795            if (sourceRecord == null) {
4796                throw new SecurityException("Called with bad activity token: " + resultTo);
4797            }
4798            if (!sourceRecord.info.packageName.equals("android")) {
4799                throw new SecurityException(
4800                        "Must be called from an activity that is declared in the android package");
4801            }
4802            if (sourceRecord.app == null) {
4803                throw new SecurityException("Called without a process attached to activity");
4804            }
4805            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4806                // This is still okay, as long as this activity is running under the
4807                // uid of the original calling activity.
4808                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4809                    throw new SecurityException(
4810                            "Calling activity in uid " + sourceRecord.app.uid
4811                                    + " must be system uid or original calling uid "
4812                                    + sourceRecord.launchedFromUid);
4813                }
4814            }
4815            if (ignoreTargetSecurity) {
4816                if (intent.getComponent() == null) {
4817                    throw new SecurityException(
4818                            "Component must be specified with ignoreTargetSecurity");
4819                }
4820                if (intent.getSelector() != null) {
4821                    throw new SecurityException(
4822                            "Selector not allowed with ignoreTargetSecurity");
4823                }
4824            }
4825            targetUid = sourceRecord.launchedFromUid;
4826            targetPackage = sourceRecord.launchedFromPackage;
4827        }
4828
4829        if (userId == UserHandle.USER_NULL) {
4830            userId = UserHandle.getUserId(sourceRecord.app.uid);
4831        }
4832
4833        // TODO: Switch to user app stacks here.
4834        try {
4835            return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
4836                    .setCallingUid(targetUid)
4837                    .setCallingPackage(targetPackage)
4838                    .setResolvedType(resolvedType)
4839                    .setResultTo(resultTo)
4840                    .setResultWho(resultWho)
4841                    .setRequestCode(requestCode)
4842                    .setStartFlags(startFlags)
4843                    .setActivityOptions(bOptions)
4844                    .setMayWait(userId)
4845                    .setIgnoreTargetSecurity(ignoreTargetSecurity)
4846                    .execute();
4847        } catch (SecurityException e) {
4848            // XXX need to figure out how to propagate to original app.
4849            // A SecurityException here is generally actually a fault of the original
4850            // calling activity (such as a fairly granting permissions), so propagate it
4851            // back to them.
4852            /*
4853            StringBuilder msg = new StringBuilder();
4854            msg.append("While launching");
4855            msg.append(intent.toString());
4856            msg.append(": ");
4857            msg.append(e.getMessage());
4858            */
4859            throw e;
4860        }
4861    }
4862
4863    @Override
4864    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4865            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4866            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4867        enforceNotIsolatedCaller("startActivityAndWait");
4868        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4869                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4870        WaitResult res = new WaitResult();
4871        // TODO: Switch to user app stacks here.
4872        mActivityStartController.obtainStarter(intent, "startActivityAndWait")
4873                .setCaller(caller)
4874                .setCallingPackage(callingPackage)
4875                .setResolvedType(resolvedType)
4876                .setResultTo(resultTo)
4877                .setResultWho(resultWho)
4878                .setRequestCode(requestCode)
4879                .setStartFlags(startFlags)
4880                .setActivityOptions(bOptions)
4881                .setMayWait(userId)
4882                .setProfilerInfo(profilerInfo)
4883                .setWaitResult(res)
4884                .execute();
4885        return res;
4886    }
4887
4888    @Override
4889    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4890            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4891            int startFlags, Configuration config, Bundle bOptions, int userId) {
4892        enforceNotIsolatedCaller("startActivityWithConfig");
4893        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4894                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4895        // TODO: Switch to user app stacks here.
4896        return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
4897                .setCaller(caller)
4898                .setCallingPackage(callingPackage)
4899                .setResolvedType(resolvedType)
4900                .setResultTo(resultTo)
4901                .setResultWho(resultWho)
4902                .setRequestCode(requestCode)
4903                .setStartFlags(startFlags)
4904                .setGlobalConfiguration(config)
4905                .setActivityOptions(bOptions)
4906                .setMayWait(userId)
4907                .execute();
4908    }
4909
4910    @Override
4911    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4912            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4913            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4914            throws TransactionTooLargeException {
4915        enforceNotIsolatedCaller("startActivityIntentSender");
4916        // Refuse possible leaked file descriptors
4917        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4918            throw new IllegalArgumentException("File descriptors passed in Intent");
4919        }
4920
4921        if (!(target instanceof PendingIntentRecord)) {
4922            throw new IllegalArgumentException("Bad PendingIntent object");
4923        }
4924
4925        PendingIntentRecord pir = (PendingIntentRecord)target;
4926
4927        synchronized (this) {
4928            // If this is coming from the currently resumed activity, it is
4929            // effectively saying that app switches are allowed at this point.
4930            final ActivityStack stack = getFocusedStack();
4931            if (stack.mResumedActivity != null &&
4932                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4933                mAppSwitchesAllowedTime = 0;
4934            }
4935        }
4936        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4937                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4938        return ret;
4939    }
4940
4941    @Override
4942    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4943            Intent intent, String resolvedType, IVoiceInteractionSession session,
4944            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4945            Bundle bOptions, int userId) {
4946        enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
4947        if (session == null || interactor == null) {
4948            throw new NullPointerException("null session or interactor");
4949        }
4950        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4951                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4952        // TODO: Switch to user app stacks here.
4953        return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
4954                .setCallingUid(callingUid)
4955                .setCallingPackage(callingPackage)
4956                .setResolvedType(resolvedType)
4957                .setVoiceSession(session)
4958                .setVoiceInteractor(interactor)
4959                .setStartFlags(startFlags)
4960                .setProfilerInfo(profilerInfo)
4961                .setActivityOptions(bOptions)
4962                .setMayWait(userId)
4963                .execute();
4964    }
4965
4966    @Override
4967    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4968            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4969        enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
4970        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4971                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4972
4973        return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
4974                .setCallingUid(callingUid)
4975                .setCallingPackage(callingPackage)
4976                .setResolvedType(resolvedType)
4977                .setActivityOptions(bOptions)
4978                .setMayWait(userId)
4979                .execute();
4980    }
4981
4982    @Override
4983    public int startRecentsActivity(IAssistDataReceiver assistDataReceiver, Bundle options,
4984            Bundle activityOptions, int userId) {
4985        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
4986            String msg = "Permission Denial: startRecentsActivity() from pid="
4987                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
4988                    + " not recent tasks package";
4989            Slog.w(TAG, msg);
4990            throw new SecurityException(msg);
4991        }
4992
4993        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
4994        final int recentsUid = mRecentTasks.getRecentsComponentUid();
4995        final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
4996        final String recentsPackage = recentsComponent.getPackageName();
4997        final long origId = Binder.clearCallingIdentity();
4998        try {
4999            synchronized (this) {
5000                // If provided, kick off the request for the assist data in the background before
5001                // starting the activity
5002                if (assistDataReceiver != null) {
5003                    final AppOpsManager appOpsManager = (AppOpsManager)
5004                            mContext.getSystemService(Context.APP_OPS_SERVICE);
5005                    final AssistDataReceiverProxy proxy = new AssistDataReceiverProxy(
5006                            assistDataReceiver, recentsPackage);
5007                    final AssistDataRequester requester = new AssistDataRequester(mContext, this,
5008                            mWindowManager, appOpsManager, proxy, this,
5009                            OP_ASSIST_STRUCTURE, OP_NONE);
5010                    requester.requestAssistData(mStackSupervisor.getTopVisibleActivities(),
5011                            true /* fetchData */, false /* fetchScreenshots */,
5012                            true /* allowFetchData */, false /* alloweFetchScreenshots */,
5013                            recentsUid, recentsPackage);
5014                }
5015
5016                final Intent intent = new Intent();
5017                intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
5018                intent.setComponent(recentsComponent);
5019                intent.putExtras(options);
5020
5021                return mActivityStartController.obtainStarter(intent, "startRecentsActivity")
5022                        .setCallingUid(recentsUid)
5023                        .setCallingPackage(recentsPackage)
5024                        .setActivityOptions(safeOptions)
5025                        .setMayWait(userId)
5026                        .execute();
5027            }
5028        } finally {
5029            Binder.restoreCallingIdentity(origId);
5030        }
5031    }
5032
5033    @Override
5034    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
5035            throws RemoteException {
5036        Slog.i(TAG, "Activity tried to startVoiceInteraction");
5037        synchronized (this) {
5038            ActivityRecord activity = getFocusedStack().getTopActivity();
5039            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
5040                throw new SecurityException("Only focused activity can call startVoiceInteraction");
5041            }
5042            if (mRunningVoice != null || activity.getTask().voiceSession != null
5043                    || activity.voiceSession != null) {
5044                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
5045                return;
5046            }
5047            if (activity.pendingVoiceInteractionStart) {
5048                Slog.w(TAG, "Pending start of voice interaction already.");
5049                return;
5050            }
5051            activity.pendingVoiceInteractionStart = true;
5052        }
5053        LocalServices.getService(VoiceInteractionManagerInternal.class)
5054                .startLocalVoiceInteraction(callingActivity, options);
5055    }
5056
5057    @Override
5058    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5059        LocalServices.getService(VoiceInteractionManagerInternal.class)
5060                .stopLocalVoiceInteraction(callingActivity);
5061    }
5062
5063    @Override
5064    public boolean supportsLocalVoiceInteraction() throws RemoteException {
5065        return LocalServices.getService(VoiceInteractionManagerInternal.class)
5066                .supportsLocalVoiceInteraction();
5067    }
5068
5069    void onLocalVoiceInteractionStartedLocked(IBinder activity,
5070            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5071        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
5072        if (activityToCallback == null) return;
5073        activityToCallback.setVoiceSessionLocked(voiceSession);
5074
5075        // Inform the activity
5076        try {
5077            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5078                    voiceInteractor);
5079            long token = Binder.clearCallingIdentity();
5080            try {
5081                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5082            } finally {
5083                Binder.restoreCallingIdentity(token);
5084            }
5085            // TODO: VI Should we cache the activity so that it's easier to find later
5086            // rather than scan through all the stacks and activities?
5087        } catch (RemoteException re) {
5088            activityToCallback.clearVoiceSessionLocked();
5089            // TODO: VI Should this terminate the voice session?
5090        }
5091    }
5092
5093    @Override
5094    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5095        synchronized (this) {
5096            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5097                if (keepAwake) {
5098                    mVoiceWakeLock.acquire();
5099                } else {
5100                    mVoiceWakeLock.release();
5101                }
5102            }
5103        }
5104    }
5105
5106    @Override
5107    public boolean startNextMatchingActivity(IBinder callingActivity,
5108            Intent intent, Bundle bOptions) {
5109        // Refuse possible leaked file descriptors
5110        if (intent != null && intent.hasFileDescriptors() == true) {
5111            throw new IllegalArgumentException("File descriptors passed in Intent");
5112        }
5113        SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5114
5115        synchronized (this) {
5116            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5117            if (r == null) {
5118                SafeActivityOptions.abort(options);
5119                return false;
5120            }
5121            if (r.app == null || r.app.thread == null) {
5122                // The caller is not running...  d'oh!
5123                SafeActivityOptions.abort(options);
5124                return false;
5125            }
5126            intent = new Intent(intent);
5127            // The caller is not allowed to change the data.
5128            intent.setDataAndType(r.intent.getData(), r.intent.getType());
5129            // And we are resetting to find the next component...
5130            intent.setComponent(null);
5131
5132            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5133
5134            ActivityInfo aInfo = null;
5135            try {
5136                List<ResolveInfo> resolves =
5137                    AppGlobals.getPackageManager().queryIntentActivities(
5138                            intent, r.resolvedType,
5139                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5140                            UserHandle.getCallingUserId()).getList();
5141
5142                // Look for the original activity in the list...
5143                final int N = resolves != null ? resolves.size() : 0;
5144                for (int i=0; i<N; i++) {
5145                    ResolveInfo rInfo = resolves.get(i);
5146                    if (rInfo.activityInfo.packageName.equals(r.packageName)
5147                            && rInfo.activityInfo.name.equals(r.info.name)) {
5148                        // We found the current one...  the next matching is
5149                        // after it.
5150                        i++;
5151                        if (i<N) {
5152                            aInfo = resolves.get(i).activityInfo;
5153                        }
5154                        if (debug) {
5155                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
5156                                    + "/" + r.info.name);
5157                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5158                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
5159                        }
5160                        break;
5161                    }
5162                }
5163            } catch (RemoteException e) {
5164            }
5165
5166            if (aInfo == null) {
5167                // Nobody who is next!
5168                SafeActivityOptions.abort(options);
5169                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5170                return false;
5171            }
5172
5173            intent.setComponent(new ComponentName(
5174                    aInfo.applicationInfo.packageName, aInfo.name));
5175            intent.setFlags(intent.getFlags()&~(
5176                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5177                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
5178                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5179                    FLAG_ACTIVITY_NEW_TASK));
5180
5181            // Okay now we need to start the new activity, replacing the
5182            // currently running activity.  This is a little tricky because
5183            // we want to start the new one as if the current one is finished,
5184            // but not finish the current one first so that there is no flicker.
5185            // And thus...
5186            final boolean wasFinishing = r.finishing;
5187            r.finishing = true;
5188
5189            // Propagate reply information over to the new activity.
5190            final ActivityRecord resultTo = r.resultTo;
5191            final String resultWho = r.resultWho;
5192            final int requestCode = r.requestCode;
5193            r.resultTo = null;
5194            if (resultTo != null) {
5195                resultTo.removeResultsLocked(r, resultWho, requestCode);
5196            }
5197
5198            final long origId = Binder.clearCallingIdentity();
5199            // TODO(b/64750076): Check if calling pid should really be -1.
5200            final int res = mActivityStartController
5201                    .obtainStarter(intent, "startNextMatchingActivity")
5202                    .setCaller(r.app.thread)
5203                    .setResolvedType(r.resolvedType)
5204                    .setActivityInfo(aInfo)
5205                    .setResultTo(resultTo != null ? resultTo.appToken : null)
5206                    .setResultWho(resultWho)
5207                    .setRequestCode(requestCode)
5208                    .setCallingPid(-1)
5209                    .setCallingUid(r.launchedFromUid)
5210                    .setCallingPackage(r.launchedFromPackage)
5211                    .setRealCallingPid(-1)
5212                    .setRealCallingUid(r.launchedFromUid)
5213                    .setActivityOptions(options)
5214                    .execute();
5215            Binder.restoreCallingIdentity(origId);
5216
5217            r.finishing = wasFinishing;
5218            if (res != ActivityManager.START_SUCCESS) {
5219                return false;
5220            }
5221            return true;
5222        }
5223    }
5224
5225    @Override
5226    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5227        enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5228                "startActivityFromRecents()");
5229
5230        final int callingPid = Binder.getCallingPid();
5231        final int callingUid = Binder.getCallingUid();
5232        final long origId = Binder.clearCallingIdentity();
5233        try {
5234            synchronized (this) {
5235                return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5236                        SafeActivityOptions.fromBundle(bOptions));
5237            }
5238        } finally {
5239            Binder.restoreCallingIdentity(origId);
5240        }
5241    }
5242
5243    @Override
5244    public final int startActivities(IApplicationThread caller, String callingPackage,
5245            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5246            int userId) {
5247        final String reason = "startActivities";
5248        enforceNotIsolatedCaller(reason);
5249        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5250                userId, false, ALLOW_FULL_ONLY, reason, null);
5251        // TODO: Switch to user app stacks here.
5252        int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
5253                intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
5254                reason);
5255        return ret;
5256    }
5257
5258    @Override
5259    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5260        synchronized (this) {
5261            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5262            if (r == null) {
5263                return;
5264            }
5265            r.reportFullyDrawnLocked(restoredFromBundle);
5266        }
5267    }
5268
5269    @Override
5270    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5271        synchronized (this) {
5272            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5273            if (r == null) {
5274                return;
5275            }
5276            final long origId = Binder.clearCallingIdentity();
5277            try {
5278                r.setRequestedOrientation(requestedOrientation);
5279            } finally {
5280                Binder.restoreCallingIdentity(origId);
5281            }
5282        }
5283    }
5284
5285    @Override
5286    public int getRequestedOrientation(IBinder token) {
5287        synchronized (this) {
5288            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5289            if (r == null) {
5290                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5291            }
5292            return r.getRequestedOrientation();
5293        }
5294    }
5295
5296    @Override
5297    public final void requestActivityRelaunch(IBinder token) {
5298        synchronized(this) {
5299            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5300            if (r == null) {
5301                return;
5302            }
5303            final long origId = Binder.clearCallingIdentity();
5304            try {
5305                r.forceNewConfig = true;
5306                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5307                        true /* preserveWindow */);
5308            } finally {
5309                Binder.restoreCallingIdentity(origId);
5310            }
5311        }
5312    }
5313
5314    /**
5315     * This is the internal entry point for handling Activity.finish().
5316     *
5317     * @param token The Binder token referencing the Activity we want to finish.
5318     * @param resultCode Result code, if any, from this Activity.
5319     * @param resultData Result data (Intent), if any, from this Activity.
5320     * @param finishTask Whether to finish the task associated with this Activity.
5321     *
5322     * @return Returns true if the activity successfully finished, or false if it is still running.
5323     */
5324    @Override
5325    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5326            int finishTask) {
5327        // Refuse possible leaked file descriptors
5328        if (resultData != null && resultData.hasFileDescriptors() == true) {
5329            throw new IllegalArgumentException("File descriptors passed in Intent");
5330        }
5331
5332        synchronized(this) {
5333            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5334            if (r == null) {
5335                return true;
5336            }
5337            // Keep track of the root activity of the task before we finish it
5338            TaskRecord tr = r.getTask();
5339            ActivityRecord rootR = tr.getRootActivity();
5340            if (rootR == null) {
5341                Slog.w(TAG, "Finishing task with all activities already finished");
5342            }
5343            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5344            // finish.
5345            if (mLockTaskController.activityBlockedFromFinish(r)) {
5346                return false;
5347            }
5348
5349            if (mController != null) {
5350                // Find the first activity that is not finishing.
5351                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5352                if (next != null) {
5353                    // ask watcher if this is allowed
5354                    boolean resumeOK = true;
5355                    try {
5356                        resumeOK = mController.activityResuming(next.packageName);
5357                    } catch (RemoteException e) {
5358                        mController = null;
5359                        Watchdog.getInstance().setActivityController(null);
5360                    }
5361
5362                    if (!resumeOK) {
5363                        Slog.i(TAG, "Not finishing activity because controller resumed");
5364                        return false;
5365                    }
5366                }
5367            }
5368            final long origId = Binder.clearCallingIdentity();
5369            try {
5370                boolean res;
5371                final boolean finishWithRootActivity =
5372                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5373                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5374                        || (finishWithRootActivity && r == rootR)) {
5375                    // If requested, remove the task that is associated to this activity only if it
5376                    // was the root activity in the task. The result code and data is ignored
5377                    // because we don't support returning them across task boundaries. Also, to
5378                    // keep backwards compatibility we remove the task from recents when finishing
5379                    // task with root activity.
5380                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5381                            finishWithRootActivity, "finish-activity");
5382                    if (!res) {
5383                        Slog.i(TAG, "Removing task failed to finish activity");
5384                    }
5385                } else {
5386                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5387                            resultData, "app-request", true);
5388                    if (!res) {
5389                        Slog.i(TAG, "Failed to finish by app-request");
5390                    }
5391                }
5392                return res;
5393            } finally {
5394                Binder.restoreCallingIdentity(origId);
5395            }
5396        }
5397    }
5398
5399    @Override
5400    public final void finishHeavyWeightApp() {
5401        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5402                != PackageManager.PERMISSION_GRANTED) {
5403            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5404                    + Binder.getCallingPid()
5405                    + ", uid=" + Binder.getCallingUid()
5406                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5407            Slog.w(TAG, msg);
5408            throw new SecurityException(msg);
5409        }
5410
5411        synchronized(this) {
5412            final ProcessRecord proc = mHeavyWeightProcess;
5413            if (proc == null) {
5414                return;
5415            }
5416
5417            ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5418            for (int i = 0; i < activities.size(); i++) {
5419                ActivityRecord r = activities.get(i);
5420                if (!r.finishing && r.isInStackLocked()) {
5421                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5422                            null, "finish-heavy", true);
5423                }
5424            }
5425
5426            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5427                    proc.userId, 0));
5428            mHeavyWeightProcess = null;
5429        }
5430    }
5431
5432    @Override
5433    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5434            String message) {
5435        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5436                != PackageManager.PERMISSION_GRANTED) {
5437            String msg = "Permission Denial: crashApplication() from pid="
5438                    + Binder.getCallingPid()
5439                    + ", uid=" + Binder.getCallingUid()
5440                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5441            Slog.w(TAG, msg);
5442            throw new SecurityException(msg);
5443        }
5444
5445        synchronized(this) {
5446            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5447        }
5448    }
5449
5450    @Override
5451    public final void finishSubActivity(IBinder token, String resultWho,
5452            int requestCode) {
5453        synchronized(this) {
5454            final long origId = Binder.clearCallingIdentity();
5455            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5456            if (r != null) {
5457                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5458            }
5459            Binder.restoreCallingIdentity(origId);
5460        }
5461    }
5462
5463    @Override
5464    public boolean finishActivityAffinity(IBinder token) {
5465        synchronized(this) {
5466            final long origId = Binder.clearCallingIdentity();
5467            try {
5468                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5469                if (r == null) {
5470                    return false;
5471                }
5472
5473                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5474                // can finish.
5475                final TaskRecord task = r.getTask();
5476                if (mLockTaskController.activityBlockedFromFinish(r)) {
5477                    return false;
5478                }
5479                return task.getStack().finishActivityAffinityLocked(r);
5480            } finally {
5481                Binder.restoreCallingIdentity(origId);
5482            }
5483        }
5484    }
5485
5486    @Override
5487    public void finishVoiceTask(IVoiceInteractionSession session) {
5488        synchronized (this) {
5489            final long origId = Binder.clearCallingIdentity();
5490            try {
5491                // TODO: VI Consider treating local voice interactions and voice tasks
5492                // differently here
5493                mStackSupervisor.finishVoiceTask(session);
5494            } finally {
5495                Binder.restoreCallingIdentity(origId);
5496            }
5497        }
5498
5499    }
5500
5501    @Override
5502    public boolean releaseActivityInstance(IBinder token) {
5503        synchronized(this) {
5504            final long origId = Binder.clearCallingIdentity();
5505            try {
5506                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5507                if (r == null) {
5508                    return false;
5509                }
5510                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5511            } finally {
5512                Binder.restoreCallingIdentity(origId);
5513            }
5514        }
5515    }
5516
5517    @Override
5518    public void releaseSomeActivities(IApplicationThread appInt) {
5519        synchronized(this) {
5520            final long origId = Binder.clearCallingIdentity();
5521            try {
5522                ProcessRecord app = getRecordForAppLocked(appInt);
5523                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5524            } finally {
5525                Binder.restoreCallingIdentity(origId);
5526            }
5527        }
5528    }
5529
5530    @Override
5531    public boolean willActivityBeVisible(IBinder token) {
5532        synchronized(this) {
5533            ActivityStack stack = ActivityRecord.getStackLocked(token);
5534            if (stack != null) {
5535                return stack.willActivityBeVisibleLocked(token);
5536            }
5537            return false;
5538        }
5539    }
5540
5541    @Override
5542    public void overridePendingTransition(IBinder token, String packageName,
5543            int enterAnim, int exitAnim) {
5544        synchronized(this) {
5545            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5546            if (self == null) {
5547                return;
5548            }
5549
5550            final long origId = Binder.clearCallingIdentity();
5551
5552            if (self.state == ActivityState.RESUMED
5553                    || self.state == ActivityState.PAUSING) {
5554                mWindowManager.overridePendingAppTransition(packageName,
5555                        enterAnim, exitAnim, null);
5556            }
5557
5558            Binder.restoreCallingIdentity(origId);
5559        }
5560    }
5561
5562    /**
5563     * Main function for removing an existing process from the activity manager
5564     * as a result of that process going away.  Clears out all connections
5565     * to the process.
5566     */
5567    private final void handleAppDiedLocked(ProcessRecord app,
5568            boolean restarting, boolean allowRestart) {
5569        int pid = app.pid;
5570        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5571                false /*replacingPid*/);
5572        if (!kept && !restarting) {
5573            removeLruProcessLocked(app);
5574            if (pid > 0) {
5575                ProcessList.remove(pid);
5576            }
5577        }
5578
5579        if (mProfileProc == app) {
5580            clearProfilerLocked();
5581        }
5582
5583        // Remove this application's activities from active lists.
5584        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5585
5586        app.clearRecentTasks();
5587
5588        app.activities.clear();
5589
5590        if (app.instr != null) {
5591            Slog.w(TAG, "Crash of app " + app.processName
5592                  + " running instrumentation " + app.instr.mClass);
5593            Bundle info = new Bundle();
5594            info.putString("shortMsg", "Process crashed.");
5595            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5596        }
5597
5598        mWindowManager.deferSurfaceLayout();
5599        try {
5600            if (!restarting && hasVisibleActivities
5601                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5602                // If there was nothing to resume, and we are not already restarting this process, but
5603                // there is a visible activity that is hosted by the process...  then make sure all
5604                // visible activities are running, taking care of restarting this process.
5605                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5606            }
5607        } finally {
5608            mWindowManager.continueSurfaceLayout();
5609        }
5610    }
5611
5612    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5613        final IBinder threadBinder = thread.asBinder();
5614        // Find the application record.
5615        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5616            final ProcessRecord rec = mLruProcesses.get(i);
5617            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5618                return i;
5619            }
5620        }
5621        return -1;
5622    }
5623
5624    ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5625        if (thread == null) {
5626            return null;
5627        }
5628
5629        int appIndex = getLRURecordIndexForAppLocked(thread);
5630        if (appIndex >= 0) {
5631            return mLruProcesses.get(appIndex);
5632        }
5633
5634        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5635        // double-check that.
5636        final IBinder threadBinder = thread.asBinder();
5637        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5638        for (int i = pmap.size()-1; i >= 0; i--) {
5639            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5640            for (int j = procs.size()-1; j >= 0; j--) {
5641                final ProcessRecord proc = procs.valueAt(j);
5642                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5643                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5644                            + proc);
5645                    return proc;
5646                }
5647            }
5648        }
5649
5650        return null;
5651    }
5652
5653    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5654        // If there are no longer any background processes running,
5655        // and the app that died was not running instrumentation,
5656        // then tell everyone we are now low on memory.
5657        boolean haveBg = false;
5658        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5659            ProcessRecord rec = mLruProcesses.get(i);
5660            if (rec.thread != null
5661                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5662                haveBg = true;
5663                break;
5664            }
5665        }
5666
5667        if (!haveBg) {
5668            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5669            if (doReport) {
5670                long now = SystemClock.uptimeMillis();
5671                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5672                    doReport = false;
5673                } else {
5674                    mLastMemUsageReportTime = now;
5675                }
5676            }
5677            final ArrayList<ProcessMemInfo> memInfos
5678                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5679            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5680            long now = SystemClock.uptimeMillis();
5681            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5682                ProcessRecord rec = mLruProcesses.get(i);
5683                if (rec == dyingProc || rec.thread == null) {
5684                    continue;
5685                }
5686                if (doReport) {
5687                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5688                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5689                }
5690                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5691                    // The low memory report is overriding any current
5692                    // state for a GC request.  Make sure to do
5693                    // heavy/important/visible/foreground processes first.
5694                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5695                        rec.lastRequestedGc = 0;
5696                    } else {
5697                        rec.lastRequestedGc = rec.lastLowMemory;
5698                    }
5699                    rec.reportLowMemory = true;
5700                    rec.lastLowMemory = now;
5701                    mProcessesToGc.remove(rec);
5702                    addProcessToGcListLocked(rec);
5703                }
5704            }
5705            if (doReport) {
5706                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5707                mHandler.sendMessage(msg);
5708            }
5709            scheduleAppGcsLocked();
5710        }
5711    }
5712
5713    final void appDiedLocked(ProcessRecord app) {
5714       appDiedLocked(app, app.pid, app.thread, false);
5715    }
5716
5717    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5718            boolean fromBinderDied) {
5719        // First check if this ProcessRecord is actually active for the pid.
5720        synchronized (mPidsSelfLocked) {
5721            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5722            if (curProc != app) {
5723                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5724                return;
5725            }
5726        }
5727
5728        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5729        synchronized (stats) {
5730            stats.noteProcessDiedLocked(app.info.uid, pid);
5731        }
5732
5733        if (!app.killed) {
5734            if (!fromBinderDied) {
5735                killProcessQuiet(pid);
5736            }
5737            killProcessGroup(app.uid, pid);
5738            app.killed = true;
5739        }
5740
5741        // Clean up already done if the process has been re-started.
5742        if (app.pid == pid && app.thread != null &&
5743                app.thread.asBinder() == thread.asBinder()) {
5744            boolean doLowMem = app.instr == null;
5745            boolean doOomAdj = doLowMem;
5746            if (!app.killedByAm) {
5747                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5748                        + ProcessList.makeOomAdjString(app.setAdj)
5749                        + ProcessList.makeProcStateString(app.setProcState));
5750                mAllowLowerMemLevel = true;
5751            } else {
5752                // Note that we always want to do oom adj to update our state with the
5753                // new number of procs.
5754                mAllowLowerMemLevel = false;
5755                doLowMem = false;
5756            }
5757            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5758                    app.setAdj, app.setProcState);
5759            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5760                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5761            handleAppDiedLocked(app, false, true);
5762
5763            if (doOomAdj) {
5764                updateOomAdjLocked();
5765            }
5766            if (doLowMem) {
5767                doLowMemReportIfNeededLocked(app);
5768            }
5769        } else if (app.pid != pid) {
5770            // A new process has already been started.
5771            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5772                    + ") has died and restarted (pid " + app.pid + ").");
5773            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5774        } else if (DEBUG_PROCESSES) {
5775            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5776                    + thread.asBinder());
5777        }
5778    }
5779
5780    /**
5781     * If a stack trace dump file is configured, dump process stack traces.
5782     * @param clearTraces causes the dump file to be erased prior to the new
5783     *    traces being written, if true; when false, the new traces will be
5784     *    appended to any existing file content.
5785     * @param firstPids of dalvik VM processes to dump stack traces for first
5786     * @param lastPids of dalvik VM processes to dump stack traces for last
5787     * @param nativePids optional list of native pids to dump stack crawls
5788     */
5789    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5790            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5791            ArrayList<Integer> nativePids) {
5792        ArrayList<Integer> extraPids = null;
5793
5794        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5795        // of the top users at the time of the request.
5796        if (processCpuTracker != null) {
5797            processCpuTracker.init();
5798            try {
5799                Thread.sleep(200);
5800            } catch (InterruptedException ignored) {
5801            }
5802
5803            processCpuTracker.update();
5804
5805            // We'll take the stack crawls of just the top apps using CPU.
5806            final int N = processCpuTracker.countWorkingStats();
5807            extraPids = new ArrayList<>();
5808            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5809                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5810                if (lastPids.indexOfKey(stats.pid) >= 0) {
5811                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5812
5813                    extraPids.add(stats.pid);
5814                } else if (DEBUG_ANR) {
5815                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5816                            + stats.pid);
5817                }
5818            }
5819        }
5820
5821        boolean useTombstonedForJavaTraces = false;
5822        File tracesFile;
5823
5824        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5825        if (tracesDirProp.isEmpty()) {
5826            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5827            // dumping scheme. All traces are written to a global trace file (usually
5828            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5829            // the file if requested.
5830            //
5831            // This mode of operation will be removed in the near future.
5832
5833
5834            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5835            if (globalTracesPath.isEmpty()) {
5836                Slog.w(TAG, "dumpStackTraces: no trace path configured");
5837                return null;
5838            }
5839
5840            tracesFile = new File(globalTracesPath);
5841            try {
5842                if (clearTraces && tracesFile.exists()) {
5843                    tracesFile.delete();
5844                }
5845
5846                tracesFile.createNewFile();
5847                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5848            } catch (IOException e) {
5849                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5850                return null;
5851            }
5852        } else {
5853            File tracesDir = new File(tracesDirProp);
5854            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5855            // Each set of ANR traces is written to a separate file and dumpstate will process
5856            // all such files and add them to a captured bug report if they're recent enough.
5857            maybePruneOldTraces(tracesDir);
5858
5859            // NOTE: We should consider creating the file in native code atomically once we've
5860            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5861            // can be removed.
5862            tracesFile = createAnrDumpFile(tracesDir);
5863            if (tracesFile == null) {
5864                return null;
5865            }
5866
5867            useTombstonedForJavaTraces = true;
5868        }
5869
5870        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5871                useTombstonedForJavaTraces);
5872        return tracesFile;
5873    }
5874
5875    @GuardedBy("ActivityManagerService.class")
5876    private static SimpleDateFormat sAnrFileDateFormat;
5877
5878    private static synchronized File createAnrDumpFile(File tracesDir) {
5879        if (sAnrFileDateFormat == null) {
5880            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5881        }
5882
5883        final String formattedDate = sAnrFileDateFormat.format(new Date());
5884        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5885
5886        try {
5887            if (anrFile.createNewFile()) {
5888                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5889                return anrFile;
5890            } else {
5891                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5892            }
5893        } catch (IOException ioe) {
5894            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5895        }
5896
5897        return null;
5898    }
5899
5900    /**
5901     * Prune all trace files that are more than a day old.
5902     *
5903     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5904     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5905     * since it's the system_server that creates trace files for most ANRs.
5906     */
5907    private static void maybePruneOldTraces(File tracesDir) {
5908        final long now = System.currentTimeMillis();
5909        final File[] traceFiles = tracesDir.listFiles();
5910
5911        if (traceFiles != null) {
5912            for (File file : traceFiles) {
5913                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5914                    if (!file.delete()) {
5915                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
5916                    }
5917                }
5918            }
5919        }
5920    }
5921
5922    /**
5923     * Legacy code, do not use. Existing users will be deleted.
5924     *
5925     * @deprecated
5926     */
5927    @Deprecated
5928    public static class DumpStackFileObserver extends FileObserver {
5929        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5930        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5931
5932        private final String mTracesPath;
5933        private boolean mClosed;
5934
5935        public DumpStackFileObserver(String tracesPath) {
5936            super(tracesPath, FileObserver.CLOSE_WRITE);
5937            mTracesPath = tracesPath;
5938        }
5939
5940        @Override
5941        public synchronized void onEvent(int event, String path) {
5942            mClosed = true;
5943            notify();
5944        }
5945
5946        public long dumpWithTimeout(int pid, long timeout) {
5947            sendSignal(pid, SIGNAL_QUIT);
5948            final long start = SystemClock.elapsedRealtime();
5949
5950            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5951            synchronized (this) {
5952                try {
5953                    wait(waitTime); // Wait for traces file to be closed.
5954                } catch (InterruptedException e) {
5955                    Slog.wtf(TAG, e);
5956                }
5957            }
5958
5959            // This avoids a corner case of passing a negative time to the native
5960            // trace in case we've already hit the overall timeout.
5961            final long timeWaited = SystemClock.elapsedRealtime() - start;
5962            if (timeWaited >= timeout) {
5963                return timeWaited;
5964            }
5965
5966            if (!mClosed) {
5967                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5968                       ". Attempting native stack collection.");
5969
5970                final long nativeDumpTimeoutMs = Math.min(
5971                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5972
5973                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5974                        (int) (nativeDumpTimeoutMs / 1000));
5975            }
5976
5977            final long end = SystemClock.elapsedRealtime();
5978            mClosed = false;
5979
5980            return (end - start);
5981        }
5982    }
5983
5984    /**
5985     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5986     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5987     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5988     * attempting to obtain native traces in the case of a failure. Returns the total time spent
5989     * capturing traces.
5990     */
5991    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5992        final long timeStart = SystemClock.elapsedRealtime();
5993        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5994            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5995                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
5996        }
5997
5998        return SystemClock.elapsedRealtime() - timeStart;
5999    }
6000
6001    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6002            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6003            boolean useTombstonedForJavaTraces) {
6004
6005        // We don't need any sort of inotify based monitoring when we're dumping traces via
6006        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
6007        // control of all writes to the file in question.
6008        final DumpStackFileObserver observer;
6009        if (useTombstonedForJavaTraces) {
6010            observer = null;
6011        } else {
6012            // Use a FileObserver to detect when traces finish writing.
6013            // The order of traces is considered important to maintain for legibility.
6014            observer = new DumpStackFileObserver(tracesFile);
6015        }
6016
6017        // We must complete all stack dumps within 20 seconds.
6018        long remainingTime = 20 * 1000;
6019        try {
6020            if (observer != null) {
6021                observer.startWatching();
6022            }
6023
6024            // First collect all of the stacks of the most important pids.
6025            if (firstPids != null) {
6026                int num = firstPids.size();
6027                for (int i = 0; i < num; i++) {
6028                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
6029                            + firstPids.get(i));
6030                    final long timeTaken;
6031                    if (useTombstonedForJavaTraces) {
6032                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
6033                    } else {
6034                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6035                    }
6036
6037                    remainingTime -= timeTaken;
6038                    if (remainingTime <= 0) {
6039                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6040                            "); deadline exceeded.");
6041                        return;
6042                    }
6043
6044                    if (DEBUG_ANR) {
6045                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
6046                    }
6047                }
6048            }
6049
6050            // Next collect the stacks of the native pids
6051            if (nativePids != null) {
6052                for (int pid : nativePids) {
6053                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
6054                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
6055
6056                    final long start = SystemClock.elapsedRealtime();
6057                    Debug.dumpNativeBacktraceToFileTimeout(
6058                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6059                    final long timeTaken = SystemClock.elapsedRealtime() - start;
6060
6061                    remainingTime -= timeTaken;
6062                    if (remainingTime <= 0) {
6063                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6064                            "); deadline exceeded.");
6065                        return;
6066                    }
6067
6068                    if (DEBUG_ANR) {
6069                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
6070                    }
6071                }
6072            }
6073
6074            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
6075            if (extraPids != null) {
6076                for (int pid : extraPids) {
6077                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6078
6079                    final long timeTaken;
6080                    if (useTombstonedForJavaTraces) {
6081                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6082                    } else {
6083                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6084                    }
6085
6086                    remainingTime -= timeTaken;
6087                    if (remainingTime <= 0) {
6088                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6089                                "); deadline exceeded.");
6090                        return;
6091                    }
6092
6093                    if (DEBUG_ANR) {
6094                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6095                    }
6096                }
6097            }
6098        } finally {
6099            if (observer != null) {
6100                observer.stopWatching();
6101            }
6102        }
6103    }
6104
6105    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6106        if (true || Build.IS_USER) {
6107            return;
6108        }
6109        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6110        if (tracesPath == null || tracesPath.length() == 0) {
6111            return;
6112        }
6113
6114        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6115        StrictMode.allowThreadDiskWrites();
6116        try {
6117            final File tracesFile = new File(tracesPath);
6118            final File tracesDir = tracesFile.getParentFile();
6119            final File tracesTmp = new File(tracesDir, "__tmp__");
6120            try {
6121                if (tracesFile.exists()) {
6122                    tracesTmp.delete();
6123                    tracesFile.renameTo(tracesTmp);
6124                }
6125                StringBuilder sb = new StringBuilder();
6126                Time tobj = new Time();
6127                tobj.set(System.currentTimeMillis());
6128                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6129                sb.append(": ");
6130                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6131                sb.append(" since ");
6132                sb.append(msg);
6133                FileOutputStream fos = new FileOutputStream(tracesFile);
6134                fos.write(sb.toString().getBytes());
6135                if (app == null) {
6136                    fos.write("\n*** No application process!".getBytes());
6137                }
6138                fos.close();
6139                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6140            } catch (IOException e) {
6141                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6142                return;
6143            }
6144
6145            if (app != null && app.pid > 0) {
6146                ArrayList<Integer> firstPids = new ArrayList<Integer>();
6147                firstPids.add(app.pid);
6148                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6149            }
6150
6151            File lastTracesFile = null;
6152            File curTracesFile = null;
6153            for (int i=9; i>=0; i--) {
6154                String name = String.format(Locale.US, "slow%02d.txt", i);
6155                curTracesFile = new File(tracesDir, name);
6156                if (curTracesFile.exists()) {
6157                    if (lastTracesFile != null) {
6158                        curTracesFile.renameTo(lastTracesFile);
6159                    } else {
6160                        curTracesFile.delete();
6161                    }
6162                }
6163                lastTracesFile = curTracesFile;
6164            }
6165            tracesFile.renameTo(curTracesFile);
6166            if (tracesTmp.exists()) {
6167                tracesTmp.renameTo(tracesFile);
6168            }
6169        } finally {
6170            StrictMode.setThreadPolicy(oldPolicy);
6171        }
6172    }
6173
6174    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6175        if (!mLaunchWarningShown) {
6176            mLaunchWarningShown = true;
6177            mUiHandler.post(new Runnable() {
6178                @Override
6179                public void run() {
6180                    synchronized (ActivityManagerService.this) {
6181                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6182                        d.show();
6183                        mUiHandler.postDelayed(new Runnable() {
6184                            @Override
6185                            public void run() {
6186                                synchronized (ActivityManagerService.this) {
6187                                    d.dismiss();
6188                                    mLaunchWarningShown = false;
6189                                }
6190                            }
6191                        }, 4000);
6192                    }
6193                }
6194            });
6195        }
6196    }
6197
6198    @Override
6199    public boolean clearApplicationUserData(final String packageName, boolean keepState,
6200            final IPackageDataObserver observer, int userId) {
6201        enforceNotIsolatedCaller("clearApplicationUserData");
6202        int uid = Binder.getCallingUid();
6203        int pid = Binder.getCallingPid();
6204        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6205                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6206
6207        final ApplicationInfo appInfo;
6208        final boolean isInstantApp;
6209
6210        long callingId = Binder.clearCallingIdentity();
6211        try {
6212            IPackageManager pm = AppGlobals.getPackageManager();
6213            synchronized(this) {
6214                // Instant packages are not protected
6215                if (getPackageManagerInternalLocked().isPackageDataProtected(
6216                        resolvedUserId, packageName)) {
6217                    throw new SecurityException(
6218                            "Cannot clear data for a protected package: " + packageName);
6219                }
6220
6221                ApplicationInfo applicationInfo = null;
6222                try {
6223                    applicationInfo = pm.getApplicationInfo(packageName,
6224                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6225                } catch (RemoteException e) {
6226                    /* ignore */
6227                }
6228                appInfo = applicationInfo;
6229
6230                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6231
6232                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6233                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6234                    throw new SecurityException("PID " + pid + " does not have permission "
6235                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6236                            + " of package " + packageName);
6237                }
6238
6239                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6240                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
6241                final boolean isUninstalledAppWithoutInstantMetadata =
6242                        (appInfo == null && !hasInstantMetadata);
6243                isInstantApp = (appInfo != null && appInfo.isInstantApp())
6244                        || hasInstantMetadata;
6245                final boolean canAccessInstantApps = checkComponentPermission(
6246                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6247                        == PackageManager.PERMISSION_GRANTED;
6248
6249                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6250                        && !canAccessInstantApps)) {
6251                    Slog.w(TAG, "Invalid packageName: " + packageName);
6252                    if (observer != null) {
6253                        try {
6254                            observer.onRemoveCompleted(packageName, false);
6255                        } catch (RemoteException e) {
6256                            Slog.i(TAG, "Observer no longer exists.");
6257                        }
6258                    }
6259                    return false;
6260                }
6261
6262                if (appInfo != null) {
6263                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6264                    mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6265                }
6266            }
6267
6268            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6269                @Override
6270                public void onRemoveCompleted(String packageName, boolean succeeded)
6271                        throws RemoteException {
6272                    if (appInfo != null) {
6273                        synchronized (ActivityManagerService.this) {
6274                            finishForceStopPackageLocked(packageName, appInfo.uid);
6275                        }
6276                    }
6277                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6278                            Uri.fromParts("package", packageName, null));
6279                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6280                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6281                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6282                    if (isInstantApp) {
6283                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6284                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6285                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6286                                resolvedUserId);
6287                    } else {
6288                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6289                                null, null, null, null, false, false, resolvedUserId);
6290                    }
6291
6292                    if (observer != null) {
6293                        observer.onRemoveCompleted(packageName, succeeded);
6294                    }
6295                }
6296            };
6297
6298            try {
6299                // Clear application user data
6300                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6301
6302                if (appInfo != null) {
6303                    // Restore already established notification state and permission grants,
6304                    // so it told us to keep those intact -- it's about to emplace app data
6305                    // that is appropriate for those bits of system state.
6306                    if (!keepState) {
6307                        synchronized (this) {
6308                            // Remove all permissions granted from/to this package
6309                            removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6310                        }
6311
6312                        // Reset notification state
6313                        INotificationManager inm = NotificationManager.getService();
6314                        inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6315                    }
6316
6317                    // Clear its scheduled jobs
6318                    JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6319                    js.cancelJobsForUid(appInfo.uid, "clear data");
6320
6321                    // Clear its pending alarms
6322                    AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6323                    ami.removeAlarmsForUid(appInfo.uid);
6324                }
6325            } catch (RemoteException e) {
6326            }
6327        } finally {
6328            Binder.restoreCallingIdentity(callingId);
6329        }
6330        return true;
6331    }
6332
6333    @Override
6334    public void killBackgroundProcesses(final String packageName, int userId) {
6335        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6336                != PackageManager.PERMISSION_GRANTED &&
6337                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6338                        != PackageManager.PERMISSION_GRANTED) {
6339            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6340                    + Binder.getCallingPid()
6341                    + ", uid=" + Binder.getCallingUid()
6342                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6343            Slog.w(TAG, msg);
6344            throw new SecurityException(msg);
6345        }
6346
6347        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6348                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6349        long callingId = Binder.clearCallingIdentity();
6350        try {
6351            IPackageManager pm = AppGlobals.getPackageManager();
6352            synchronized(this) {
6353                int appId = -1;
6354                try {
6355                    appId = UserHandle.getAppId(
6356                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6357                } catch (RemoteException e) {
6358                }
6359                if (appId == -1) {
6360                    Slog.w(TAG, "Invalid packageName: " + packageName);
6361                    return;
6362                }
6363                killPackageProcessesLocked(packageName, appId, userId,
6364                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6365            }
6366        } finally {
6367            Binder.restoreCallingIdentity(callingId);
6368        }
6369    }
6370
6371    @Override
6372    public void killAllBackgroundProcesses() {
6373        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6374                != PackageManager.PERMISSION_GRANTED) {
6375            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6376                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6377                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6378            Slog.w(TAG, msg);
6379            throw new SecurityException(msg);
6380        }
6381
6382        final long callingId = Binder.clearCallingIdentity();
6383        try {
6384            synchronized (this) {
6385                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6386                final int NP = mProcessNames.getMap().size();
6387                for (int ip = 0; ip < NP; ip++) {
6388                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6389                    final int NA = apps.size();
6390                    for (int ia = 0; ia < NA; ia++) {
6391                        final ProcessRecord app = apps.valueAt(ia);
6392                        if (app.persistent) {
6393                            // We don't kill persistent processes.
6394                            continue;
6395                        }
6396                        if (app.removed) {
6397                            procs.add(app);
6398                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6399                            app.removed = true;
6400                            procs.add(app);
6401                        }
6402                    }
6403                }
6404
6405                final int N = procs.size();
6406                for (int i = 0; i < N; i++) {
6407                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6408                }
6409
6410                mAllowLowerMemLevel = true;
6411
6412                updateOomAdjLocked();
6413                doLowMemReportIfNeededLocked(null);
6414            }
6415        } finally {
6416            Binder.restoreCallingIdentity(callingId);
6417        }
6418    }
6419
6420    /**
6421     * Kills all background processes, except those matching any of the
6422     * specified properties.
6423     *
6424     * @param minTargetSdk the target SDK version at or above which to preserve
6425     *                     processes, or {@code -1} to ignore the target SDK
6426     * @param maxProcState the process state at or below which to preserve
6427     *                     processes, or {@code -1} to ignore the process state
6428     */
6429    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6430        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6431                != PackageManager.PERMISSION_GRANTED) {
6432            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6433                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6434                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6435            Slog.w(TAG, msg);
6436            throw new SecurityException(msg);
6437        }
6438
6439        final long callingId = Binder.clearCallingIdentity();
6440        try {
6441            synchronized (this) {
6442                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6443                final int NP = mProcessNames.getMap().size();
6444                for (int ip = 0; ip < NP; ip++) {
6445                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6446                    final int NA = apps.size();
6447                    for (int ia = 0; ia < NA; ia++) {
6448                        final ProcessRecord app = apps.valueAt(ia);
6449                        if (app.removed) {
6450                            procs.add(app);
6451                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6452                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6453                            app.removed = true;
6454                            procs.add(app);
6455                        }
6456                    }
6457                }
6458
6459                final int N = procs.size();
6460                for (int i = 0; i < N; i++) {
6461                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6462                }
6463            }
6464        } finally {
6465            Binder.restoreCallingIdentity(callingId);
6466        }
6467    }
6468
6469    @Override
6470    public void forceStopPackage(final String packageName, int userId) {
6471        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6472                != PackageManager.PERMISSION_GRANTED) {
6473            String msg = "Permission Denial: forceStopPackage() from pid="
6474                    + Binder.getCallingPid()
6475                    + ", uid=" + Binder.getCallingUid()
6476                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6477            Slog.w(TAG, msg);
6478            throw new SecurityException(msg);
6479        }
6480        final int callingPid = Binder.getCallingPid();
6481        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6482                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6483        long callingId = Binder.clearCallingIdentity();
6484        try {
6485            IPackageManager pm = AppGlobals.getPackageManager();
6486            synchronized(this) {
6487                int[] users = userId == UserHandle.USER_ALL
6488                        ? mUserController.getUsers() : new int[] { userId };
6489                for (int user : users) {
6490                    int pkgUid = -1;
6491                    try {
6492                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6493                                user);
6494                    } catch (RemoteException e) {
6495                    }
6496                    if (pkgUid == -1) {
6497                        Slog.w(TAG, "Invalid packageName: " + packageName);
6498                        continue;
6499                    }
6500                    try {
6501                        pm.setPackageStoppedState(packageName, true, user);
6502                    } catch (RemoteException e) {
6503                    } catch (IllegalArgumentException e) {
6504                        Slog.w(TAG, "Failed trying to unstop package "
6505                                + packageName + ": " + e);
6506                    }
6507                    if (mUserController.isUserRunning(user, 0)) {
6508                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6509                        finishForceStopPackageLocked(packageName, pkgUid);
6510                    }
6511                }
6512            }
6513        } finally {
6514            Binder.restoreCallingIdentity(callingId);
6515        }
6516    }
6517
6518    @Override
6519    public void addPackageDependency(String packageName) {
6520        synchronized (this) {
6521            int callingPid = Binder.getCallingPid();
6522            if (callingPid == myPid()) {
6523                //  Yeah, um, no.
6524                return;
6525            }
6526            ProcessRecord proc;
6527            synchronized (mPidsSelfLocked) {
6528                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6529            }
6530            if (proc != null) {
6531                if (proc.pkgDeps == null) {
6532                    proc.pkgDeps = new ArraySet<String>(1);
6533                }
6534                proc.pkgDeps.add(packageName);
6535            }
6536        }
6537    }
6538
6539    /*
6540     * The pkg name and app id have to be specified.
6541     */
6542    @Override
6543    public void killApplication(String pkg, int appId, int userId, String reason) {
6544        if (pkg == null) {
6545            return;
6546        }
6547        // Make sure the uid is valid.
6548        if (appId < 0) {
6549            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6550            return;
6551        }
6552        int callerUid = Binder.getCallingUid();
6553        // Only the system server can kill an application
6554        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6555            // Post an aysnc message to kill the application
6556            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6557            msg.arg1 = appId;
6558            msg.arg2 = userId;
6559            Bundle bundle = new Bundle();
6560            bundle.putString("pkg", pkg);
6561            bundle.putString("reason", reason);
6562            msg.obj = bundle;
6563            mHandler.sendMessage(msg);
6564        } else {
6565            throw new SecurityException(callerUid + " cannot kill pkg: " +
6566                    pkg);
6567        }
6568    }
6569
6570    @Override
6571    public void closeSystemDialogs(String reason) {
6572        enforceNotIsolatedCaller("closeSystemDialogs");
6573
6574        final int pid = Binder.getCallingPid();
6575        final int uid = Binder.getCallingUid();
6576        final long origId = Binder.clearCallingIdentity();
6577        try {
6578            synchronized (this) {
6579                // Only allow this from foreground processes, so that background
6580                // applications can't abuse it to prevent system UI from being shown.
6581                if (uid >= FIRST_APPLICATION_UID) {
6582                    ProcessRecord proc;
6583                    synchronized (mPidsSelfLocked) {
6584                        proc = mPidsSelfLocked.get(pid);
6585                    }
6586                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6587                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6588                                + " from background process " + proc);
6589                        return;
6590                    }
6591                }
6592                closeSystemDialogsLocked(reason);
6593            }
6594        } finally {
6595            Binder.restoreCallingIdentity(origId);
6596        }
6597    }
6598
6599    void closeSystemDialogsLocked(String reason) {
6600        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6601        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6602                | Intent.FLAG_RECEIVER_FOREGROUND);
6603        if (reason != null) {
6604            intent.putExtra("reason", reason);
6605        }
6606        mWindowManager.closeSystemDialogs(reason);
6607
6608        mStackSupervisor.closeSystemDialogsLocked();
6609
6610        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6611                OP_NONE, null, false, false,
6612                -1, SYSTEM_UID, UserHandle.USER_ALL);
6613    }
6614
6615    @Override
6616    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6617        enforceNotIsolatedCaller("getProcessMemoryInfo");
6618        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6619        for (int i=pids.length-1; i>=0; i--) {
6620            ProcessRecord proc;
6621            int oomAdj;
6622            synchronized (this) {
6623                synchronized (mPidsSelfLocked) {
6624                    proc = mPidsSelfLocked.get(pids[i]);
6625                    oomAdj = proc != null ? proc.setAdj : 0;
6626                }
6627            }
6628            infos[i] = new Debug.MemoryInfo();
6629            long startTime = SystemClock.currentThreadTimeMillis();
6630            Debug.getMemoryInfo(pids[i], infos[i]);
6631            long endTime = SystemClock.currentThreadTimeMillis();
6632            if (proc != null) {
6633                synchronized (this) {
6634                    if (proc.thread != null && proc.setAdj == oomAdj) {
6635                        // Record this for posterity if the process has been stable.
6636                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6637                                infos[i].getTotalUss(), false,
6638                                ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
6639                                proc.pkgList);
6640                    }
6641                }
6642            }
6643        }
6644        return infos;
6645    }
6646
6647    @Override
6648    public long[] getProcessPss(int[] pids) {
6649        enforceNotIsolatedCaller("getProcessPss");
6650        long[] pss = new long[pids.length];
6651        for (int i=pids.length-1; i>=0; i--) {
6652            ProcessRecord proc;
6653            int oomAdj;
6654            synchronized (this) {
6655                synchronized (mPidsSelfLocked) {
6656                    proc = mPidsSelfLocked.get(pids[i]);
6657                    oomAdj = proc != null ? proc.setAdj : 0;
6658                }
6659            }
6660            long[] tmpUss = new long[1];
6661            long startTime = SystemClock.currentThreadTimeMillis();
6662            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6663            long endTime = SystemClock.currentThreadTimeMillis();
6664            if (proc != null) {
6665                synchronized (this) {
6666                    if (proc.thread != null && proc.setAdj == oomAdj) {
6667                        // Record this for posterity if the process has been stable.
6668                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false,
6669                                ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
6670                    }
6671                }
6672            }
6673        }
6674        return pss;
6675    }
6676
6677    @Override
6678    public void killApplicationProcess(String processName, int uid) {
6679        if (processName == null) {
6680            return;
6681        }
6682
6683        int callerUid = Binder.getCallingUid();
6684        // Only the system server can kill an application
6685        if (callerUid == SYSTEM_UID) {
6686            synchronized (this) {
6687                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6688                if (app != null && app.thread != null) {
6689                    try {
6690                        app.thread.scheduleSuicide();
6691                    } catch (RemoteException e) {
6692                        // If the other end already died, then our work here is done.
6693                    }
6694                } else {
6695                    Slog.w(TAG, "Process/uid not found attempting kill of "
6696                            + processName + " / " + uid);
6697                }
6698            }
6699        } else {
6700            throw new SecurityException(callerUid + " cannot kill app process: " +
6701                    processName);
6702        }
6703    }
6704
6705    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6706        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6707                false, true, false, false, UserHandle.getUserId(uid), reason);
6708    }
6709
6710    private void finishForceStopPackageLocked(final String packageName, int uid) {
6711        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6712                Uri.fromParts("package", packageName, null));
6713        if (!mProcessesReady) {
6714            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6715                    | Intent.FLAG_RECEIVER_FOREGROUND);
6716        }
6717        intent.putExtra(Intent.EXTRA_UID, uid);
6718        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6719        broadcastIntentLocked(null, null, intent,
6720                null, null, 0, null, null, null, OP_NONE,
6721                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6722    }
6723
6724
6725    private final boolean killPackageProcessesLocked(String packageName, int appId,
6726            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6727            boolean doit, boolean evenPersistent, String reason) {
6728        ArrayList<ProcessRecord> procs = new ArrayList<>();
6729
6730        // Remove all processes this package may have touched: all with the
6731        // same UID (except for the system or root user), and all whose name
6732        // matches the package name.
6733        final int NP = mProcessNames.getMap().size();
6734        for (int ip=0; ip<NP; ip++) {
6735            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6736            final int NA = apps.size();
6737            for (int ia=0; ia<NA; ia++) {
6738                ProcessRecord app = apps.valueAt(ia);
6739                if (app.persistent && !evenPersistent) {
6740                    // we don't kill persistent processes
6741                    continue;
6742                }
6743                if (app.removed) {
6744                    if (doit) {
6745                        procs.add(app);
6746                    }
6747                    continue;
6748                }
6749
6750                // Skip process if it doesn't meet our oom adj requirement.
6751                if (app.setAdj < minOomAdj) {
6752                    continue;
6753                }
6754
6755                // If no package is specified, we call all processes under the
6756                // give user id.
6757                if (packageName == null) {
6758                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6759                        continue;
6760                    }
6761                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6762                        continue;
6763                    }
6764                // Package has been specified, we want to hit all processes
6765                // that match it.  We need to qualify this by the processes
6766                // that are running under the specified app and user ID.
6767                } else {
6768                    final boolean isDep = app.pkgDeps != null
6769                            && app.pkgDeps.contains(packageName);
6770                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6771                        continue;
6772                    }
6773                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6774                        continue;
6775                    }
6776                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6777                        continue;
6778                    }
6779                }
6780
6781                // Process has passed all conditions, kill it!
6782                if (!doit) {
6783                    return true;
6784                }
6785                app.removed = true;
6786                procs.add(app);
6787            }
6788        }
6789
6790        int N = procs.size();
6791        for (int i=0; i<N; i++) {
6792            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6793        }
6794        updateOomAdjLocked();
6795        return N > 0;
6796    }
6797
6798    private void cleanupDisabledPackageComponentsLocked(
6799            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6800
6801        Set<String> disabledClasses = null;
6802        boolean packageDisabled = false;
6803        IPackageManager pm = AppGlobals.getPackageManager();
6804
6805        if (changedClasses == null) {
6806            // Nothing changed...
6807            return;
6808        }
6809
6810        // Determine enable/disable state of the package and its components.
6811        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6812        for (int i = changedClasses.length - 1; i >= 0; i--) {
6813            final String changedClass = changedClasses[i];
6814
6815            if (changedClass.equals(packageName)) {
6816                try {
6817                    // Entire package setting changed
6818                    enabled = pm.getApplicationEnabledSetting(packageName,
6819                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6820                } catch (Exception e) {
6821                    // No such package/component; probably racing with uninstall.  In any
6822                    // event it means we have nothing further to do here.
6823                    return;
6824                }
6825                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6826                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6827                if (packageDisabled) {
6828                    // Entire package is disabled.
6829                    // No need to continue to check component states.
6830                    disabledClasses = null;
6831                    break;
6832                }
6833            } else {
6834                try {
6835                    enabled = pm.getComponentEnabledSetting(
6836                            new ComponentName(packageName, changedClass),
6837                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6838                } catch (Exception e) {
6839                    // As above, probably racing with uninstall.
6840                    return;
6841                }
6842                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6843                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6844                    if (disabledClasses == null) {
6845                        disabledClasses = new ArraySet<>(changedClasses.length);
6846                    }
6847                    disabledClasses.add(changedClass);
6848                }
6849            }
6850        }
6851
6852        if (!packageDisabled && disabledClasses == null) {
6853            // Nothing to do here...
6854            return;
6855        }
6856
6857        // Clean-up disabled activities.
6858        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6859                packageName, disabledClasses, true, false, userId) && mBooted) {
6860            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6861            mStackSupervisor.scheduleIdleLocked();
6862        }
6863
6864        // Clean-up disabled tasks
6865        mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6866
6867        // Clean-up disabled services.
6868        mServices.bringDownDisabledPackageServicesLocked(
6869                packageName, disabledClasses, userId, false, killProcess, true);
6870
6871        // Clean-up disabled providers.
6872        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6873        mProviderMap.collectPackageProvidersLocked(
6874                packageName, disabledClasses, true, false, userId, providers);
6875        for (int i = providers.size() - 1; i >= 0; i--) {
6876            removeDyingProviderLocked(null, providers.get(i), true);
6877        }
6878
6879        // Clean-up disabled broadcast receivers.
6880        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6881            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6882                    packageName, disabledClasses, userId, true);
6883        }
6884
6885    }
6886
6887    final boolean clearBroadcastQueueForUserLocked(int userId) {
6888        boolean didSomething = false;
6889        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6890            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6891                    null, null, userId, true);
6892        }
6893        return didSomething;
6894    }
6895
6896    final boolean forceStopPackageLocked(String packageName, int appId,
6897            boolean callerWillRestart, boolean purgeCache, boolean doit,
6898            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6899        int i;
6900
6901        if (userId == UserHandle.USER_ALL && packageName == null) {
6902            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6903        }
6904
6905        if (appId < 0 && packageName != null) {
6906            try {
6907                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6908                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6909            } catch (RemoteException e) {
6910            }
6911        }
6912
6913        if (doit) {
6914            if (packageName != null) {
6915                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6916                        + " user=" + userId + ": " + reason);
6917            } else {
6918                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6919            }
6920
6921            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6922        }
6923
6924        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6925                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6926                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6927
6928        didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
6929
6930        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6931                packageName, null, doit, evenPersistent, userId)) {
6932            if (!doit) {
6933                return true;
6934            }
6935            didSomething = true;
6936        }
6937
6938        if (mServices.bringDownDisabledPackageServicesLocked(
6939                packageName, null, userId, evenPersistent, true, doit)) {
6940            if (!doit) {
6941                return true;
6942            }
6943            didSomething = true;
6944        }
6945
6946        if (packageName == null) {
6947            // Remove all sticky broadcasts from this user.
6948            mStickyBroadcasts.remove(userId);
6949        }
6950
6951        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6952        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6953                userId, providers)) {
6954            if (!doit) {
6955                return true;
6956            }
6957            didSomething = true;
6958        }
6959        for (i = providers.size() - 1; i >= 0; i--) {
6960            removeDyingProviderLocked(null, providers.get(i), true);
6961        }
6962
6963        // Remove transient permissions granted from/to this package/user
6964        removeUriPermissionsForPackageLocked(packageName, userId, false);
6965
6966        if (doit) {
6967            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6968                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6969                        packageName, null, userId, doit);
6970            }
6971        }
6972
6973        if (packageName == null || uninstalling) {
6974            // Remove pending intents.  For now we only do this when force
6975            // stopping users, because we have some problems when doing this
6976            // for packages -- app widgets are not currently cleaned up for
6977            // such packages, so they can be left with bad pending intents.
6978            if (mIntentSenderRecords.size() > 0) {
6979                Iterator<WeakReference<PendingIntentRecord>> it
6980                        = mIntentSenderRecords.values().iterator();
6981                while (it.hasNext()) {
6982                    WeakReference<PendingIntentRecord> wpir = it.next();
6983                    if (wpir == null) {
6984                        it.remove();
6985                        continue;
6986                    }
6987                    PendingIntentRecord pir = wpir.get();
6988                    if (pir == null) {
6989                        it.remove();
6990                        continue;
6991                    }
6992                    if (packageName == null) {
6993                        // Stopping user, remove all objects for the user.
6994                        if (pir.key.userId != userId) {
6995                            // Not the same user, skip it.
6996                            continue;
6997                        }
6998                    } else {
6999                        if (UserHandle.getAppId(pir.uid) != appId) {
7000                            // Different app id, skip it.
7001                            continue;
7002                        }
7003                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7004                            // Different user, skip it.
7005                            continue;
7006                        }
7007                        if (!pir.key.packageName.equals(packageName)) {
7008                            // Different package, skip it.
7009                            continue;
7010                        }
7011                    }
7012                    if (!doit) {
7013                        return true;
7014                    }
7015                    didSomething = true;
7016                    it.remove();
7017                    makeIntentSenderCanceledLocked(pir);
7018                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7019                        pir.key.activity.pendingResults.remove(pir.ref);
7020                    }
7021                }
7022            }
7023        }
7024
7025        if (doit) {
7026            if (purgeCache && packageName != null) {
7027                AttributeCache ac = AttributeCache.instance();
7028                if (ac != null) {
7029                    ac.removePackage(packageName);
7030                }
7031            }
7032            if (mBooted) {
7033                mStackSupervisor.resumeFocusedStackTopActivityLocked();
7034                mStackSupervisor.scheduleIdleLocked();
7035            }
7036        }
7037
7038        return didSomething;
7039    }
7040
7041    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7042        return removeProcessNameLocked(name, uid, null);
7043    }
7044
7045    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
7046            final ProcessRecord expecting) {
7047        ProcessRecord old = mProcessNames.get(name, uid);
7048        // Only actually remove when the currently recorded value matches the
7049        // record that we expected; if it doesn't match then we raced with a
7050        // newly created process and we don't want to destroy the new one.
7051        if ((expecting == null) || (old == expecting)) {
7052            mProcessNames.remove(name, uid);
7053        }
7054        if (old != null && old.uidRecord != null) {
7055            old.uidRecord.numProcs--;
7056            if (old.uidRecord.numProcs == 0) {
7057                // No more processes using this uid, tell clients it is gone.
7058                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7059                        "No more processes in " + old.uidRecord);
7060                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
7061                EventLogTags.writeAmUidStopped(uid);
7062                mActiveUids.remove(uid);
7063                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
7064            }
7065            old.uidRecord = null;
7066        }
7067        mIsolatedProcesses.remove(uid);
7068        return old;
7069    }
7070
7071    private final void addProcessNameLocked(ProcessRecord proc) {
7072        // We shouldn't already have a process under this name, but just in case we
7073        // need to clean up whatever may be there now.
7074        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
7075        if (old == proc && proc.persistent) {
7076            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
7077            Slog.w(TAG, "Re-adding persistent process " + proc);
7078        } else if (old != null) {
7079            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7080        }
7081        UidRecord uidRec = mActiveUids.get(proc.uid);
7082        if (uidRec == null) {
7083            uidRec = new UidRecord(proc.uid);
7084            // This is the first appearance of the uid, report it now!
7085            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7086                    "Creating new process uid: " + uidRec);
7087            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7088                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7089                uidRec.setWhitelist = uidRec.curWhitelist = true;
7090            }
7091            uidRec.updateHasInternetPermission();
7092            mActiveUids.put(proc.uid, uidRec);
7093            EventLogTags.writeAmUidRunning(uidRec.uid);
7094            noteUidProcessState(uidRec.uid, uidRec.curProcState);
7095        }
7096        proc.uidRecord = uidRec;
7097
7098        // Reset render thread tid if it was already set, so new process can set it again.
7099        proc.renderThreadTid = 0;
7100        uidRec.numProcs++;
7101        mProcessNames.put(proc.processName, proc.uid, proc);
7102        if (proc.isolated) {
7103            mIsolatedProcesses.put(proc.uid, proc);
7104        }
7105    }
7106
7107    boolean removeProcessLocked(ProcessRecord app,
7108            boolean callerWillRestart, boolean allowRestart, String reason) {
7109        final String name = app.processName;
7110        final int uid = app.uid;
7111        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7112            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7113
7114        ProcessRecord old = mProcessNames.get(name, uid);
7115        if (old != app) {
7116            // This process is no longer active, so nothing to do.
7117            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7118            return false;
7119        }
7120        removeProcessNameLocked(name, uid);
7121        if (mHeavyWeightProcess == app) {
7122            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7123                    mHeavyWeightProcess.userId, 0));
7124            mHeavyWeightProcess = null;
7125        }
7126        boolean needRestart = false;
7127        if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7128            int pid = app.pid;
7129            if (pid > 0) {
7130                synchronized (mPidsSelfLocked) {
7131                    mPidsSelfLocked.remove(pid);
7132                    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7133                }
7134                mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7135                if (app.isolated) {
7136                    mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7137                    getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7138                }
7139            }
7140            boolean willRestart = false;
7141            if (app.persistent && !app.isolated) {
7142                if (!callerWillRestart) {
7143                    willRestart = true;
7144                } else {
7145                    needRestart = true;
7146                }
7147            }
7148            app.kill(reason, true);
7149            handleAppDiedLocked(app, willRestart, allowRestart);
7150            if (willRestart) {
7151                removeLruProcessLocked(app);
7152                addAppLocked(app.info, null, false, null /* ABI override */);
7153            }
7154        } else {
7155            mRemovedProcesses.add(app);
7156        }
7157
7158        return needRestart;
7159    }
7160
7161    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7162        cleanupAppInLaunchingProvidersLocked(app, true);
7163        removeProcessLocked(app, false, true, "timeout publishing content providers");
7164    }
7165
7166    private final void processStartTimedOutLocked(ProcessRecord app) {
7167        final int pid = app.pid;
7168        boolean gone = false;
7169        synchronized (mPidsSelfLocked) {
7170            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7171            if (knownApp != null && knownApp.thread == null) {
7172                mPidsSelfLocked.remove(pid);
7173                gone = true;
7174            }
7175        }
7176
7177        if (gone) {
7178            Slog.w(TAG, "Process " + app + " failed to attach");
7179            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7180                    pid, app.uid, app.processName);
7181            removeProcessNameLocked(app.processName, app.uid);
7182            if (mHeavyWeightProcess == app) {
7183                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7184                        mHeavyWeightProcess.userId, 0));
7185                mHeavyWeightProcess = null;
7186            }
7187            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7188            // Take care of any launching providers waiting for this process.
7189            cleanupAppInLaunchingProvidersLocked(app, true);
7190            // Take care of any services that are waiting for the process.
7191            mServices.processStartTimedOutLocked(app);
7192            app.kill("start timeout", true);
7193            if (app.isolated) {
7194                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7195            }
7196            removeLruProcessLocked(app);
7197            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7198                Slog.w(TAG, "Unattached app died before backup, skipping");
7199                mHandler.post(new Runnable() {
7200                @Override
7201                    public void run(){
7202                        try {
7203                            IBackupManager bm = IBackupManager.Stub.asInterface(
7204                                    ServiceManager.getService(Context.BACKUP_SERVICE));
7205                            bm.agentDisconnected(app.info.packageName);
7206                        } catch (RemoteException e) {
7207                            // Can't happen; the backup manager is local
7208                        }
7209                    }
7210                });
7211            }
7212            if (isPendingBroadcastProcessLocked(pid)) {
7213                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7214                skipPendingBroadcastLocked(pid);
7215            }
7216        } else {
7217            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7218        }
7219    }
7220
7221    private final boolean attachApplicationLocked(IApplicationThread thread,
7222            int pid, int callingUid, long startSeq) {
7223
7224        // Find the application record that is being attached...  either via
7225        // the pid if we are running in multiple processes, or just pull the
7226        // next app record if we are emulating process with anonymous threads.
7227        ProcessRecord app;
7228        long startTime = SystemClock.uptimeMillis();
7229        if (pid != MY_PID && pid >= 0) {
7230            synchronized (mPidsSelfLocked) {
7231                app = mPidsSelfLocked.get(pid);
7232            }
7233        } else {
7234            app = null;
7235        }
7236
7237        // It's possible that process called attachApplication before we got a chance to
7238        // update the internal state.
7239        if (app == null && startSeq > 0) {
7240            final ProcessRecord pending = mPendingStarts.get(startSeq);
7241            if (pending != null && pending.startUid == callingUid
7242                    && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7243                            startSeq, true)) {
7244                app = pending;
7245            }
7246        }
7247
7248        if (app == null) {
7249            Slog.w(TAG, "No pending application record for pid " + pid
7250                    + " (IApplicationThread " + thread + "); dropping process");
7251            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7252            if (pid > 0 && pid != MY_PID) {
7253                killProcessQuiet(pid);
7254                //TODO: killProcessGroup(app.info.uid, pid);
7255            } else {
7256                try {
7257                    thread.scheduleExit();
7258                } catch (Exception e) {
7259                    // Ignore exceptions.
7260                }
7261            }
7262            return false;
7263        }
7264
7265        // If this application record is still attached to a previous
7266        // process, clean it up now.
7267        if (app.thread != null) {
7268            handleAppDiedLocked(app, true, true);
7269        }
7270
7271        // Tell the process all about itself.
7272
7273        if (DEBUG_ALL) Slog.v(
7274                TAG, "Binding process pid " + pid + " to record " + app);
7275
7276        final String processName = app.processName;
7277        try {
7278            AppDeathRecipient adr = new AppDeathRecipient(
7279                    app, pid, thread);
7280            thread.asBinder().linkToDeath(adr, 0);
7281            app.deathRecipient = adr;
7282        } catch (RemoteException e) {
7283            app.resetPackageList(mProcessStats);
7284            startProcessLocked(app, "link fail", processName);
7285            return false;
7286        }
7287
7288        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7289
7290        app.makeActive(thread, mProcessStats);
7291        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7292        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7293        app.forcingToImportant = null;
7294        updateProcessForegroundLocked(app, false, false);
7295        app.hasShownUi = false;
7296        app.debugging = false;
7297        app.cached = false;
7298        app.killedByAm = false;
7299        app.killed = false;
7300
7301
7302        // We carefully use the same state that PackageManager uses for
7303        // filtering, since we use this flag to decide if we need to install
7304        // providers when user is unlocked later
7305        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7306
7307        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7308
7309        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7310        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7311
7312        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7313            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7314            msg.obj = app;
7315            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7316        }
7317
7318        checkTime(startTime, "attachApplicationLocked: before bindApplication");
7319
7320        if (!normalMode) {
7321            Slog.i(TAG, "Launching preboot mode app: " + app);
7322        }
7323
7324        if (DEBUG_ALL) Slog.v(
7325            TAG, "New app record " + app
7326            + " thread=" + thread.asBinder() + " pid=" + pid);
7327        try {
7328            int testMode = ApplicationThreadConstants.DEBUG_OFF;
7329            if (mDebugApp != null && mDebugApp.equals(processName)) {
7330                testMode = mWaitForDebugger
7331                    ? ApplicationThreadConstants.DEBUG_WAIT
7332                    : ApplicationThreadConstants.DEBUG_ON;
7333                app.debugging = true;
7334                if (mDebugTransient) {
7335                    mDebugApp = mOrigDebugApp;
7336                    mWaitForDebugger = mOrigWaitForDebugger;
7337                }
7338            }
7339
7340            ProfilerInfo profilerInfo = null;
7341            String preBindAgent = null;
7342            if (mProfileApp != null && mProfileApp.equals(processName)) {
7343                mProfileProc = app;
7344                if (mProfilerInfo != null) {
7345                    // Send a profiler info object to the app if either a file is given, or
7346                    // an agent should be loaded at bind-time.
7347                    boolean needsInfo = mProfilerInfo.profileFile != null
7348                            || mProfilerInfo.attachAgentDuringBind;
7349                    profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7350                    if (!mProfilerInfo.attachAgentDuringBind) {
7351                        preBindAgent = mProfilerInfo.agent;
7352                    }
7353                }
7354            } else if (app.instr != null && app.instr.mProfileFile != null) {
7355                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7356                        null, false);
7357            }
7358
7359            boolean enableTrackAllocation = false;
7360            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7361                enableTrackAllocation = true;
7362                mTrackAllocationApp = null;
7363            }
7364
7365            // If the app is being launched for restore or full backup, set it up specially
7366            boolean isRestrictedBackupMode = false;
7367            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7368                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7369                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7370                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7371                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7372            }
7373
7374            if (app.instr != null) {
7375                notifyPackageUse(app.instr.mClass.getPackageName(),
7376                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7377            }
7378            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7379                    + processName + " with config " + getGlobalConfiguration());
7380            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7381            app.compat = compatibilityInfoForPackageLocked(appInfo);
7382
7383            if (profilerInfo != null && profilerInfo.profileFd != null) {
7384                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7385            }
7386
7387            // We deprecated Build.SERIAL and it is not accessible to
7388            // apps that target the v2 security sandbox and to apps that
7389            // target APIs higher than O MR1. Since access to the serial
7390            // is now behind a permission we push down the value.
7391            final String buildSerial = (appInfo.targetSandboxVersion < 2
7392                    && appInfo.targetSdkVersion <= Build.VERSION_CODES.O_MR1)
7393                            ? sTheRealBuildSerial : Build.UNKNOWN;
7394
7395            // Check if this is a secondary process that should be incorporated into some
7396            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7397            // stuff above because profiling can currently happen only in the primary
7398            // instrumentation process.)
7399            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7400                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7401                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7402                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7403                        if (aInstr.mTargetProcesses.length == 0) {
7404                            // This is the wildcard mode, where every process brought up for
7405                            // the target instrumentation should be included.
7406                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7407                                app.instr = aInstr;
7408                                aInstr.mRunningProcesses.add(app);
7409                            }
7410                        } else {
7411                            for (String proc : aInstr.mTargetProcesses) {
7412                                if (proc.equals(app.processName)) {
7413                                    app.instr = aInstr;
7414                                    aInstr.mRunningProcesses.add(app);
7415                                    break;
7416                                }
7417                            }
7418                        }
7419                    }
7420                }
7421            }
7422
7423            // If we were asked to attach an agent on startup, do so now, before we're binding
7424            // application code.
7425            if (preBindAgent != null) {
7426                thread.attachAgent(preBindAgent);
7427            }
7428
7429            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7430            mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7431            if (app.isolatedEntryPoint != null) {
7432                // This is an isolated process which should just call an entry point instead of
7433                // being bound to an application.
7434                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7435            } else if (app.instr != null) {
7436                thread.bindApplication(processName, appInfo, providers,
7437                        app.instr.mClass,
7438                        profilerInfo, app.instr.mArguments,
7439                        app.instr.mWatcher,
7440                        app.instr.mUiAutomationConnection, testMode,
7441                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7442                        isRestrictedBackupMode || !normalMode, app.persistent,
7443                        new Configuration(getGlobalConfiguration()), app.compat,
7444                        getCommonServicesLocked(app.isolated),
7445                        mCoreSettingsObserver.getCoreSettingsLocked(),
7446                        buildSerial);
7447            } else {
7448                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7449                        null, null, null, testMode,
7450                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7451                        isRestrictedBackupMode || !normalMode, app.persistent,
7452                        new Configuration(getGlobalConfiguration()), app.compat,
7453                        getCommonServicesLocked(app.isolated),
7454                        mCoreSettingsObserver.getCoreSettingsLocked(),
7455                        buildSerial);
7456            }
7457
7458            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7459            updateLruProcessLocked(app, false, null);
7460            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7461            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7462        } catch (Exception e) {
7463            // todo: Yikes!  What should we do?  For now we will try to
7464            // start another process, but that could easily get us in
7465            // an infinite loop of restarting processes...
7466            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7467
7468            app.resetPackageList(mProcessStats);
7469            app.unlinkDeathRecipient();
7470            startProcessLocked(app, "bind fail", processName);
7471            return false;
7472        }
7473
7474        // Remove this record from the list of starting applications.
7475        mPersistentStartingProcesses.remove(app);
7476        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7477                "Attach application locked removing on hold: " + app);
7478        mProcessesOnHold.remove(app);
7479
7480        boolean badApp = false;
7481        boolean didSomething = false;
7482
7483        // See if the top visible activity is waiting to run in this process...
7484        if (normalMode) {
7485            try {
7486                if (mStackSupervisor.attachApplicationLocked(app)) {
7487                    didSomething = true;
7488                }
7489            } catch (Exception e) {
7490                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7491                badApp = true;
7492            }
7493        }
7494
7495        // Find any services that should be running in this process...
7496        if (!badApp) {
7497            try {
7498                didSomething |= mServices.attachApplicationLocked(app, processName);
7499                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7500            } catch (Exception e) {
7501                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7502                badApp = true;
7503            }
7504        }
7505
7506        // Check if a next-broadcast receiver is in this process...
7507        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7508            try {
7509                didSomething |= sendPendingBroadcastsLocked(app);
7510                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7511            } catch (Exception e) {
7512                // If the app died trying to launch the receiver we declare it 'bad'
7513                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7514                badApp = true;
7515            }
7516        }
7517
7518        // Check whether the next backup agent is in this process...
7519        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7520            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7521                    "New app is backup target, launching agent for " + app);
7522            notifyPackageUse(mBackupTarget.appInfo.packageName,
7523                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7524            try {
7525                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7526                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7527                        mBackupTarget.backupMode);
7528            } catch (Exception e) {
7529                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7530                badApp = true;
7531            }
7532        }
7533
7534        if (badApp) {
7535            app.kill("error during init", true);
7536            handleAppDiedLocked(app, false, true);
7537            return false;
7538        }
7539
7540        if (!didSomething) {
7541            updateOomAdjLocked();
7542            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7543        }
7544
7545        return true;
7546    }
7547
7548    @Override
7549    public final void attachApplication(IApplicationThread thread, long startSeq) {
7550        synchronized (this) {
7551            int callingPid = Binder.getCallingPid();
7552            final int callingUid = Binder.getCallingUid();
7553            final long origId = Binder.clearCallingIdentity();
7554            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7555            Binder.restoreCallingIdentity(origId);
7556        }
7557    }
7558
7559    @Override
7560    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7561        final long origId = Binder.clearCallingIdentity();
7562        synchronized (this) {
7563            ActivityStack stack = ActivityRecord.getStackLocked(token);
7564            if (stack != null) {
7565                ActivityRecord r =
7566                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7567                                false /* processPausingActivities */, config);
7568                if (stopProfiling) {
7569                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7570                        clearProfilerLocked();
7571                    }
7572                }
7573            }
7574        }
7575        Binder.restoreCallingIdentity(origId);
7576    }
7577
7578    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7579        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7580                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7581    }
7582
7583    void enableScreenAfterBoot() {
7584        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7585                SystemClock.uptimeMillis());
7586        mWindowManager.enableScreenAfterBoot();
7587
7588        synchronized (this) {
7589            updateEventDispatchingLocked();
7590        }
7591    }
7592
7593    @Override
7594    public void showBootMessage(final CharSequence msg, final boolean always) {
7595        if (Binder.getCallingUid() != myUid()) {
7596            throw new SecurityException();
7597        }
7598        mWindowManager.showBootMessage(msg, always);
7599    }
7600
7601    @Override
7602    public void keyguardGoingAway(int flags) {
7603        enforceNotIsolatedCaller("keyguardGoingAway");
7604        final long token = Binder.clearCallingIdentity();
7605        try {
7606            synchronized (this) {
7607                mKeyguardController.keyguardGoingAway(flags);
7608            }
7609        } finally {
7610            Binder.restoreCallingIdentity(token);
7611        }
7612    }
7613
7614    /**
7615     * @return whther the keyguard is currently locked.
7616     */
7617    boolean isKeyguardLocked() {
7618        return mKeyguardController.isKeyguardLocked();
7619    }
7620
7621    final void finishBooting() {
7622        synchronized (this) {
7623            if (!mBootAnimationComplete) {
7624                mCallFinishBooting = true;
7625                return;
7626            }
7627            mCallFinishBooting = false;
7628        }
7629
7630        ArraySet<String> completedIsas = new ArraySet<String>();
7631        for (String abi : Build.SUPPORTED_ABIS) {
7632            zygoteProcess.establishZygoteConnectionForAbi(abi);
7633            final String instructionSet = VMRuntime.getInstructionSet(abi);
7634            if (!completedIsas.contains(instructionSet)) {
7635                try {
7636                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7637                } catch (InstallerException e) {
7638                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7639                            e.getMessage() +")");
7640                }
7641                completedIsas.add(instructionSet);
7642            }
7643        }
7644
7645        IntentFilter pkgFilter = new IntentFilter();
7646        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7647        pkgFilter.addDataScheme("package");
7648        mContext.registerReceiver(new BroadcastReceiver() {
7649            @Override
7650            public void onReceive(Context context, Intent intent) {
7651                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7652                if (pkgs != null) {
7653                    for (String pkg : pkgs) {
7654                        synchronized (ActivityManagerService.this) {
7655                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7656                                    0, "query restart")) {
7657                                setResultCode(Activity.RESULT_OK);
7658                                return;
7659                            }
7660                        }
7661                    }
7662                }
7663            }
7664        }, pkgFilter);
7665
7666        IntentFilter dumpheapFilter = new IntentFilter();
7667        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7668        mContext.registerReceiver(new BroadcastReceiver() {
7669            @Override
7670            public void onReceive(Context context, Intent intent) {
7671                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7672                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7673                } else {
7674                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7675                }
7676            }
7677        }, dumpheapFilter);
7678
7679        // Let system services know.
7680        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7681
7682        synchronized (this) {
7683            // Ensure that any processes we had put on hold are now started
7684            // up.
7685            final int NP = mProcessesOnHold.size();
7686            if (NP > 0) {
7687                ArrayList<ProcessRecord> procs =
7688                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7689                for (int ip=0; ip<NP; ip++) {
7690                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7691                            + procs.get(ip));
7692                    startProcessLocked(procs.get(ip), "on-hold", null);
7693                }
7694            }
7695            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7696                return;
7697            }
7698            // Start looking for apps that are abusing wake locks.
7699            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7700            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7701            // Tell anyone interested that we are done booting!
7702            SystemProperties.set("sys.boot_completed", "1");
7703
7704            // And trigger dev.bootcomplete if we are not showing encryption progress
7705            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7706                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7707                SystemProperties.set("dev.bootcomplete", "1");
7708            }
7709            mUserController.sendBootCompleted(
7710                    new IIntentReceiver.Stub() {
7711                        @Override
7712                        public void performReceive(Intent intent, int resultCode,
7713                                String data, Bundle extras, boolean ordered,
7714                                boolean sticky, int sendingUser) {
7715                            synchronized (ActivityManagerService.this) {
7716                                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
7717                            }
7718                        }
7719                    });
7720            mUserController.scheduleStartProfiles();
7721        }
7722    }
7723
7724    @Override
7725    public void bootAnimationComplete() {
7726        final boolean callFinishBooting;
7727        synchronized (this) {
7728            callFinishBooting = mCallFinishBooting;
7729            mBootAnimationComplete = true;
7730        }
7731        if (callFinishBooting) {
7732            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7733            finishBooting();
7734            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7735        }
7736    }
7737
7738    final void ensureBootCompleted() {
7739        boolean booting;
7740        boolean enableScreen;
7741        synchronized (this) {
7742            booting = mBooting;
7743            mBooting = false;
7744            enableScreen = !mBooted;
7745            mBooted = true;
7746        }
7747
7748        if (booting) {
7749            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7750            finishBooting();
7751            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7752        }
7753
7754        if (enableScreen) {
7755            enableScreenAfterBoot();
7756        }
7757    }
7758
7759    @Override
7760    public final void activityResumed(IBinder token) {
7761        final long origId = Binder.clearCallingIdentity();
7762        synchronized(this) {
7763            ActivityRecord.activityResumedLocked(token);
7764            mWindowManager.notifyAppResumedFinished(token);
7765        }
7766        Binder.restoreCallingIdentity(origId);
7767    }
7768
7769    @Override
7770    public final void activityPaused(IBinder token) {
7771        final long origId = Binder.clearCallingIdentity();
7772        synchronized(this) {
7773            ActivityStack stack = ActivityRecord.getStackLocked(token);
7774            if (stack != null) {
7775                stack.activityPausedLocked(token, false);
7776            }
7777        }
7778        Binder.restoreCallingIdentity(origId);
7779    }
7780
7781    @Override
7782    public final void activityStopped(IBinder token, Bundle icicle,
7783            PersistableBundle persistentState, CharSequence description) {
7784        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7785
7786        // Refuse possible leaked file descriptors
7787        if (icicle != null && icicle.hasFileDescriptors()) {
7788            throw new IllegalArgumentException("File descriptors passed in Bundle");
7789        }
7790
7791        final long origId = Binder.clearCallingIdentity();
7792
7793        synchronized (this) {
7794            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7795            if (r != null) {
7796                r.activityStoppedLocked(icicle, persistentState, description);
7797            }
7798        }
7799
7800        trimApplications();
7801
7802        Binder.restoreCallingIdentity(origId);
7803    }
7804
7805    @Override
7806    public final void activityDestroyed(IBinder token) {
7807        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7808        synchronized (this) {
7809            ActivityStack stack = ActivityRecord.getStackLocked(token);
7810            if (stack != null) {
7811                stack.activityDestroyedLocked(token, "activityDestroyed");
7812            }
7813        }
7814    }
7815
7816    @Override
7817    public final void activityRelaunched(IBinder token) {
7818        final long origId = Binder.clearCallingIdentity();
7819        synchronized (this) {
7820            mStackSupervisor.activityRelaunchedLocked(token);
7821        }
7822        Binder.restoreCallingIdentity(origId);
7823    }
7824
7825    @Override
7826    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7827            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7828        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7829                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7830        synchronized (this) {
7831            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7832            if (record == null) {
7833                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7834                        + "found for: " + token);
7835            }
7836            record.setSizeConfigurations(horizontalSizeConfiguration,
7837                    verticalSizeConfigurations, smallestSizeConfigurations);
7838        }
7839    }
7840
7841    @Override
7842    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7843        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7844    }
7845
7846    @Override
7847    public final void notifyEnterAnimationComplete(IBinder token) {
7848        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7849    }
7850
7851    @Override
7852    public String getCallingPackage(IBinder token) {
7853        synchronized (this) {
7854            ActivityRecord r = getCallingRecordLocked(token);
7855            return r != null ? r.info.packageName : null;
7856        }
7857    }
7858
7859    @Override
7860    public ComponentName getCallingActivity(IBinder token) {
7861        synchronized (this) {
7862            ActivityRecord r = getCallingRecordLocked(token);
7863            return r != null ? r.intent.getComponent() : null;
7864        }
7865    }
7866
7867    private ActivityRecord getCallingRecordLocked(IBinder token) {
7868        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7869        if (r == null) {
7870            return null;
7871        }
7872        return r.resultTo;
7873    }
7874
7875    @Override
7876    public ComponentName getActivityClassForToken(IBinder token) {
7877        synchronized(this) {
7878            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7879            if (r == null) {
7880                return null;
7881            }
7882            return r.intent.getComponent();
7883        }
7884    }
7885
7886    @Override
7887    public String getPackageForToken(IBinder token) {
7888        synchronized(this) {
7889            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7890            if (r == null) {
7891                return null;
7892            }
7893            return r.packageName;
7894        }
7895    }
7896
7897    @Override
7898    public boolean isRootVoiceInteraction(IBinder token) {
7899        synchronized(this) {
7900            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7901            if (r == null) {
7902                return false;
7903            }
7904            return r.rootVoiceInteraction;
7905        }
7906    }
7907
7908    @Override
7909    public IIntentSender getIntentSender(int type,
7910            String packageName, IBinder token, String resultWho,
7911            int requestCode, Intent[] intents, String[] resolvedTypes,
7912            int flags, Bundle bOptions, int userId) {
7913        enforceNotIsolatedCaller("getIntentSender");
7914        // Refuse possible leaked file descriptors
7915        if (intents != null) {
7916            if (intents.length < 1) {
7917                throw new IllegalArgumentException("Intents array length must be >= 1");
7918            }
7919            for (int i=0; i<intents.length; i++) {
7920                Intent intent = intents[i];
7921                if (intent != null) {
7922                    if (intent.hasFileDescriptors()) {
7923                        throw new IllegalArgumentException("File descriptors passed in Intent");
7924                    }
7925                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7926                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7927                        throw new IllegalArgumentException(
7928                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7929                    }
7930                    intents[i] = new Intent(intent);
7931                }
7932            }
7933            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7934                throw new IllegalArgumentException(
7935                        "Intent array length does not match resolvedTypes length");
7936            }
7937        }
7938        if (bOptions != null) {
7939            if (bOptions.hasFileDescriptors()) {
7940                throw new IllegalArgumentException("File descriptors passed in options");
7941            }
7942        }
7943
7944        synchronized(this) {
7945            int callingUid = Binder.getCallingUid();
7946            int origUserId = userId;
7947            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7948                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7949                    ALLOW_NON_FULL, "getIntentSender", null);
7950            if (origUserId == UserHandle.USER_CURRENT) {
7951                // We don't want to evaluate this until the pending intent is
7952                // actually executed.  However, we do want to always do the
7953                // security checking for it above.
7954                userId = UserHandle.USER_CURRENT;
7955            }
7956            try {
7957                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7958                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7959                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7960                    if (!UserHandle.isSameApp(callingUid, uid)) {
7961                        String msg = "Permission Denial: getIntentSender() from pid="
7962                            + Binder.getCallingPid()
7963                            + ", uid=" + Binder.getCallingUid()
7964                            + ", (need uid=" + uid + ")"
7965                            + " is not allowed to send as package " + packageName;
7966                        Slog.w(TAG, msg);
7967                        throw new SecurityException(msg);
7968                    }
7969                }
7970
7971                return getIntentSenderLocked(type, packageName, callingUid, userId,
7972                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7973
7974            } catch (RemoteException e) {
7975                throw new SecurityException(e);
7976            }
7977        }
7978    }
7979
7980    IIntentSender getIntentSenderLocked(int type, String packageName,
7981            int callingUid, int userId, IBinder token, String resultWho,
7982            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7983            Bundle bOptions) {
7984        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7985        ActivityRecord activity = null;
7986        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7987            activity = ActivityRecord.isInStackLocked(token);
7988            if (activity == null) {
7989                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7990                return null;
7991            }
7992            if (activity.finishing) {
7993                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7994                return null;
7995            }
7996        }
7997
7998        // We're going to be splicing together extras before sending, so we're
7999        // okay poking into any contained extras.
8000        if (intents != null) {
8001            for (int i = 0; i < intents.length; i++) {
8002                intents[i].setDefusable(true);
8003            }
8004        }
8005        Bundle.setDefusable(bOptions, true);
8006
8007        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
8008        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
8009        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
8010        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
8011                |PendingIntent.FLAG_UPDATE_CURRENT);
8012
8013        PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
8014                resultWho, requestCode, intents, resolvedTypes, flags,
8015                SafeActivityOptions.fromBundle(bOptions), userId);
8016        WeakReference<PendingIntentRecord> ref;
8017        ref = mIntentSenderRecords.get(key);
8018        PendingIntentRecord rec = ref != null ? ref.get() : null;
8019        if (rec != null) {
8020            if (!cancelCurrent) {
8021                if (updateCurrent) {
8022                    if (rec.key.requestIntent != null) {
8023                        rec.key.requestIntent.replaceExtras(intents != null ?
8024                                intents[intents.length - 1] : null);
8025                    }
8026                    if (intents != null) {
8027                        intents[intents.length-1] = rec.key.requestIntent;
8028                        rec.key.allIntents = intents;
8029                        rec.key.allResolvedTypes = resolvedTypes;
8030                    } else {
8031                        rec.key.allIntents = null;
8032                        rec.key.allResolvedTypes = null;
8033                    }
8034                }
8035                return rec;
8036            }
8037            makeIntentSenderCanceledLocked(rec);
8038            mIntentSenderRecords.remove(key);
8039        }
8040        if (noCreate) {
8041            return rec;
8042        }
8043        rec = new PendingIntentRecord(this, key, callingUid);
8044        mIntentSenderRecords.put(key, rec.ref);
8045        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8046            if (activity.pendingResults == null) {
8047                activity.pendingResults
8048                        = new HashSet<WeakReference<PendingIntentRecord>>();
8049            }
8050            activity.pendingResults.add(rec.ref);
8051        }
8052        return rec;
8053    }
8054
8055    @Override
8056    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
8057            Intent intent, String resolvedType,
8058            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
8059        if (target instanceof PendingIntentRecord) {
8060            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
8061                    whitelistToken, finishedReceiver, requiredPermission, options);
8062        } else {
8063            if (intent == null) {
8064                // Weird case: someone has given us their own custom IIntentSender, and now
8065                // they have someone else trying to send to it but of course this isn't
8066                // really a PendingIntent, so there is no base Intent, and the caller isn't
8067                // supplying an Intent... but we never want to dispatch a null Intent to
8068                // a receiver, so um...  let's make something up.
8069                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
8070                intent = new Intent(Intent.ACTION_MAIN);
8071            }
8072            try {
8073                target.send(code, intent, resolvedType, whitelistToken, null,
8074                        requiredPermission, options);
8075            } catch (RemoteException e) {
8076            }
8077            // Platform code can rely on getting a result back when the send is done, but if
8078            // this intent sender is from outside of the system we can't rely on it doing that.
8079            // So instead we don't give it the result receiver, and instead just directly
8080            // report the finish immediately.
8081            if (finishedReceiver != null) {
8082                try {
8083                    finishedReceiver.performReceive(intent, 0,
8084                            null, null, false, false, UserHandle.getCallingUserId());
8085                } catch (RemoteException e) {
8086                }
8087            }
8088            return 0;
8089        }
8090    }
8091
8092    @Override
8093    public void cancelIntentSender(IIntentSender sender) {
8094        if (!(sender instanceof PendingIntentRecord)) {
8095            return;
8096        }
8097        synchronized(this) {
8098            PendingIntentRecord rec = (PendingIntentRecord)sender;
8099            try {
8100                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8101                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8102                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8103                    String msg = "Permission Denial: cancelIntentSender() from pid="
8104                        + Binder.getCallingPid()
8105                        + ", uid=" + Binder.getCallingUid()
8106                        + " is not allowed to cancel package "
8107                        + rec.key.packageName;
8108                    Slog.w(TAG, msg);
8109                    throw new SecurityException(msg);
8110                }
8111            } catch (RemoteException e) {
8112                throw new SecurityException(e);
8113            }
8114            cancelIntentSenderLocked(rec, true);
8115        }
8116    }
8117
8118    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8119        makeIntentSenderCanceledLocked(rec);
8120        mIntentSenderRecords.remove(rec.key);
8121        if (cleanActivity && rec.key.activity != null) {
8122            rec.key.activity.pendingResults.remove(rec.ref);
8123        }
8124    }
8125
8126    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8127        rec.canceled = true;
8128        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8129        if (callbacks != null) {
8130            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8131        }
8132    }
8133
8134    @Override
8135    public String getPackageForIntentSender(IIntentSender pendingResult) {
8136        if (!(pendingResult instanceof PendingIntentRecord)) {
8137            return null;
8138        }
8139        try {
8140            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8141            return res.key.packageName;
8142        } catch (ClassCastException e) {
8143        }
8144        return null;
8145    }
8146
8147    @Override
8148    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8149        if (!(sender instanceof PendingIntentRecord)) {
8150            return;
8151        }
8152        synchronized(this) {
8153            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
8154        }
8155    }
8156
8157    @Override
8158    public void unregisterIntentSenderCancelListener(IIntentSender sender,
8159            IResultReceiver receiver) {
8160        if (!(sender instanceof PendingIntentRecord)) {
8161            return;
8162        }
8163        synchronized(this) {
8164            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8165        }
8166    }
8167
8168    @Override
8169    public int getUidForIntentSender(IIntentSender sender) {
8170        if (sender instanceof PendingIntentRecord) {
8171            try {
8172                PendingIntentRecord res = (PendingIntentRecord)sender;
8173                return res.uid;
8174            } catch (ClassCastException e) {
8175            }
8176        }
8177        return -1;
8178    }
8179
8180    @Override
8181    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8182        if (!(pendingResult instanceof PendingIntentRecord)) {
8183            return false;
8184        }
8185        try {
8186            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8187            if (res.key.allIntents == null) {
8188                return false;
8189            }
8190            for (int i=0; i<res.key.allIntents.length; i++) {
8191                Intent intent = res.key.allIntents[i];
8192                if (intent.getPackage() != null && intent.getComponent() != null) {
8193                    return false;
8194                }
8195            }
8196            return true;
8197        } catch (ClassCastException e) {
8198        }
8199        return false;
8200    }
8201
8202    @Override
8203    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8204        if (!(pendingResult instanceof PendingIntentRecord)) {
8205            return false;
8206        }
8207        try {
8208            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8209            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8210                return true;
8211            }
8212            return false;
8213        } catch (ClassCastException e) {
8214        }
8215        return false;
8216    }
8217
8218    @Override
8219    public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8220        if (pendingResult instanceof PendingIntentRecord) {
8221            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8222            return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8223        }
8224        return false;
8225    }
8226
8227    @Override
8228    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8229        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8230                "getIntentForIntentSender()");
8231        if (!(pendingResult instanceof PendingIntentRecord)) {
8232            return null;
8233        }
8234        try {
8235            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8236            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8237        } catch (ClassCastException e) {
8238        }
8239        return null;
8240    }
8241
8242    @Override
8243    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8244        if (!(pendingResult instanceof PendingIntentRecord)) {
8245            return null;
8246        }
8247        try {
8248            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8249            synchronized (this) {
8250                return getTagForIntentSenderLocked(res, prefix);
8251            }
8252        } catch (ClassCastException e) {
8253        }
8254        return null;
8255    }
8256
8257    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8258        final Intent intent = res.key.requestIntent;
8259        if (intent != null) {
8260            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8261                    || res.lastTagPrefix.equals(prefix))) {
8262                return res.lastTag;
8263            }
8264            res.lastTagPrefix = prefix;
8265            final StringBuilder sb = new StringBuilder(128);
8266            if (prefix != null) {
8267                sb.append(prefix);
8268            }
8269            if (intent.getAction() != null) {
8270                sb.append(intent.getAction());
8271            } else if (intent.getComponent() != null) {
8272                intent.getComponent().appendShortString(sb);
8273            } else {
8274                sb.append("?");
8275            }
8276            return res.lastTag = sb.toString();
8277        }
8278        return null;
8279    }
8280
8281    @Override
8282    public void setProcessLimit(int max) {
8283        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8284                "setProcessLimit()");
8285        synchronized (this) {
8286            mConstants.setOverrideMaxCachedProcesses(max);
8287        }
8288        trimApplications();
8289    }
8290
8291    @Override
8292    public int getProcessLimit() {
8293        synchronized (this) {
8294            return mConstants.getOverrideMaxCachedProcesses();
8295        }
8296    }
8297
8298    void importanceTokenDied(ImportanceToken token) {
8299        synchronized (ActivityManagerService.this) {
8300            synchronized (mPidsSelfLocked) {
8301                ImportanceToken cur
8302                    = mImportantProcesses.get(token.pid);
8303                if (cur != token) {
8304                    return;
8305                }
8306                mImportantProcesses.remove(token.pid);
8307                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8308                if (pr == null) {
8309                    return;
8310                }
8311                pr.forcingToImportant = null;
8312                updateProcessForegroundLocked(pr, false, false);
8313            }
8314            updateOomAdjLocked();
8315        }
8316    }
8317
8318    @Override
8319    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8320        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8321                "setProcessImportant()");
8322        synchronized(this) {
8323            boolean changed = false;
8324
8325            synchronized (mPidsSelfLocked) {
8326                ProcessRecord pr = mPidsSelfLocked.get(pid);
8327                if (pr == null && isForeground) {
8328                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8329                    return;
8330                }
8331                ImportanceToken oldToken = mImportantProcesses.get(pid);
8332                if (oldToken != null) {
8333                    oldToken.token.unlinkToDeath(oldToken, 0);
8334                    mImportantProcesses.remove(pid);
8335                    if (pr != null) {
8336                        pr.forcingToImportant = null;
8337                    }
8338                    changed = true;
8339                }
8340                if (isForeground && token != null) {
8341                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8342                        @Override
8343                        public void binderDied() {
8344                            importanceTokenDied(this);
8345                        }
8346                    };
8347                    try {
8348                        token.linkToDeath(newToken, 0);
8349                        mImportantProcesses.put(pid, newToken);
8350                        pr.forcingToImportant = newToken;
8351                        changed = true;
8352                    } catch (RemoteException e) {
8353                        // If the process died while doing this, we will later
8354                        // do the cleanup with the process death link.
8355                    }
8356                }
8357            }
8358
8359            if (changed) {
8360                updateOomAdjLocked();
8361            }
8362        }
8363    }
8364
8365    @Override
8366    public boolean isAppForeground(int uid) throws RemoteException {
8367        synchronized (this) {
8368            UidRecord uidRec = mActiveUids.get(uid);
8369            if (uidRec == null || uidRec.idle) {
8370                return false;
8371            }
8372            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8373        }
8374    }
8375
8376    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8377    // be guarded by permission checking.
8378    int getUidState(int uid) {
8379        synchronized (this) {
8380            return getUidStateLocked(uid);
8381        }
8382    }
8383
8384    int getUidStateLocked(int uid) {
8385        UidRecord uidRec = mActiveUids.get(uid);
8386        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8387    }
8388
8389    @Override
8390    public boolean isInMultiWindowMode(IBinder token) {
8391        final long origId = Binder.clearCallingIdentity();
8392        try {
8393            synchronized(this) {
8394                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8395                if (r == null) {
8396                    return false;
8397                }
8398                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8399                return r.inMultiWindowMode();
8400            }
8401        } finally {
8402            Binder.restoreCallingIdentity(origId);
8403        }
8404    }
8405
8406    @Override
8407    public boolean isInPictureInPictureMode(IBinder token) {
8408        final long origId = Binder.clearCallingIdentity();
8409        try {
8410            synchronized(this) {
8411                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8412            }
8413        } finally {
8414            Binder.restoreCallingIdentity(origId);
8415        }
8416    }
8417
8418    private boolean isInPictureInPictureMode(ActivityRecord r) {
8419        if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8420                || r.getStack().isInStackLocked(r) == null) {
8421            return false;
8422        }
8423
8424        // If we are animating to fullscreen then we have already dispatched the PIP mode
8425        // changed, so we should reflect that check here as well.
8426        final PinnedActivityStack stack = r.getStack();
8427        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8428        return !windowController.isAnimatingBoundsToFullscreen();
8429    }
8430
8431    @Override
8432    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8433        final long origId = Binder.clearCallingIdentity();
8434        try {
8435            synchronized(this) {
8436                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8437                        "enterPictureInPictureMode", token, params);
8438
8439                // If the activity is already in picture in picture mode, then just return early
8440                if (isInPictureInPictureMode(r)) {
8441                    return true;
8442                }
8443
8444                // Activity supports picture-in-picture, now check that we can enter PiP at this
8445                // point, if it is
8446                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8447                        false /* beforeStopping */)) {
8448                    return false;
8449                }
8450
8451                final Runnable enterPipRunnable = () -> {
8452                    // Only update the saved args from the args that are set
8453                    r.pictureInPictureArgs.copyOnlySet(params);
8454                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8455                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8456                    // Adjust the source bounds by the insets for the transition down
8457                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8458                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8459                            "enterPictureInPictureMode");
8460                    final PinnedActivityStack stack = r.getStack();
8461                    stack.setPictureInPictureAspectRatio(aspectRatio);
8462                    stack.setPictureInPictureActions(actions);
8463
8464                    MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.supportsEnterPipOnTaskSwitch);
8465                    logPictureInPictureArgs(params);
8466                };
8467
8468                if (isKeyguardLocked()) {
8469                    // If the keyguard is showing or occluded, then try and dismiss it before
8470                    // entering picture-in-picture (this will prompt the user to authenticate if the
8471                    // device is currently locked).
8472                    try {
8473                        dismissKeyguard(token, new KeyguardDismissCallback() {
8474                            @Override
8475                            public void onDismissSucceeded() throws RemoteException {
8476                                mHandler.post(enterPipRunnable);
8477                            }
8478                        }, null /* message */);
8479                    } catch (RemoteException e) {
8480                        // Local call
8481                    }
8482                } else {
8483                    // Enter picture in picture immediately otherwise
8484                    enterPipRunnable.run();
8485                }
8486                return true;
8487            }
8488        } finally {
8489            Binder.restoreCallingIdentity(origId);
8490        }
8491    }
8492
8493    @Override
8494    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8495        final long origId = Binder.clearCallingIdentity();
8496        try {
8497            synchronized(this) {
8498                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8499                        "setPictureInPictureParams", token, params);
8500
8501                // Only update the saved args from the args that are set
8502                r.pictureInPictureArgs.copyOnlySet(params);
8503                if (r.inPinnedWindowingMode()) {
8504                    // If the activity is already in picture-in-picture, update the pinned stack now
8505                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8506                    // be used the next time the activity enters PiP
8507                    final PinnedActivityStack stack = r.getStack();
8508                    if (!stack.isAnimatingBoundsToFullscreen()) {
8509                        stack.setPictureInPictureAspectRatio(
8510                                r.pictureInPictureArgs.getAspectRatio());
8511                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8512                    }
8513                }
8514                logPictureInPictureArgs(params);
8515            }
8516        } finally {
8517            Binder.restoreCallingIdentity(origId);
8518        }
8519    }
8520
8521    @Override
8522    public int getMaxNumPictureInPictureActions(IBinder token) {
8523        // Currently, this is a static constant, but later, we may change this to be dependent on
8524        // the context of the activity
8525        return 3;
8526    }
8527
8528    private void logPictureInPictureArgs(PictureInPictureParams params) {
8529        if (params.hasSetActions()) {
8530            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8531                    params.getActions().size());
8532        }
8533        if (params.hasSetAspectRatio()) {
8534            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8535            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8536            MetricsLogger.action(lm);
8537        }
8538    }
8539
8540    /**
8541     * Checks the state of the system and the activity associated with the given {@param token} to
8542     * verify that picture-in-picture is supported for that activity.
8543     *
8544     * @return the activity record for the given {@param token} if all the checks pass.
8545     */
8546    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8547            IBinder token, PictureInPictureParams params) {
8548        if (!mSupportsPictureInPicture) {
8549            throw new IllegalStateException(caller
8550                    + ": Device doesn't support picture-in-picture mode.");
8551        }
8552
8553        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8554        if (r == null) {
8555            throw new IllegalStateException(caller
8556                    + ": Can't find activity for token=" + token);
8557        }
8558
8559        if (!r.supportsPictureInPicture()) {
8560            throw new IllegalStateException(caller
8561                    + ": Current activity does not support picture-in-picture.");
8562        }
8563
8564        if (params.hasSetAspectRatio()
8565                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8566                        params.getAspectRatio())) {
8567            final float minAspectRatio = mContext.getResources().getFloat(
8568                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8569            final float maxAspectRatio = mContext.getResources().getFloat(
8570                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8571            throw new IllegalArgumentException(String.format(caller
8572                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8573                            minAspectRatio, maxAspectRatio));
8574        }
8575
8576        // Truncate the number of actions if necessary
8577        params.truncateActions(getMaxNumPictureInPictureActions(token));
8578
8579        return r;
8580    }
8581
8582    // =========================================================
8583    // PROCESS INFO
8584    // =========================================================
8585
8586    static class ProcessInfoService extends IProcessInfoService.Stub {
8587        final ActivityManagerService mActivityManagerService;
8588        ProcessInfoService(ActivityManagerService activityManagerService) {
8589            mActivityManagerService = activityManagerService;
8590        }
8591
8592        @Override
8593        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8594            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8595                    /*in*/ pids, /*out*/ states, null);
8596        }
8597
8598        @Override
8599        public void getProcessStatesAndOomScoresFromPids(
8600                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8601            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8602                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8603        }
8604    }
8605
8606    /**
8607     * For each PID in the given input array, write the current process state
8608     * for that process into the states array, or -1 to indicate that no
8609     * process with the given PID exists. If scores array is provided, write
8610     * the oom score for the process into the scores array, with INVALID_ADJ
8611     * indicating the PID doesn't exist.
8612     */
8613    public void getProcessStatesAndOomScoresForPIDs(
8614            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8615        if (scores != null) {
8616            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8617                    "getProcessStatesAndOomScoresForPIDs()");
8618        }
8619
8620        if (pids == null) {
8621            throw new NullPointerException("pids");
8622        } else if (states == null) {
8623            throw new NullPointerException("states");
8624        } else if (pids.length != states.length) {
8625            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8626        } else if (scores != null && pids.length != scores.length) {
8627            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8628        }
8629
8630        synchronized (mPidsSelfLocked) {
8631            for (int i = 0; i < pids.length; i++) {
8632                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8633                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8634                        pr.curProcState;
8635                if (scores != null) {
8636                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8637                }
8638            }
8639        }
8640    }
8641
8642    // =========================================================
8643    // PERMISSIONS
8644    // =========================================================
8645
8646    static class PermissionController extends IPermissionController.Stub {
8647        ActivityManagerService mActivityManagerService;
8648        PermissionController(ActivityManagerService activityManagerService) {
8649            mActivityManagerService = activityManagerService;
8650        }
8651
8652        @Override
8653        public boolean checkPermission(String permission, int pid, int uid) {
8654            return mActivityManagerService.checkPermission(permission, pid,
8655                    uid) == PackageManager.PERMISSION_GRANTED;
8656        }
8657
8658        @Override
8659        public String[] getPackagesForUid(int uid) {
8660            return mActivityManagerService.mContext.getPackageManager()
8661                    .getPackagesForUid(uid);
8662        }
8663
8664        @Override
8665        public boolean isRuntimePermission(String permission) {
8666            try {
8667                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8668                        .getPermissionInfo(permission, 0);
8669                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8670                        == PermissionInfo.PROTECTION_DANGEROUS;
8671            } catch (NameNotFoundException nnfe) {
8672                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8673            }
8674            return false;
8675        }
8676
8677        @Override
8678        public int getPackageUid(String packageName, int flags) {
8679            try {
8680                return mActivityManagerService.mContext.getPackageManager()
8681                        .getPackageUid(packageName, flags);
8682            } catch (NameNotFoundException nnfe) {
8683                return -1;
8684            }
8685        }
8686    }
8687
8688    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8689        @Override
8690        public int checkComponentPermission(String permission, int pid, int uid,
8691                int owningUid, boolean exported) {
8692            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8693                    owningUid, exported);
8694        }
8695
8696        @Override
8697        public Object getAMSLock() {
8698            return ActivityManagerService.this;
8699        }
8700    }
8701
8702    int checkComponentPermission(String permission, int pid, int uid,
8703            int owningUid, boolean exported) {
8704        if (pid == MY_PID) {
8705            return PackageManager.PERMISSION_GRANTED;
8706        }
8707        return ActivityManager.checkComponentPermission(permission, uid,
8708                owningUid, exported);
8709    }
8710
8711    /**
8712     * As the only public entry point for permissions checking, this method
8713     * can enforce the semantic that requesting a check on a null global
8714     * permission is automatically denied.  (Internally a null permission
8715     * string is used when calling {@link #checkComponentPermission} in cases
8716     * when only uid-based security is needed.)
8717     *
8718     * This can be called with or without the global lock held.
8719     */
8720    @Override
8721    public int checkPermission(String permission, int pid, int uid) {
8722        if (permission == null) {
8723            return PackageManager.PERMISSION_DENIED;
8724        }
8725        return checkComponentPermission(permission, pid, uid, -1, true);
8726    }
8727
8728    @Override
8729    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8730        if (permission == null) {
8731            return PackageManager.PERMISSION_DENIED;
8732        }
8733
8734        // We might be performing an operation on behalf of an indirect binder
8735        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8736        // client identity accordingly before proceeding.
8737        Identity tlsIdentity = sCallerIdentity.get();
8738        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8739            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8740                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8741            uid = tlsIdentity.uid;
8742            pid = tlsIdentity.pid;
8743        }
8744
8745        return checkComponentPermission(permission, pid, uid, -1, true);
8746    }
8747
8748    /**
8749     * Binder IPC calls go through the public entry point.
8750     * This can be called with or without the global lock held.
8751     */
8752    int checkCallingPermission(String permission) {
8753        return checkPermission(permission,
8754                Binder.getCallingPid(),
8755                UserHandle.getAppId(Binder.getCallingUid()));
8756    }
8757
8758    /**
8759     * This can be called with or without the global lock held.
8760     */
8761    void enforceCallingPermission(String permission, String func) {
8762        if (checkCallingPermission(permission)
8763                == PackageManager.PERMISSION_GRANTED) {
8764            return;
8765        }
8766
8767        String msg = "Permission Denial: " + func + " from pid="
8768                + Binder.getCallingPid()
8769                + ", uid=" + Binder.getCallingUid()
8770                + " requires " + permission;
8771        Slog.w(TAG, msg);
8772        throw new SecurityException(msg);
8773    }
8774
8775    /**
8776     * This can be called with or without the global lock held.
8777     */
8778    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
8779        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
8780            enforceCallingPermission(permission, func);
8781        }
8782    }
8783
8784    /**
8785     * Determine if UID is holding permissions required to access {@link Uri} in
8786     * the given {@link ProviderInfo}. Final permission checking is always done
8787     * in {@link ContentProvider}.
8788     */
8789    private final boolean checkHoldingPermissionsLocked(
8790            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8791        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8792                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8793        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8794            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8795                    != PERMISSION_GRANTED) {
8796                return false;
8797            }
8798        }
8799        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8800    }
8801
8802    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8803            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8804        if (pi.applicationInfo.uid == uid) {
8805            return true;
8806        } else if (!pi.exported) {
8807            return false;
8808        }
8809
8810        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8811        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8812        try {
8813            // check if target holds top-level <provider> permissions
8814            if (!readMet && pi.readPermission != null && considerUidPermissions
8815                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8816                readMet = true;
8817            }
8818            if (!writeMet && pi.writePermission != null && considerUidPermissions
8819                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8820                writeMet = true;
8821            }
8822
8823            // track if unprotected read/write is allowed; any denied
8824            // <path-permission> below removes this ability
8825            boolean allowDefaultRead = pi.readPermission == null;
8826            boolean allowDefaultWrite = pi.writePermission == null;
8827
8828            // check if target holds any <path-permission> that match uri
8829            final PathPermission[] pps = pi.pathPermissions;
8830            if (pps != null) {
8831                final String path = grantUri.uri.getPath();
8832                int i = pps.length;
8833                while (i > 0 && (!readMet || !writeMet)) {
8834                    i--;
8835                    PathPermission pp = pps[i];
8836                    if (pp.match(path)) {
8837                        if (!readMet) {
8838                            final String pprperm = pp.getReadPermission();
8839                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8840                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8841                                    + ": match=" + pp.match(path)
8842                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8843                            if (pprperm != null) {
8844                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8845                                        == PERMISSION_GRANTED) {
8846                                    readMet = true;
8847                                } else {
8848                                    allowDefaultRead = false;
8849                                }
8850                            }
8851                        }
8852                        if (!writeMet) {
8853                            final String ppwperm = pp.getWritePermission();
8854                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8855                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8856                                    + ": match=" + pp.match(path)
8857                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8858                            if (ppwperm != null) {
8859                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8860                                        == PERMISSION_GRANTED) {
8861                                    writeMet = true;
8862                                } else {
8863                                    allowDefaultWrite = false;
8864                                }
8865                            }
8866                        }
8867                    }
8868                }
8869            }
8870
8871            // grant unprotected <provider> read/write, if not blocked by
8872            // <path-permission> above
8873            if (allowDefaultRead) readMet = true;
8874            if (allowDefaultWrite) writeMet = true;
8875
8876        } catch (RemoteException e) {
8877            return false;
8878        }
8879
8880        return readMet && writeMet;
8881    }
8882
8883    public boolean isAppStartModeDisabled(int uid, String packageName) {
8884        synchronized (this) {
8885            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8886                    == ActivityManager.APP_START_MODE_DISABLED;
8887        }
8888    }
8889
8890    // Unified app-op and target sdk check
8891    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8892        // Apps that target O+ are always subject to background check
8893        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8894            if (DEBUG_BACKGROUND_CHECK) {
8895                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8896            }
8897            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8898        }
8899        // ...and legacy apps get an AppOp check
8900        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8901                uid, packageName);
8902        if (DEBUG_BACKGROUND_CHECK) {
8903            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8904        }
8905        switch (appop) {
8906            case AppOpsManager.MODE_ALLOWED:
8907                // If force-background-check is enabled, restrict all apps that aren't whitelisted.
8908                if (mForceBackgroundCheck &&
8909                        !UserHandle.isCore(uid) &&
8910                        !isOnDeviceIdleWhitelistLocked(uid)) {
8911                    if (DEBUG_BACKGROUND_CHECK) {
8912                        Slog.i(TAG, "Force background check: " +
8913                                uid + "/" + packageName + " restricted");
8914                    }
8915                    return ActivityManager.APP_START_MODE_DELAYED;
8916                }
8917                return ActivityManager.APP_START_MODE_NORMAL;
8918            case AppOpsManager.MODE_IGNORED:
8919                return ActivityManager.APP_START_MODE_DELAYED;
8920            default:
8921                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8922        }
8923    }
8924
8925    // Service launch is available to apps with run-in-background exemptions but
8926    // some other background operations are not.  If we're doing a check
8927    // of service-launch policy, allow those callers to proceed unrestricted.
8928    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8929        // Persistent app?
8930        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8931            if (DEBUG_BACKGROUND_CHECK) {
8932                Slog.i(TAG, "App " + uid + "/" + packageName
8933                        + " is persistent; not restricted in background");
8934            }
8935            return ActivityManager.APP_START_MODE_NORMAL;
8936        }
8937
8938        // Non-persistent but background whitelisted?
8939        if (uidOnBackgroundWhitelist(uid)) {
8940            if (DEBUG_BACKGROUND_CHECK) {
8941                Slog.i(TAG, "App " + uid + "/" + packageName
8942                        + " on background whitelist; not restricted in background");
8943            }
8944            return ActivityManager.APP_START_MODE_NORMAL;
8945        }
8946
8947        // Is this app on the battery whitelist?
8948        if (isOnDeviceIdleWhitelistLocked(uid)) {
8949            if (DEBUG_BACKGROUND_CHECK) {
8950                Slog.i(TAG, "App " + uid + "/" + packageName
8951                        + " on idle whitelist; not restricted in background");
8952            }
8953            return ActivityManager.APP_START_MODE_NORMAL;
8954        }
8955
8956        // None of the service-policy criteria apply, so we apply the common criteria
8957        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8958    }
8959
8960    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8961            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8962        UidRecord uidRec = mActiveUids.get(uid);
8963        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8964                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8965                + (uidRec != null ? uidRec.idle : false));
8966        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8967            boolean ephemeral;
8968            if (uidRec == null) {
8969                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8970                        UserHandle.getUserId(uid), packageName);
8971            } else {
8972                ephemeral = uidRec.ephemeral;
8973            }
8974
8975            if (ephemeral) {
8976                // We are hard-core about ephemeral apps not running in the background.
8977                return ActivityManager.APP_START_MODE_DISABLED;
8978            } else {
8979                if (disabledOnly) {
8980                    // The caller is only interested in whether app starts are completely
8981                    // disabled for the given package (that is, it is an instant app).  So
8982                    // we don't need to go further, which is all just seeing if we should
8983                    // apply a "delayed" mode for a regular app.
8984                    return ActivityManager.APP_START_MODE_NORMAL;
8985                }
8986                final int startMode = (alwaysRestrict)
8987                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8988                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8989                                packageTargetSdk);
8990                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8991                        + " pkg=" + packageName + " startMode=" + startMode
8992                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8993                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8994                    // This is an old app that has been forced into a "compatible as possible"
8995                    // mode of background check.  To increase compatibility, we will allow other
8996                    // foreground apps to cause its services to start.
8997                    if (callingPid >= 0) {
8998                        ProcessRecord proc;
8999                        synchronized (mPidsSelfLocked) {
9000                            proc = mPidsSelfLocked.get(callingPid);
9001                        }
9002                        if (proc != null &&
9003                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
9004                            // Whoever is instigating this is in the foreground, so we will allow it
9005                            // to go through.
9006                            return ActivityManager.APP_START_MODE_NORMAL;
9007                        }
9008                    }
9009                }
9010                return startMode;
9011            }
9012        }
9013        return ActivityManager.APP_START_MODE_NORMAL;
9014    }
9015
9016    /**
9017     * @return whether a UID is in the system, user or temp doze whitelist.
9018     */
9019    boolean isOnDeviceIdleWhitelistLocked(int uid) {
9020        final int appId = UserHandle.getAppId(uid);
9021        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
9022                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9023                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9024    }
9025
9026    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9027        ProviderInfo pi = null;
9028        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9029        if (cpr != null) {
9030            pi = cpr.info;
9031        } else {
9032            try {
9033                pi = AppGlobals.getPackageManager().resolveContentProvider(
9034                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9035                        userHandle);
9036            } catch (RemoteException ex) {
9037            }
9038        }
9039        return pi;
9040    }
9041
9042    void grantEphemeralAccessLocked(int userId, Intent intent,
9043            int targetAppId, int ephemeralAppId) {
9044        getPackageManagerInternalLocked().
9045                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
9046    }
9047
9048    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
9049        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9050        if (targetUris != null) {
9051            return targetUris.get(grantUri);
9052        }
9053        return null;
9054    }
9055
9056    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
9057            String targetPkg, int targetUid, GrantUri grantUri) {
9058        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9059        if (targetUris == null) {
9060            targetUris = Maps.newArrayMap();
9061            mGrantedUriPermissions.put(targetUid, targetUris);
9062        }
9063
9064        UriPermission perm = targetUris.get(grantUri);
9065        if (perm == null) {
9066            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9067            targetUris.put(grantUri, perm);
9068        }
9069
9070        return perm;
9071    }
9072
9073    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
9074            final int modeFlags) {
9075        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
9076        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9077                : UriPermission.STRENGTH_OWNED;
9078
9079        // Root gets to do everything.
9080        if (uid == 0) {
9081            return true;
9082        }
9083
9084        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9085        if (perms == null) return false;
9086
9087        // First look for exact match
9088        final UriPermission exactPerm = perms.get(grantUri);
9089        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9090            return true;
9091        }
9092
9093        // No exact match, look for prefixes
9094        final int N = perms.size();
9095        for (int i = 0; i < N; i++) {
9096            final UriPermission perm = perms.valueAt(i);
9097            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9098                    && perm.getStrength(modeFlags) >= minStrength) {
9099                return true;
9100            }
9101        }
9102
9103        return false;
9104    }
9105
9106    /**
9107     * @param uri This uri must NOT contain an embedded userId.
9108     * @param userId The userId in which the uri is to be resolved.
9109     */
9110    @Override
9111    public int checkUriPermission(Uri uri, int pid, int uid,
9112            final int modeFlags, int userId, IBinder callerToken) {
9113        enforceNotIsolatedCaller("checkUriPermission");
9114
9115        // Another redirected-binder-call permissions check as in
9116        // {@link checkPermissionWithToken}.
9117        Identity tlsIdentity = sCallerIdentity.get();
9118        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9119            uid = tlsIdentity.uid;
9120            pid = tlsIdentity.pid;
9121        }
9122
9123        // Our own process gets to do everything.
9124        if (pid == MY_PID) {
9125            return PackageManager.PERMISSION_GRANTED;
9126        }
9127        synchronized (this) {
9128            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9129                    ? PackageManager.PERMISSION_GRANTED
9130                    : PackageManager.PERMISSION_DENIED;
9131        }
9132    }
9133
9134    /**
9135     * Check if the targetPkg can be granted permission to access uri by
9136     * the callingUid using the given modeFlags.  Throws a security exception
9137     * if callingUid is not allowed to do this.  Returns the uid of the target
9138     * if the URI permission grant should be performed; returns -1 if it is not
9139     * needed (for example targetPkg already has permission to access the URI).
9140     * If you already know the uid of the target, you can supply it in
9141     * lastTargetUid else set that to -1.
9142     */
9143    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9144            final int modeFlags, int lastTargetUid) {
9145        if (!Intent.isAccessUriMode(modeFlags)) {
9146            return -1;
9147        }
9148
9149        if (targetPkg != null) {
9150            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9151                    "Checking grant " + targetPkg + " permission to " + grantUri);
9152        }
9153
9154        final IPackageManager pm = AppGlobals.getPackageManager();
9155
9156        // If this is not a content: uri, we can't do anything with it.
9157        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9158            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9159                    "Can't grant URI permission for non-content URI: " + grantUri);
9160            return -1;
9161        }
9162
9163        // Bail early if system is trying to hand out permissions directly; it
9164        // must always grant permissions on behalf of someone explicit.
9165        final int callingAppId = UserHandle.getAppId(callingUid);
9166        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9167            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9168                // Exempted authority for
9169                // 1. cropping user photos and sharing a generated license html
9170                //    file in Settings app
9171                // 2. sharing a generated license html file in TvSettings app
9172            } else {
9173                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9174                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9175                return -1;
9176            }
9177        }
9178
9179        final String authority = grantUri.uri.getAuthority();
9180        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9181                MATCH_DEBUG_TRIAGED_MISSING);
9182        if (pi == null) {
9183            Slog.w(TAG, "No content provider found for permission check: " +
9184                    grantUri.uri.toSafeString());
9185            return -1;
9186        }
9187
9188        int targetUid = lastTargetUid;
9189        if (targetUid < 0 && targetPkg != null) {
9190            try {
9191                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9192                        UserHandle.getUserId(callingUid));
9193                if (targetUid < 0) {
9194                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9195                            "Can't grant URI permission no uid for: " + targetPkg);
9196                    return -1;
9197                }
9198            } catch (RemoteException ex) {
9199                return -1;
9200            }
9201        }
9202
9203        // If we're extending a persistable grant, then we always need to create
9204        // the grant data structure so that take/release APIs work
9205        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9206            return targetUid;
9207        }
9208
9209        if (targetUid >= 0) {
9210            // First...  does the target actually need this permission?
9211            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9212                // No need to grant the target this permission.
9213                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9214                        "Target " + targetPkg + " already has full permission to " + grantUri);
9215                return -1;
9216            }
9217        } else {
9218            // First...  there is no target package, so can anyone access it?
9219            boolean allowed = pi.exported;
9220            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9221                if (pi.readPermission != null) {
9222                    allowed = false;
9223                }
9224            }
9225            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9226                if (pi.writePermission != null) {
9227                    allowed = false;
9228                }
9229            }
9230            if (allowed) {
9231                return -1;
9232            }
9233        }
9234
9235        /* There is a special cross user grant if:
9236         * - The target is on another user.
9237         * - Apps on the current user can access the uri without any uid permissions.
9238         * In this case, we grant a uri permission, even if the ContentProvider does not normally
9239         * grant uri permissions.
9240         */
9241        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9242                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9243                modeFlags, false /*without considering the uid permissions*/);
9244
9245        // Second...  is the provider allowing granting of URI permissions?
9246        if (!specialCrossUserGrant) {
9247            if (!pi.grantUriPermissions) {
9248                throw new SecurityException("Provider " + pi.packageName
9249                        + "/" + pi.name
9250                        + " does not allow granting of Uri permissions (uri "
9251                        + grantUri + ")");
9252            }
9253            if (pi.uriPermissionPatterns != null) {
9254                final int N = pi.uriPermissionPatterns.length;
9255                boolean allowed = false;
9256                for (int i=0; i<N; i++) {
9257                    if (pi.uriPermissionPatterns[i] != null
9258                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9259                        allowed = true;
9260                        break;
9261                    }
9262                }
9263                if (!allowed) {
9264                    throw new SecurityException("Provider " + pi.packageName
9265                            + "/" + pi.name
9266                            + " does not allow granting of permission to path of Uri "
9267                            + grantUri);
9268                }
9269            }
9270        }
9271
9272        // Third...  does the caller itself have permission to access
9273        // this uri?
9274        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9275            // Require they hold a strong enough Uri permission
9276            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9277                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9278                    throw new SecurityException(
9279                            "UID " + callingUid + " does not have permission to " + grantUri
9280                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9281                                    + "or related APIs");
9282                } else {
9283                    throw new SecurityException(
9284                            "UID " + callingUid + " does not have permission to " + grantUri);
9285                }
9286            }
9287        }
9288        return targetUid;
9289    }
9290
9291    /**
9292     * @param uri This uri must NOT contain an embedded userId.
9293     * @param userId The userId in which the uri is to be resolved.
9294     */
9295    @Override
9296    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9297            final int modeFlags, int userId) {
9298        enforceNotIsolatedCaller("checkGrantUriPermission");
9299        synchronized(this) {
9300            return checkGrantUriPermissionLocked(callingUid, targetPkg,
9301                    new GrantUri(userId, uri, false), modeFlags, -1);
9302        }
9303    }
9304
9305    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9306            final int modeFlags, UriPermissionOwner owner) {
9307        if (!Intent.isAccessUriMode(modeFlags)) {
9308            return;
9309        }
9310
9311        // So here we are: the caller has the assumed permission
9312        // to the uri, and the target doesn't.  Let's now give this to
9313        // the target.
9314
9315        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9316                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9317
9318        final String authority = grantUri.uri.getAuthority();
9319        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9320                MATCH_DEBUG_TRIAGED_MISSING);
9321        if (pi == null) {
9322            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9323            return;
9324        }
9325
9326        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9327            grantUri.prefix = true;
9328        }
9329        final UriPermission perm = findOrCreateUriPermissionLocked(
9330                pi.packageName, targetPkg, targetUid, grantUri);
9331        perm.grantModes(modeFlags, owner);
9332    }
9333
9334    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9335            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9336        if (targetPkg == null) {
9337            throw new NullPointerException("targetPkg");
9338        }
9339        int targetUid;
9340        final IPackageManager pm = AppGlobals.getPackageManager();
9341        try {
9342            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9343        } catch (RemoteException ex) {
9344            return;
9345        }
9346
9347        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9348                targetUid);
9349        if (targetUid < 0) {
9350            return;
9351        }
9352
9353        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9354                owner);
9355    }
9356
9357    static class NeededUriGrants extends ArrayList<GrantUri> {
9358        final String targetPkg;
9359        final int targetUid;
9360        final int flags;
9361
9362        NeededUriGrants(String targetPkg, int targetUid, int flags) {
9363            this.targetPkg = targetPkg;
9364            this.targetUid = targetUid;
9365            this.flags = flags;
9366        }
9367
9368        void writeToProto(ProtoOutputStream proto, long fieldId) {
9369            long token = proto.start(fieldId);
9370            proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9371            proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9372            proto.write(NeededUriGrantsProto.FLAGS, flags);
9373
9374            final int N = this.size();
9375            for (int i=0; i<N; i++) {
9376                this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9377            }
9378            proto.end(token);
9379        }
9380    }
9381
9382    /**
9383     * Like checkGrantUriPermissionLocked, but takes an Intent.
9384     */
9385    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9386            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9387        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9388                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9389                + " clip=" + (intent != null ? intent.getClipData() : null)
9390                + " from " + intent + "; flags=0x"
9391                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9392
9393        if (targetPkg == null) {
9394            throw new NullPointerException("targetPkg");
9395        }
9396
9397        if (intent == null) {
9398            return null;
9399        }
9400        Uri data = intent.getData();
9401        ClipData clip = intent.getClipData();
9402        if (data == null && clip == null) {
9403            return null;
9404        }
9405        // Default userId for uris in the intent (if they don't specify it themselves)
9406        int contentUserHint = intent.getContentUserHint();
9407        if (contentUserHint == UserHandle.USER_CURRENT) {
9408            contentUserHint = UserHandle.getUserId(callingUid);
9409        }
9410        final IPackageManager pm = AppGlobals.getPackageManager();
9411        int targetUid;
9412        if (needed != null) {
9413            targetUid = needed.targetUid;
9414        } else {
9415            try {
9416                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9417                        targetUserId);
9418            } catch (RemoteException ex) {
9419                return null;
9420            }
9421            if (targetUid < 0) {
9422                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9423                        "Can't grant URI permission no uid for: " + targetPkg
9424                        + " on user " + targetUserId);
9425                return null;
9426            }
9427        }
9428        if (data != null) {
9429            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9430            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9431                    targetUid);
9432            if (targetUid > 0) {
9433                if (needed == null) {
9434                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9435                }
9436                needed.add(grantUri);
9437            }
9438        }
9439        if (clip != null) {
9440            for (int i=0; i<clip.getItemCount(); i++) {
9441                Uri uri = clip.getItemAt(i).getUri();
9442                if (uri != null) {
9443                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9444                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9445                            targetUid);
9446                    if (targetUid > 0) {
9447                        if (needed == null) {
9448                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9449                        }
9450                        needed.add(grantUri);
9451                    }
9452                } else {
9453                    Intent clipIntent = clip.getItemAt(i).getIntent();
9454                    if (clipIntent != null) {
9455                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9456                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9457                        if (newNeeded != null) {
9458                            needed = newNeeded;
9459                        }
9460                    }
9461                }
9462            }
9463        }
9464
9465        return needed;
9466    }
9467
9468    /**
9469     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9470     */
9471    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9472            UriPermissionOwner owner) {
9473        if (needed != null) {
9474            for (int i=0; i<needed.size(); i++) {
9475                GrantUri grantUri = needed.get(i);
9476                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9477                        grantUri, needed.flags, owner);
9478            }
9479        }
9480    }
9481
9482    void grantUriPermissionFromIntentLocked(int callingUid,
9483            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9484        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9485                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9486        if (needed == null) {
9487            return;
9488        }
9489
9490        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9491    }
9492
9493    /**
9494     * @param uri This uri must NOT contain an embedded userId.
9495     * @param userId The userId in which the uri is to be resolved.
9496     */
9497    @Override
9498    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9499            final int modeFlags, int userId) {
9500        enforceNotIsolatedCaller("grantUriPermission");
9501        GrantUri grantUri = new GrantUri(userId, uri, false);
9502        synchronized(this) {
9503            final ProcessRecord r = getRecordForAppLocked(caller);
9504            if (r == null) {
9505                throw new SecurityException("Unable to find app for caller "
9506                        + caller
9507                        + " when granting permission to uri " + grantUri);
9508            }
9509            if (targetPkg == null) {
9510                throw new IllegalArgumentException("null target");
9511            }
9512            if (grantUri == null) {
9513                throw new IllegalArgumentException("null uri");
9514            }
9515
9516            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9517                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9518                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9519                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9520
9521            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9522                    UserHandle.getUserId(r.uid));
9523        }
9524    }
9525
9526    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9527        if (perm.modeFlags == 0) {
9528            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9529                    perm.targetUid);
9530            if (perms != null) {
9531                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9532                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9533
9534                perms.remove(perm.uri);
9535                if (perms.isEmpty()) {
9536                    mGrantedUriPermissions.remove(perm.targetUid);
9537                }
9538            }
9539        }
9540    }
9541
9542    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9543            final int modeFlags) {
9544        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9545                "Revoking all granted permissions to " + grantUri);
9546
9547        final IPackageManager pm = AppGlobals.getPackageManager();
9548        final String authority = grantUri.uri.getAuthority();
9549        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9550                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9551        if (pi == null) {
9552            Slog.w(TAG, "No content provider found for permission revoke: "
9553                    + grantUri.toSafeString());
9554            return;
9555        }
9556
9557        // Does the caller have this permission on the URI?
9558        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9559            // If they don't have direct access to the URI, then revoke any
9560            // ownerless URI permissions that have been granted to them.
9561            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9562            if (perms != null) {
9563                boolean persistChanged = false;
9564                for (int i = perms.size()-1; i >= 0; i--) {
9565                    final UriPermission perm = perms.valueAt(i);
9566                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9567                        continue;
9568                    }
9569                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9570                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9571                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9572                                "Revoking non-owned " + perm.targetUid
9573                                + " permission to " + perm.uri);
9574                        persistChanged |= perm.revokeModes(
9575                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9576                        if (perm.modeFlags == 0) {
9577                            perms.removeAt(i);
9578                        }
9579                    }
9580                }
9581                if (perms.isEmpty()) {
9582                    mGrantedUriPermissions.remove(callingUid);
9583                }
9584                if (persistChanged) {
9585                    schedulePersistUriGrants();
9586                }
9587            }
9588            return;
9589        }
9590
9591        boolean persistChanged = false;
9592
9593        // Go through all of the permissions and remove any that match.
9594        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9595            final int targetUid = mGrantedUriPermissions.keyAt(i);
9596            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9597
9598            for (int j = perms.size()-1; j >= 0; j--) {
9599                final UriPermission perm = perms.valueAt(j);
9600                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9601                    continue;
9602                }
9603                if (perm.uri.sourceUserId == grantUri.sourceUserId
9604                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9605                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9606                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9607                    persistChanged |= perm.revokeModes(
9608                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9609                            targetPackage == null);
9610                    if (perm.modeFlags == 0) {
9611                        perms.removeAt(j);
9612                    }
9613                }
9614            }
9615
9616            if (perms.isEmpty()) {
9617                mGrantedUriPermissions.removeAt(i);
9618            }
9619        }
9620
9621        if (persistChanged) {
9622            schedulePersistUriGrants();
9623        }
9624    }
9625
9626    /**
9627     * @param uri This uri must NOT contain an embedded userId.
9628     * @param userId The userId in which the uri is to be resolved.
9629     */
9630    @Override
9631    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9632            final int modeFlags, int userId) {
9633        enforceNotIsolatedCaller("revokeUriPermission");
9634        synchronized(this) {
9635            final ProcessRecord r = getRecordForAppLocked(caller);
9636            if (r == null) {
9637                throw new SecurityException("Unable to find app for caller "
9638                        + caller
9639                        + " when revoking permission to uri " + uri);
9640            }
9641            if (uri == null) {
9642                Slog.w(TAG, "revokeUriPermission: null uri");
9643                return;
9644            }
9645
9646            if (!Intent.isAccessUriMode(modeFlags)) {
9647                return;
9648            }
9649
9650            final String authority = uri.getAuthority();
9651            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9652                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9653            if (pi == null) {
9654                Slog.w(TAG, "No content provider found for permission revoke: "
9655                        + uri.toSafeString());
9656                return;
9657            }
9658
9659            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9660                    modeFlags);
9661        }
9662    }
9663
9664    /**
9665     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9666     * given package.
9667     *
9668     * @param packageName Package name to match, or {@code null} to apply to all
9669     *            packages.
9670     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9671     *            to all users.
9672     * @param persistable If persistable grants should be removed.
9673     */
9674    private void removeUriPermissionsForPackageLocked(
9675            String packageName, int userHandle, boolean persistable) {
9676        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9677            throw new IllegalArgumentException("Must narrow by either package or user");
9678        }
9679
9680        boolean persistChanged = false;
9681
9682        int N = mGrantedUriPermissions.size();
9683        for (int i = 0; i < N; i++) {
9684            final int targetUid = mGrantedUriPermissions.keyAt(i);
9685            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9686
9687            // Only inspect grants matching user
9688            if (userHandle == UserHandle.USER_ALL
9689                    || userHandle == UserHandle.getUserId(targetUid)) {
9690                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9691                    final UriPermission perm = it.next();
9692
9693                    // Only inspect grants matching package
9694                    if (packageName == null || perm.sourcePkg.equals(packageName)
9695                            || perm.targetPkg.equals(packageName)) {
9696                        // Hacky solution as part of fixing a security bug; ignore
9697                        // grants associated with DownloadManager so we don't have
9698                        // to immediately launch it to regrant the permissions
9699                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9700                                && !persistable) continue;
9701
9702                        persistChanged |= perm.revokeModes(persistable
9703                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9704
9705                        // Only remove when no modes remain; any persisted grants
9706                        // will keep this alive.
9707                        if (perm.modeFlags == 0) {
9708                            it.remove();
9709                        }
9710                    }
9711                }
9712
9713                if (perms.isEmpty()) {
9714                    mGrantedUriPermissions.remove(targetUid);
9715                    N--;
9716                    i--;
9717                }
9718            }
9719        }
9720
9721        if (persistChanged) {
9722            schedulePersistUriGrants();
9723        }
9724    }
9725
9726    @Override
9727    public IBinder newUriPermissionOwner(String name) {
9728        enforceNotIsolatedCaller("newUriPermissionOwner");
9729        synchronized(this) {
9730            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9731            return owner.getExternalTokenLocked();
9732        }
9733    }
9734
9735    @Override
9736    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9737        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9738        synchronized(this) {
9739            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9740            if (r == null) {
9741                throw new IllegalArgumentException("Activity does not exist; token="
9742                        + activityToken);
9743            }
9744            return r.getUriPermissionsLocked().getExternalTokenLocked();
9745        }
9746    }
9747    /**
9748     * @param uri This uri must NOT contain an embedded userId.
9749     * @param sourceUserId The userId in which the uri is to be resolved.
9750     * @param targetUserId The userId of the app that receives the grant.
9751     */
9752    @Override
9753    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9754            final int modeFlags, int sourceUserId, int targetUserId) {
9755        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9756                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9757                "grantUriPermissionFromOwner", null);
9758        synchronized(this) {
9759            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9760            if (owner == null) {
9761                throw new IllegalArgumentException("Unknown owner: " + token);
9762            }
9763            if (fromUid != Binder.getCallingUid()) {
9764                if (Binder.getCallingUid() != myUid()) {
9765                    // Only system code can grant URI permissions on behalf
9766                    // of other users.
9767                    throw new SecurityException("nice try");
9768                }
9769            }
9770            if (targetPkg == null) {
9771                throw new IllegalArgumentException("null target");
9772            }
9773            if (uri == null) {
9774                throw new IllegalArgumentException("null uri");
9775            }
9776
9777            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9778                    modeFlags, owner, targetUserId);
9779        }
9780    }
9781
9782    /**
9783     * @param uri This uri must NOT contain an embedded userId.
9784     * @param userId The userId in which the uri is to be resolved.
9785     */
9786    @Override
9787    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9788        synchronized(this) {
9789            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9790            if (owner == null) {
9791                throw new IllegalArgumentException("Unknown owner: " + token);
9792            }
9793
9794            if (uri == null) {
9795                owner.removeUriPermissionsLocked(mode);
9796            } else {
9797                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9798                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9799            }
9800        }
9801    }
9802
9803    private void schedulePersistUriGrants() {
9804        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9805            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9806                    10 * DateUtils.SECOND_IN_MILLIS);
9807        }
9808    }
9809
9810    private void writeGrantedUriPermissions() {
9811        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9812
9813        // Snapshot permissions so we can persist without lock
9814        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9815        synchronized (this) {
9816            final int size = mGrantedUriPermissions.size();
9817            for (int i = 0; i < size; i++) {
9818                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9819                for (UriPermission perm : perms.values()) {
9820                    if (perm.persistedModeFlags != 0) {
9821                        persist.add(perm.snapshot());
9822                    }
9823                }
9824            }
9825        }
9826
9827        FileOutputStream fos = null;
9828        try {
9829            fos = mGrantFile.startWrite();
9830
9831            XmlSerializer out = new FastXmlSerializer();
9832            out.setOutput(fos, StandardCharsets.UTF_8.name());
9833            out.startDocument(null, true);
9834            out.startTag(null, TAG_URI_GRANTS);
9835            for (UriPermission.Snapshot perm : persist) {
9836                out.startTag(null, TAG_URI_GRANT);
9837                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9838                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9839                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9840                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9841                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9842                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9843                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9844                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9845                out.endTag(null, TAG_URI_GRANT);
9846            }
9847            out.endTag(null, TAG_URI_GRANTS);
9848            out.endDocument();
9849
9850            mGrantFile.finishWrite(fos);
9851        } catch (IOException e) {
9852            if (fos != null) {
9853                mGrantFile.failWrite(fos);
9854            }
9855        }
9856    }
9857
9858    private void readGrantedUriPermissionsLocked() {
9859        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9860
9861        final long now = System.currentTimeMillis();
9862
9863        FileInputStream fis = null;
9864        try {
9865            fis = mGrantFile.openRead();
9866            final XmlPullParser in = Xml.newPullParser();
9867            in.setInput(fis, StandardCharsets.UTF_8.name());
9868
9869            int type;
9870            while ((type = in.next()) != END_DOCUMENT) {
9871                final String tag = in.getName();
9872                if (type == START_TAG) {
9873                    if (TAG_URI_GRANT.equals(tag)) {
9874                        final int sourceUserId;
9875                        final int targetUserId;
9876                        final int userHandle = readIntAttribute(in,
9877                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9878                        if (userHandle != UserHandle.USER_NULL) {
9879                            // For backwards compatibility.
9880                            sourceUserId = userHandle;
9881                            targetUserId = userHandle;
9882                        } else {
9883                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9884                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9885                        }
9886                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9887                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9888                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9889                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9890                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9891                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9892
9893                        // Sanity check that provider still belongs to source package
9894                        // Both direct boot aware and unaware packages are fine as we
9895                        // will do filtering at query time to avoid multiple parsing.
9896                        final ProviderInfo pi = getProviderInfoLocked(
9897                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9898                                        | MATCH_DIRECT_BOOT_UNAWARE);
9899                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9900                            int targetUid = -1;
9901                            try {
9902                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9903                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9904                            } catch (RemoteException e) {
9905                            }
9906                            if (targetUid != -1) {
9907                                final UriPermission perm = findOrCreateUriPermissionLocked(
9908                                        sourcePkg, targetPkg, targetUid,
9909                                        new GrantUri(sourceUserId, uri, prefix));
9910                                perm.initPersistedModes(modeFlags, createdTime);
9911                            }
9912                        } else {
9913                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9914                                    + " but instead found " + pi);
9915                        }
9916                    }
9917                }
9918            }
9919        } catch (FileNotFoundException e) {
9920            // Missing grants is okay
9921        } catch (IOException e) {
9922            Slog.wtf(TAG, "Failed reading Uri grants", e);
9923        } catch (XmlPullParserException e) {
9924            Slog.wtf(TAG, "Failed reading Uri grants", e);
9925        } finally {
9926            IoUtils.closeQuietly(fis);
9927        }
9928    }
9929
9930    /**
9931     * @param uri This uri must NOT contain an embedded userId.
9932     * @param userId The userId in which the uri is to be resolved.
9933     */
9934    @Override
9935    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9936        enforceNotIsolatedCaller("takePersistableUriPermission");
9937
9938        Preconditions.checkFlagsArgument(modeFlags,
9939                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9940
9941        synchronized (this) {
9942            final int callingUid = Binder.getCallingUid();
9943            boolean persistChanged = false;
9944            GrantUri grantUri = new GrantUri(userId, uri, false);
9945
9946            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9947                    new GrantUri(userId, uri, false));
9948            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9949                    new GrantUri(userId, uri, true));
9950
9951            final boolean exactValid = (exactPerm != null)
9952                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9953            final boolean prefixValid = (prefixPerm != null)
9954                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9955
9956            if (!(exactValid || prefixValid)) {
9957                throw new SecurityException("No persistable permission grants found for UID "
9958                        + callingUid + " and Uri " + grantUri.toSafeString());
9959            }
9960
9961            if (exactValid) {
9962                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9963            }
9964            if (prefixValid) {
9965                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9966            }
9967
9968            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9969
9970            if (persistChanged) {
9971                schedulePersistUriGrants();
9972            }
9973        }
9974    }
9975
9976    /**
9977     * @param uri This uri must NOT contain an embedded userId.
9978     * @param userId The userId in which the uri is to be resolved.
9979     */
9980    @Override
9981    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9982        enforceNotIsolatedCaller("releasePersistableUriPermission");
9983
9984        Preconditions.checkFlagsArgument(modeFlags,
9985                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9986
9987        synchronized (this) {
9988            final int callingUid = Binder.getCallingUid();
9989            boolean persistChanged = false;
9990
9991            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9992                    new GrantUri(userId, uri, false));
9993            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9994                    new GrantUri(userId, uri, true));
9995            if (exactPerm == null && prefixPerm == null) {
9996                throw new SecurityException("No permission grants found for UID " + callingUid
9997                        + " and Uri " + uri.toSafeString());
9998            }
9999
10000            if (exactPerm != null) {
10001                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10002                removeUriPermissionIfNeededLocked(exactPerm);
10003            }
10004            if (prefixPerm != null) {
10005                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10006                removeUriPermissionIfNeededLocked(prefixPerm);
10007            }
10008
10009            if (persistChanged) {
10010                schedulePersistUriGrants();
10011            }
10012        }
10013    }
10014
10015    /**
10016     * Prune any older {@link UriPermission} for the given UID until outstanding
10017     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10018     *
10019     * @return if any mutations occured that require persisting.
10020     */
10021    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
10022        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
10023        if (perms == null) return false;
10024        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
10025
10026        final ArrayList<UriPermission> persisted = Lists.newArrayList();
10027        for (UriPermission perm : perms.values()) {
10028            if (perm.persistedModeFlags != 0) {
10029                persisted.add(perm);
10030            }
10031        }
10032
10033        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10034        if (trimCount <= 0) return false;
10035
10036        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10037        for (int i = 0; i < trimCount; i++) {
10038            final UriPermission perm = persisted.get(i);
10039
10040            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10041                    "Trimming grant created at " + perm.persistedCreateTime);
10042
10043            perm.releasePersistableModes(~0);
10044            removeUriPermissionIfNeededLocked(perm);
10045        }
10046
10047        return true;
10048    }
10049
10050    @Override
10051    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10052            String packageName, boolean incoming) {
10053        enforceNotIsolatedCaller("getPersistedUriPermissions");
10054        Preconditions.checkNotNull(packageName, "packageName");
10055
10056        final int callingUid = Binder.getCallingUid();
10057        final int callingUserId = UserHandle.getUserId(callingUid);
10058        final IPackageManager pm = AppGlobals.getPackageManager();
10059        try {
10060            final int packageUid = pm.getPackageUid(packageName,
10061                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
10062            if (packageUid != callingUid) {
10063                throw new SecurityException(
10064                        "Package " + packageName + " does not belong to calling UID " + callingUid);
10065            }
10066        } catch (RemoteException e) {
10067            throw new SecurityException("Failed to verify package name ownership");
10068        }
10069
10070        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10071        synchronized (this) {
10072            if (incoming) {
10073                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10074                        callingUid);
10075                if (perms == null) {
10076                    Slog.w(TAG, "No permission grants found for " + packageName);
10077                } else {
10078                    for (UriPermission perm : perms.values()) {
10079                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10080                            result.add(perm.buildPersistedPublicApiObject());
10081                        }
10082                    }
10083                }
10084            } else {
10085                final int size = mGrantedUriPermissions.size();
10086                for (int i = 0; i < size; i++) {
10087                    final ArrayMap<GrantUri, UriPermission> perms =
10088                            mGrantedUriPermissions.valueAt(i);
10089                    for (UriPermission perm : perms.values()) {
10090                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10091                            result.add(perm.buildPersistedPublicApiObject());
10092                        }
10093                    }
10094                }
10095            }
10096        }
10097        return new ParceledListSlice<android.content.UriPermission>(result);
10098    }
10099
10100    @Override
10101    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
10102            String packageName, int userId) {
10103        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10104                "getGrantedUriPermissions");
10105
10106        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10107        synchronized (this) {
10108            final int size = mGrantedUriPermissions.size();
10109            for (int i = 0; i < size; i++) {
10110                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10111                for (UriPermission perm : perms.values()) {
10112                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
10113                            && perm.persistedModeFlags != 0) {
10114                        result.add(perm.buildPersistedPublicApiObject());
10115                    }
10116                }
10117            }
10118        }
10119        return new ParceledListSlice<android.content.UriPermission>(result);
10120    }
10121
10122    @Override
10123    public void clearGrantedUriPermissions(String packageName, int userId) {
10124        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10125                "clearGrantedUriPermissions");
10126        removeUriPermissionsForPackageLocked(packageName, userId, true);
10127    }
10128
10129    @Override
10130    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10131        synchronized (this) {
10132            ProcessRecord app =
10133                who != null ? getRecordForAppLocked(who) : null;
10134            if (app == null) return;
10135
10136            Message msg = Message.obtain();
10137            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10138            msg.obj = app;
10139            msg.arg1 = waiting ? 1 : 0;
10140            mUiHandler.sendMessage(msg);
10141        }
10142    }
10143
10144    @Override
10145    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10146        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10147        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10148        outInfo.availMem = getFreeMemory();
10149        outInfo.totalMem = getTotalMemory();
10150        outInfo.threshold = homeAppMem;
10151        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10152        outInfo.hiddenAppThreshold = cachedAppMem;
10153        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10154                ProcessList.SERVICE_ADJ);
10155        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10156                ProcessList.VISIBLE_APP_ADJ);
10157        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10158                ProcessList.FOREGROUND_APP_ADJ);
10159    }
10160
10161    // =========================================================
10162    // TASK MANAGEMENT
10163    // =========================================================
10164
10165    @Override
10166    public List<IBinder> getAppTasks(String callingPackage) {
10167        int callingUid = Binder.getCallingUid();
10168        long ident = Binder.clearCallingIdentity();
10169        try {
10170            synchronized(this) {
10171                return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10172            }
10173        } finally {
10174            Binder.restoreCallingIdentity(ident);
10175        }
10176    }
10177
10178    @Override
10179    public List<RunningTaskInfo> getTasks(int maxNum) {
10180       return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10181    }
10182
10183    @Override
10184    public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10185            @WindowingMode int ignoreWindowingMode) {
10186        final int callingUid = Binder.getCallingUid();
10187        ArrayList<RunningTaskInfo> list = new ArrayList<>();
10188
10189        synchronized(this) {
10190            if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10191
10192            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10193                    callingUid);
10194            mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10195                    ignoreWindowingMode, callingUid, allowed);
10196        }
10197
10198        return list;
10199    }
10200
10201    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10202        if (mRecentTasks.isCallerRecents(callingUid)) {
10203            // Always allow the recents component to get tasks
10204            return true;
10205        }
10206
10207        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10208                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10209        if (!allowed) {
10210            if (checkPermission(android.Manifest.permission.GET_TASKS,
10211                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10212                // Temporary compatibility: some existing apps on the system image may
10213                // still be requesting the old permission and not switched to the new
10214                // one; if so, we'll still allow them full access.  This means we need
10215                // to see if they are holding the old permission and are a system app.
10216                try {
10217                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10218                        allowed = true;
10219                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10220                                + " is using old GET_TASKS but privileged; allowing");
10221                    }
10222                } catch (RemoteException e) {
10223                }
10224            }
10225        }
10226        if (!allowed) {
10227            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10228                    + " does not hold REAL_GET_TASKS; limiting output");
10229        }
10230        return allowed;
10231    }
10232
10233    @Override
10234    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10235            int userId) {
10236        final int callingUid = Binder.getCallingUid();
10237        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10238                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10239        final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10240                callingUid);
10241        final boolean detailed = checkCallingPermission(
10242                android.Manifest.permission.GET_DETAILED_TASKS)
10243                        == PackageManager.PERMISSION_GRANTED;
10244
10245        synchronized (this) {
10246            return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10247                    callingUid);
10248        }
10249    }
10250
10251    @Override
10252    public ActivityManager.TaskDescription getTaskDescription(int id) {
10253        synchronized (this) {
10254            enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10255            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10256                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10257            if (tr != null) {
10258                return tr.lastTaskDescription;
10259            }
10260        }
10261        return null;
10262    }
10263
10264    @Override
10265    public int addAppTask(IBinder activityToken, Intent intent,
10266            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10267        final int callingUid = Binder.getCallingUid();
10268        final long callingIdent = Binder.clearCallingIdentity();
10269
10270        try {
10271            synchronized (this) {
10272                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10273                if (r == null) {
10274                    throw new IllegalArgumentException("Activity does not exist; token="
10275                            + activityToken);
10276                }
10277                ComponentName comp = intent.getComponent();
10278                if (comp == null) {
10279                    throw new IllegalArgumentException("Intent " + intent
10280                            + " must specify explicit component");
10281                }
10282                if (thumbnail.getWidth() != mThumbnailWidth
10283                        || thumbnail.getHeight() != mThumbnailHeight) {
10284                    throw new IllegalArgumentException("Bad thumbnail size: got "
10285                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10286                            + mThumbnailWidth + "x" + mThumbnailHeight);
10287                }
10288                if (intent.getSelector() != null) {
10289                    intent.setSelector(null);
10290                }
10291                if (intent.getSourceBounds() != null) {
10292                    intent.setSourceBounds(null);
10293                }
10294                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10295                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10296                        // The caller has added this as an auto-remove task...  that makes no
10297                        // sense, so turn off auto-remove.
10298                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10299                    }
10300                }
10301                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10302                    mLastAddedTaskActivity = null;
10303                }
10304                ActivityInfo ainfo = mLastAddedTaskActivity;
10305                if (ainfo == null) {
10306                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10307                            comp, 0, UserHandle.getUserId(callingUid));
10308                    if (ainfo.applicationInfo.uid != callingUid) {
10309                        throw new SecurityException(
10310                                "Can't add task for another application: target uid="
10311                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10312                    }
10313                }
10314
10315                TaskRecord task = TaskRecord.create(this,
10316                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10317                        ainfo, intent, description);
10318                if (!mRecentTasks.addToBottom(task)) {
10319                    return INVALID_TASK_ID;
10320                }
10321                r.getStack().addTask(task, !ON_TOP, "addAppTask");
10322
10323                // TODO: Send the thumbnail to WM to store it.
10324
10325                return task.taskId;
10326            }
10327        } finally {
10328            Binder.restoreCallingIdentity(callingIdent);
10329        }
10330    }
10331
10332    @Override
10333    public Point getAppTaskThumbnailSize() {
10334        synchronized (this) {
10335            return new Point(mThumbnailWidth,  mThumbnailHeight);
10336        }
10337    }
10338
10339    @Override
10340    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10341        synchronized (this) {
10342            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10343            if (r != null) {
10344                r.setTaskDescription(td);
10345                final TaskRecord task = r.getTask();
10346                task.updateTaskDescription();
10347                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10348            }
10349        }
10350    }
10351
10352    @Override
10353    public void setTaskResizeable(int taskId, int resizeableMode) {
10354        synchronized (this) {
10355            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10356                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10357            if (task == null) {
10358                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10359                return;
10360            }
10361            task.setResizeMode(resizeableMode);
10362        }
10363    }
10364
10365    @Override
10366    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10367        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10368        long ident = Binder.clearCallingIdentity();
10369        try {
10370            synchronized (this) {
10371                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10372                if (task == null) {
10373                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10374                    return;
10375                }
10376                // Place the task in the right stack if it isn't there already based on
10377                // the requested bounds.
10378                // The stack transition logic is:
10379                // - a null bounds on a freeform task moves that task to fullscreen
10380                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10381                //   that task to freeform
10382                // - otherwise the task is not moved
10383                ActivityStack stack = task.getStack();
10384                if (!task.getWindowConfiguration().canResizeTask()) {
10385                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10386                }
10387                if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10388                    stack = stack.getDisplay().getOrCreateStack(
10389                            WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10390                } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10391                    stack = stack.getDisplay().getOrCreateStack(
10392                            WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10393                }
10394
10395                // Reparent the task to the right stack if necessary
10396                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10397                if (stack != task.getStack()) {
10398                    // Defer resume until the task is resized below
10399                    task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10400                            DEFER_RESUME, "resizeTask");
10401                    preserveWindow = false;
10402                }
10403
10404                // After reparenting (which only resizes the task to the stack bounds), resize the
10405                // task to the actual bounds provided
10406                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10407            }
10408        } finally {
10409            Binder.restoreCallingIdentity(ident);
10410        }
10411    }
10412
10413    @Override
10414    public Rect getTaskBounds(int taskId) {
10415        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10416        long ident = Binder.clearCallingIdentity();
10417        Rect rect = new Rect();
10418        try {
10419            synchronized (this) {
10420                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10421                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10422                if (task == null) {
10423                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10424                    return rect;
10425                }
10426                if (task.getStack() != null) {
10427                    // Return the bounds from window manager since it will be adjusted for various
10428                    // things like the presense of a docked stack for tasks that aren't resizeable.
10429                    task.getWindowContainerBounds(rect);
10430                } else {
10431                    // Task isn't in window manager yet since it isn't associated with a stack.
10432                    // Return the persist value from activity manager
10433                    if (!task.matchParentBounds()) {
10434                        rect.set(task.getBounds());
10435                    } else if (task.mLastNonFullscreenBounds != null) {
10436                        rect.set(task.mLastNonFullscreenBounds);
10437                    }
10438                }
10439            }
10440        } finally {
10441            Binder.restoreCallingIdentity(ident);
10442        }
10443        return rect;
10444    }
10445
10446    @Override
10447    public void cancelTaskWindowTransition(int taskId) {
10448        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10449                "cancelTaskWindowTransition()");
10450        final long ident = Binder.clearCallingIdentity();
10451        try {
10452            synchronized (this) {
10453                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10454                        MATCH_TASK_IN_STACKS_ONLY);
10455                if (task == null) {
10456                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10457                    return;
10458                }
10459                task.cancelWindowTransition();
10460            }
10461        } finally {
10462            Binder.restoreCallingIdentity(ident);
10463        }
10464    }
10465
10466    @Override
10467    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10468        enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10469        final long ident = Binder.clearCallingIdentity();
10470        try {
10471            final TaskRecord task;
10472            synchronized (this) {
10473                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10474                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10475                if (task == null) {
10476                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10477                    return null;
10478                }
10479            }
10480            // Don't call this while holding the lock as this operation might hit the disk.
10481            return task.getSnapshot(reducedResolution);
10482        } finally {
10483            Binder.restoreCallingIdentity(ident);
10484        }
10485    }
10486
10487    @Override
10488    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10489        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10490                userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
10491
10492        final File passedIconFile = new File(filePath);
10493        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10494                passedIconFile.getName());
10495        if (!legitIconFile.getPath().equals(filePath)
10496                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10497            throw new IllegalArgumentException("Bad file path: " + filePath
10498                    + " passed for userId " + userId);
10499        }
10500        return mRecentTasks.getTaskDescriptionIcon(filePath);
10501    }
10502
10503    @Override
10504    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10505            throws RemoteException {
10506        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
10507        final ActivityOptions activityOptions = safeOptions != null
10508                ? safeOptions.getOptions(mStackSupervisor)
10509                : null;
10510        if (activityOptions == null
10511                || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
10512                || activityOptions.getCustomInPlaceResId() == 0) {
10513            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10514                    "with valid animation");
10515        }
10516        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10517        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10518                activityOptions.getCustomInPlaceResId());
10519        mWindowManager.executeAppTransition();
10520    }
10521
10522    @Override
10523    public void removeStack(int stackId) {
10524        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
10525        synchronized (this) {
10526            final long ident = Binder.clearCallingIdentity();
10527            try {
10528                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10529                if (stack == null) {
10530                    Slog.w(TAG, "removeStack: No stack with id=" + stackId);
10531                    return;
10532                }
10533                if (!stack.isActivityTypeStandardOrUndefined()) {
10534                    throw new IllegalArgumentException(
10535                            "Removing non-standard stack is not allowed.");
10536                }
10537                mStackSupervisor.removeStack(stack);
10538            } finally {
10539                Binder.restoreCallingIdentity(ident);
10540            }
10541        }
10542    }
10543
10544    /**
10545     * Removes stacks in the input windowing modes from the system if they are of activity type
10546     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
10547     */
10548    @Override
10549    public void removeStacksInWindowingModes(int[] windowingModes) {
10550        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10551                "removeStacksInWindowingModes()");
10552        synchronized (this) {
10553            final long ident = Binder.clearCallingIdentity();
10554            try {
10555                mStackSupervisor.removeStacksInWindowingModes(windowingModes);
10556            } finally {
10557                Binder.restoreCallingIdentity(ident);
10558            }
10559        }
10560    }
10561
10562    @Override
10563    public void removeStacksWithActivityTypes(int[] activityTypes) {
10564        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10565                "removeStacksWithActivityTypes()");
10566        synchronized (this) {
10567            final long ident = Binder.clearCallingIdentity();
10568            try {
10569                mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
10570            } finally {
10571                Binder.restoreCallingIdentity(ident);
10572            }
10573        }
10574    }
10575
10576    @Override
10577    public void moveStackToDisplay(int stackId, int displayId) {
10578        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10579
10580        synchronized (this) {
10581            final long ident = Binder.clearCallingIdentity();
10582            try {
10583                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10584                        + " to displayId=" + displayId);
10585                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10586            } finally {
10587                Binder.restoreCallingIdentity(ident);
10588            }
10589        }
10590    }
10591
10592    @Override
10593    public boolean removeTask(int taskId) {
10594        enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
10595        synchronized (this) {
10596            final long ident = Binder.clearCallingIdentity();
10597            try {
10598                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
10599                        "remove-task");
10600            } finally {
10601                Binder.restoreCallingIdentity(ident);
10602            }
10603        }
10604    }
10605
10606    /**
10607     * TODO: Add mController hook
10608     */
10609    @Override
10610    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10611        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10612
10613        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10614        synchronized(this) {
10615            moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
10616                    false /* fromRecents */);
10617        }
10618    }
10619
10620    void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
10621            boolean fromRecents) {
10622
10623        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10624                Binder.getCallingUid(), -1, -1, "Task to front")) {
10625            SafeActivityOptions.abort(options);
10626            return;
10627        }
10628        final long origId = Binder.clearCallingIdentity();
10629        try {
10630            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10631            if (task == null) {
10632                Slog.d(TAG, "Could not find task for id: "+ taskId);
10633                return;
10634            }
10635            if (mLockTaskController.isLockTaskModeViolation(task)) {
10636                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10637                return;
10638            }
10639            ActivityOptions realOptions = options != null
10640                    ? options.getOptions(mStackSupervisor)
10641                    : null;
10642            mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
10643                    false /* forceNonResizable */);
10644
10645            final ActivityRecord topActivity = task.getTopActivity();
10646            if (topActivity != null) {
10647
10648                // We are reshowing a task, use a starting window to hide the initial draw delay
10649                // so the transition can start earlier.
10650                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10651                        true /* taskSwitch */, fromRecents);
10652            }
10653        } finally {
10654            Binder.restoreCallingIdentity(origId);
10655        }
10656        SafeActivityOptions.abort(options);
10657    }
10658
10659    /**
10660     * Attempts to move a task backwards in z-order (the order of activities within the task is
10661     * unchanged).
10662     *
10663     * There are several possible results of this call:
10664     * - if the task is locked, then we will show the lock toast
10665     * - if there is a task behind the provided task, then that task is made visible and resumed as
10666     *   this task is moved to the back
10667     * - otherwise, if there are no other tasks in the stack:
10668     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10669     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10670     *       (depending on whether it is visible)
10671     *     - otherwise, we simply return home and hide this task
10672     *
10673     * @param token A reference to the activity we wish to move
10674     * @param nonRoot If false then this only works if the activity is the root
10675     *                of a task; if true it will work for any activity in a task.
10676     * @return Returns true if the move completed, false if not.
10677     */
10678    @Override
10679    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10680        enforceNotIsolatedCaller("moveActivityTaskToBack");
10681        synchronized(this) {
10682            final long origId = Binder.clearCallingIdentity();
10683            try {
10684                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10685                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10686                if (task != null) {
10687                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10688                }
10689            } finally {
10690                Binder.restoreCallingIdentity(origId);
10691            }
10692        }
10693        return false;
10694    }
10695
10696    @Override
10697    public void moveTaskBackwards(int task) {
10698        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10699                "moveTaskBackwards()");
10700
10701        synchronized(this) {
10702            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10703                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10704                return;
10705            }
10706            final long origId = Binder.clearCallingIdentity();
10707            moveTaskBackwardsLocked(task);
10708            Binder.restoreCallingIdentity(origId);
10709        }
10710    }
10711
10712    private final void moveTaskBackwardsLocked(int task) {
10713        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10714    }
10715
10716    @Override
10717    public int createStackOnDisplay(int displayId) throws RemoteException {
10718        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10719        synchronized (this) {
10720            final ActivityDisplay display =
10721                    mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
10722            if (display == null) {
10723                return INVALID_STACK_ID;
10724            }
10725            // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
10726            final ActivityStack stack = display.createStack(
10727                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
10728                    ON_TOP);
10729            return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
10730        }
10731    }
10732
10733    @Override
10734    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10735        synchronized (this) {
10736            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10737            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10738                return stack.mDisplayId;
10739            }
10740            return DEFAULT_DISPLAY;
10741        }
10742    }
10743
10744    @Override
10745    public void exitFreeformMode(IBinder token) throws RemoteException {
10746        synchronized (this) {
10747            long ident = Binder.clearCallingIdentity();
10748            try {
10749                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10750                if (r == null) {
10751                    throw new IllegalArgumentException(
10752                            "exitFreeformMode: No activity record matching token=" + token);
10753                }
10754
10755                final ActivityStack stack = r.getStack();
10756                if (stack == null || !stack.inFreeformWindowingMode()) {
10757                    throw new IllegalStateException(
10758                            "exitFreeformMode: You can only go fullscreen from freeform.");
10759                }
10760
10761                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
10762            } finally {
10763                Binder.restoreCallingIdentity(ident);
10764            }
10765        }
10766    }
10767
10768    @Override
10769    public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
10770        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
10771            setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
10772                    toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
10773            return;
10774        }
10775        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
10776        synchronized (this) {
10777            final long ident = Binder.clearCallingIdentity();
10778            try {
10779                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10780                if (task == null) {
10781                    Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
10782                    return;
10783                }
10784
10785                if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
10786                        + " to windowingMode=" + windowingMode + " toTop=" + toTop);
10787
10788                if (!task.isActivityTypeStandardOrUndefined()) {
10789                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
10790                            + " non-standard task " + taskId + " to windowing mode="
10791                            + windowingMode);
10792                }
10793
10794                final ActivityStack stack = task.getStack();
10795                if (toTop) {
10796                    stack.moveToFront("setTaskWindowingMode", task);
10797                }
10798                stack.setWindowingMode(windowingMode);
10799            } finally {
10800                Binder.restoreCallingIdentity(ident);
10801            }
10802        }
10803    }
10804
10805    /**
10806     * Moves the specified task to the primary-split-screen stack.
10807     *
10808     * @param taskId Id of task to move.
10809     * @param createMode The mode the primary split screen stack should be created in if it doesn't
10810     *                   exist already. See
10811     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
10812     *                   and
10813     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
10814     * @param toTop If the task and stack should be moved to the top.
10815     * @param animate Whether we should play an animation for the moving the task.
10816     * @param initialBounds If the primary stack gets created, it will use these bounds for the
10817     *                      stack. Pass {@code null} to use default bounds.
10818     * @param showRecents If the recents activity should be shown on the other side of the task
10819     *                    going into split-screen mode.
10820     */
10821    @Override
10822    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
10823            boolean animate, Rect initialBounds, boolean showRecents) {
10824        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10825                "setTaskWindowingModeSplitScreenPrimary()");
10826        synchronized (this) {
10827            long ident = Binder.clearCallingIdentity();
10828            try {
10829                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10830                if (task == null) {
10831                    Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
10832                    return false;
10833                }
10834                if (DEBUG_STACK) Slog.d(TAG_STACK,
10835                        "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
10836                        + " to createMode=" + createMode + " toTop=" + toTop);
10837                if (!task.isActivityTypeStandardOrUndefined()) {
10838                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
10839                            + " non-standard task " + taskId + " to split-screen windowing mode");
10840                }
10841
10842                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10843                final int windowingMode = task.getWindowingMode();
10844                final ActivityStack stack = task.getStack();
10845                if (toTop) {
10846                    stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
10847                }
10848                stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
10849                        false /* enteringSplitScreenMode */);
10850                return windowingMode != task.getWindowingMode();
10851            } finally {
10852                Binder.restoreCallingIdentity(ident);
10853            }
10854        }
10855    }
10856
10857    @Override
10858    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10859        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10860        synchronized (this) {
10861            long ident = Binder.clearCallingIdentity();
10862            try {
10863                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10864                if (task == null) {
10865                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10866                    return;
10867                }
10868
10869                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10870                        + " to stackId=" + stackId + " toTop=" + toTop);
10871
10872                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10873                if (stack == null) {
10874                    throw new IllegalStateException(
10875                            "moveTaskToStack: No stack for stackId=" + stackId);
10876                }
10877                if (!stack.isActivityTypeStandardOrUndefined()) {
10878                    throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
10879                            + taskId + " to stack " + stackId);
10880                }
10881                if (stack.inSplitScreenPrimaryWindowingMode()) {
10882                    mWindowManager.setDockedStackCreateState(
10883                            SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
10884                }
10885                task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
10886                        "moveTaskToStack");
10887            } finally {
10888                Binder.restoreCallingIdentity(ident);
10889            }
10890        }
10891    }
10892
10893    /**
10894     * Dismisses split-screen multi-window mode.
10895     * @param toTop If true the current primary split-screen stack will be placed or left on top.
10896     */
10897    @Override
10898    public void dismissSplitScreenMode(boolean toTop) {
10899        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
10900        final long ident = Binder.clearCallingIdentity();
10901        try {
10902            synchronized (this) {
10903                final ActivityStack stack =
10904                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
10905                if (stack == null) {
10906                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
10907                    return;
10908                }
10909
10910                if (toTop) {
10911                    stack.moveToFront("dismissSplitScreenMode");
10912                }
10913                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
10914            }
10915        } finally {
10916            Binder.restoreCallingIdentity(ident);
10917        }
10918    }
10919
10920    /**
10921     * Dismisses Pip
10922     * @param animate True if the dismissal should be animated.
10923     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
10924     *                          default animation duration should be used.
10925     */
10926    @Override
10927    public void dismissPip(boolean animate, int animationDuration) {
10928        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
10929        final long ident = Binder.clearCallingIdentity();
10930        try {
10931            synchronized (this) {
10932                final PinnedActivityStack stack =
10933                        mStackSupervisor.getDefaultDisplay().getPinnedStack();
10934                if (stack == null) {
10935                    Slog.w(TAG, "dismissPip: pinned stack not found.");
10936                    return;
10937                }
10938                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
10939                    throw new IllegalArgumentException("Stack: " + stack
10940                            + " doesn't support animated resize.");
10941                }
10942                if (animate) {
10943                    stack.animateResizePinnedStack(null /* sourceHintBounds */,
10944                            null /* destBounds */, animationDuration, false /* fromFullscreen */);
10945                } else {
10946                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
10947                }
10948            }
10949        } finally {
10950            Binder.restoreCallingIdentity(ident);
10951        }
10952    }
10953
10954    /**
10955     * Moves the top activity in the input stackId to the pinned stack.
10956     *
10957     * @param stackId Id of stack to move the top activity to pinned stack.
10958     * @param bounds Bounds to use for pinned stack.
10959     *
10960     * @return True if the top activity of the input stack was successfully moved to the pinned
10961     *          stack.
10962     */
10963    @Override
10964    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10965        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10966                "moveTopActivityToPinnedStack()");
10967        synchronized (this) {
10968            if (!mSupportsPictureInPicture) {
10969                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10970                        + "Device doesn't support picture-in-picture mode");
10971            }
10972
10973            long ident = Binder.clearCallingIdentity();
10974            try {
10975                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10976            } finally {
10977                Binder.restoreCallingIdentity(ident);
10978            }
10979        }
10980    }
10981
10982    @Override
10983    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10984            boolean preserveWindows, boolean animate, int animationDuration) {
10985        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10986        long ident = Binder.clearCallingIdentity();
10987        try {
10988            synchronized (this) {
10989                if (animate) {
10990                    final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
10991                    if (stack == null) {
10992                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
10993                        return;
10994                    }
10995                    if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
10996                        throw new IllegalArgumentException("Stack: " + stackId
10997                                + " doesn't support animated resize.");
10998                    }
10999                    stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11000                            animationDuration, false /* fromFullscreen */);
11001                } else {
11002                    final ActivityStack stack = mStackSupervisor.getStack(stackId);
11003                    if (stack == null) {
11004                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11005                        return;
11006                    }
11007                    mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11008                            null /* tempTaskInsetBounds */, preserveWindows,
11009                            allowResizeInDockedMode, !DEFER_RESUME);
11010                }
11011            }
11012        } finally {
11013            Binder.restoreCallingIdentity(ident);
11014        }
11015    }
11016
11017    @Override
11018    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
11019            Rect tempDockedTaskInsetBounds,
11020            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
11021        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
11022        long ident = Binder.clearCallingIdentity();
11023        try {
11024            synchronized (this) {
11025                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11026                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11027                        PRESERVE_WINDOWS);
11028            }
11029        } finally {
11030            Binder.restoreCallingIdentity(ident);
11031        }
11032    }
11033
11034    @Override
11035    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11036        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11037        final long ident = Binder.clearCallingIdentity();
11038        try {
11039            synchronized (this) {
11040                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11041            }
11042        } finally {
11043            Binder.restoreCallingIdentity(ident);
11044        }
11045    }
11046
11047    /**
11048     * Try to place task to provided position. The final position might be different depending on
11049     * current user and stacks state. The task will be moved to target stack if it's currently in
11050     * different stack.
11051     */
11052    @Override
11053    public void positionTaskInStack(int taskId, int stackId, int position) {
11054        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11055        synchronized (this) {
11056            long ident = Binder.clearCallingIdentity();
11057            try {
11058                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
11059                        + taskId + " in stackId=" + stackId + " at position=" + position);
11060                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11061                if (task == null) {
11062                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
11063                            + taskId);
11064                }
11065
11066                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11067
11068                if (stack == null) {
11069                    throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11070                            + stackId);
11071                }
11072                if (!stack.isActivityTypeStandardOrUndefined()) {
11073                    throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11074                            + " the position of task " + taskId + " in/to non-standard stack");
11075                }
11076
11077                // TODO: Have the callers of this API call a separate reparent method if that is
11078                // what they intended to do vs. having this method also do reparenting.
11079                if (task.getStack() == stack) {
11080                    // Change position in current stack.
11081                    stack.positionChildAt(task, position);
11082                } else {
11083                    // Reparent to new stack.
11084                    task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11085                            !DEFER_RESUME, "positionTaskInStack");
11086                }
11087            } finally {
11088                Binder.restoreCallingIdentity(ident);
11089            }
11090        }
11091    }
11092
11093    @Override
11094    public List<StackInfo> getAllStackInfos() {
11095        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11096        long ident = Binder.clearCallingIdentity();
11097        try {
11098            synchronized (this) {
11099                return mStackSupervisor.getAllStackInfosLocked();
11100            }
11101        } finally {
11102            Binder.restoreCallingIdentity(ident);
11103        }
11104    }
11105
11106    @Override
11107    public StackInfo getStackInfo(int windowingMode, int activityType) {
11108        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11109        long ident = Binder.clearCallingIdentity();
11110        try {
11111            synchronized (this) {
11112                return mStackSupervisor.getStackInfo(windowingMode, activityType);
11113            }
11114        } finally {
11115            Binder.restoreCallingIdentity(ident);
11116        }
11117    }
11118
11119    @Override
11120    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11121        synchronized(this) {
11122            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11123        }
11124    }
11125
11126    @Override
11127    public void updateDeviceOwner(String packageName) {
11128        final int callingUid = Binder.getCallingUid();
11129        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11130            throw new SecurityException("updateDeviceOwner called from non-system process");
11131        }
11132        synchronized (this) {
11133            mDeviceOwnerName = packageName;
11134        }
11135    }
11136
11137    @Override
11138    public void updateLockTaskPackages(int userId, String[] packages) {
11139        final int callingUid = Binder.getCallingUid();
11140        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11141            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11142                    "updateLockTaskPackages()");
11143        }
11144        synchronized (this) {
11145            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11146                    Arrays.toString(packages));
11147            mLockTaskController.updateLockTaskPackages(userId, packages);
11148        }
11149    }
11150
11151    @Override
11152    public void updateLockTaskFeatures(int userId, int flags) {
11153        final int callingUid = Binder.getCallingUid();
11154        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11155            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11156                    "updateLockTaskFeatures()");
11157        }
11158        synchronized (this) {
11159            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11160                    Integer.toHexString(flags));
11161            mLockTaskController.updateLockTaskFeatures(userId, flags);
11162        }
11163    }
11164
11165    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11166        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11167        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11168            return;
11169        }
11170
11171        final ActivityStack stack = mStackSupervisor.getFocusedStack();
11172        if (stack == null || task != stack.topTask()) {
11173            throw new IllegalArgumentException("Invalid task, not in foreground");
11174        }
11175
11176        // When a task is locked, dismiss the pinned stack if it exists
11177        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11178
11179        // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11180        // system or a specific app.
11181        // * System-initiated requests will only start the pinned mode (screen pinning)
11182        // * App-initiated requests
11183        //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
11184        //   - will start the pinned mode, otherwise
11185        final int callingUid = Binder.getCallingUid();
11186        long ident = Binder.clearCallingIdentity();
11187        try {
11188            mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11189        } finally {
11190            Binder.restoreCallingIdentity(ident);
11191        }
11192    }
11193
11194    @Override
11195    public void startLockTaskModeByToken(IBinder token) {
11196        synchronized (this) {
11197            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11198            if (r == null) {
11199                return;
11200            }
11201            startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11202        }
11203    }
11204
11205    @Override
11206    public void startSystemLockTaskMode(int taskId) throws RemoteException {
11207        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11208        // This makes inner call to look as if it was initiated by system.
11209        long ident = Binder.clearCallingIdentity();
11210        try {
11211            synchronized (this) {
11212                startLockTaskModeLocked(mStackSupervisor.anyTaskForIdLocked(taskId),
11213                        true /* isSystemCaller */);
11214            }
11215        } finally {
11216            Binder.restoreCallingIdentity(ident);
11217        }
11218    }
11219
11220    @Override
11221    public void stopLockTaskModeByToken(IBinder token) {
11222        synchronized (this) {
11223            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11224            if (r == null) {
11225                return;
11226            }
11227            stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11228        }
11229    }
11230
11231    /**
11232     * This API should be called by SystemUI only when user perform certain action to dismiss
11233     * lock task mode. We should only dismiss pinned lock task mode in this case.
11234     */
11235    @Override
11236    public void stopSystemLockTaskMode() throws RemoteException {
11237        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11238        stopLockTaskModeInternal(null, true /* isSystemCaller */);
11239    }
11240
11241    private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11242        final int callingUid = Binder.getCallingUid();
11243        long ident = Binder.clearCallingIdentity();
11244        try {
11245            synchronized (this) {
11246                mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11247            }
11248            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11249            // task and jumping straight into a call in the case of emergency call back.
11250            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11251            if (tm != null) {
11252                tm.showInCallScreen(false);
11253            }
11254        } finally {
11255            Binder.restoreCallingIdentity(ident);
11256        }
11257    }
11258
11259    @Override
11260    public boolean isInLockTaskMode() {
11261        return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11262    }
11263
11264    @Override
11265    public int getLockTaskModeState() {
11266        synchronized (this) {
11267            return mLockTaskController.getLockTaskModeState();
11268        }
11269    }
11270
11271    @Override
11272    public void showLockTaskEscapeMessage(IBinder token) {
11273        synchronized (this) {
11274            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11275            if (r == null) {
11276                return;
11277            }
11278            mLockTaskController.showLockTaskToast();
11279        }
11280    }
11281
11282    @Override
11283    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11284            throws RemoteException {
11285        synchronized (this) {
11286            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11287            if (r == null) {
11288                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11289                        + token);
11290                return;
11291            }
11292            final long origId = Binder.clearCallingIdentity();
11293            try {
11294                r.setDisablePreviewScreenshots(disable);
11295            } finally {
11296                Binder.restoreCallingIdentity(origId);
11297            }
11298        }
11299    }
11300
11301    // =========================================================
11302    // CONTENT PROVIDERS
11303    // =========================================================
11304
11305    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11306        List<ProviderInfo> providers = null;
11307        try {
11308            providers = AppGlobals.getPackageManager()
11309                    .queryContentProviders(app.processName, app.uid,
11310                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11311                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11312                    .getList();
11313        } catch (RemoteException ex) {
11314        }
11315        if (DEBUG_MU) Slog.v(TAG_MU,
11316                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11317        int userId = app.userId;
11318        if (providers != null) {
11319            int N = providers.size();
11320            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11321            for (int i=0; i<N; i++) {
11322                // TODO: keep logic in sync with installEncryptionUnawareProviders
11323                ProviderInfo cpi =
11324                    (ProviderInfo)providers.get(i);
11325                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11326                        cpi.name, cpi.flags);
11327                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11328                    // This is a singleton provider, but a user besides the
11329                    // default user is asking to initialize a process it runs
11330                    // in...  well, no, it doesn't actually run in this process,
11331                    // it runs in the process of the default user.  Get rid of it.
11332                    providers.remove(i);
11333                    N--;
11334                    i--;
11335                    continue;
11336                }
11337
11338                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11339                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11340                if (cpr == null) {
11341                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11342                    mProviderMap.putProviderByClass(comp, cpr);
11343                }
11344                if (DEBUG_MU) Slog.v(TAG_MU,
11345                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11346                app.pubProviders.put(cpi.name, cpr);
11347                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11348                    // Don't add this if it is a platform component that is marked
11349                    // to run in multiple processes, because this is actually
11350                    // part of the framework so doesn't make sense to track as a
11351                    // separate apk in the process.
11352                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11353                            mProcessStats);
11354                }
11355                notifyPackageUse(cpi.applicationInfo.packageName,
11356                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11357            }
11358        }
11359        return providers;
11360    }
11361
11362    /**
11363     * Check if the calling UID has a possible chance at accessing the provider
11364     * at the given authority and user.
11365     */
11366    public String checkContentProviderAccess(String authority, int userId) {
11367        if (userId == UserHandle.USER_ALL) {
11368            mContext.enforceCallingOrSelfPermission(
11369                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11370            userId = UserHandle.getCallingUserId();
11371        }
11372
11373        ProviderInfo cpi = null;
11374        try {
11375            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11376                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11377                            | PackageManager.MATCH_DISABLED_COMPONENTS
11378                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11379                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11380                    userId);
11381        } catch (RemoteException ignored) {
11382        }
11383        if (cpi == null) {
11384            return "Failed to find provider " + authority + " for user " + userId
11385                    + "; expected to find a valid ContentProvider for this authority";
11386        }
11387
11388        ProcessRecord r = null;
11389        synchronized (mPidsSelfLocked) {
11390            r = mPidsSelfLocked.get(Binder.getCallingPid());
11391        }
11392        if (r == null) {
11393            return "Failed to find PID " + Binder.getCallingPid();
11394        }
11395
11396        synchronized (this) {
11397            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11398        }
11399    }
11400
11401    /**
11402     * Check if {@link ProcessRecord} has a possible chance at accessing the
11403     * given {@link ProviderInfo}. Final permission checking is always done
11404     * in {@link ContentProvider}.
11405     */
11406    private final String checkContentProviderPermissionLocked(
11407            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11408        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11409        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11410        boolean checkedGrants = false;
11411        if (checkUser) {
11412            // Looking for cross-user grants before enforcing the typical cross-users permissions
11413            int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11414            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11415                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11416                    return null;
11417                }
11418                checkedGrants = true;
11419            }
11420            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11421                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11422            if (userId != tmpTargetUserId) {
11423                // When we actually went to determine the final targer user ID, this ended
11424                // up different than our initial check for the authority.  This is because
11425                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11426                // SELF.  So we need to re-check the grants again.
11427                checkedGrants = false;
11428            }
11429        }
11430        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11431                cpi.applicationInfo.uid, cpi.exported)
11432                == PackageManager.PERMISSION_GRANTED) {
11433            return null;
11434        }
11435        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11436                cpi.applicationInfo.uid, cpi.exported)
11437                == PackageManager.PERMISSION_GRANTED) {
11438            return null;
11439        }
11440
11441        PathPermission[] pps = cpi.pathPermissions;
11442        if (pps != null) {
11443            int i = pps.length;
11444            while (i > 0) {
11445                i--;
11446                PathPermission pp = pps[i];
11447                String pprperm = pp.getReadPermission();
11448                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11449                        cpi.applicationInfo.uid, cpi.exported)
11450                        == PackageManager.PERMISSION_GRANTED) {
11451                    return null;
11452                }
11453                String ppwperm = pp.getWritePermission();
11454                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11455                        cpi.applicationInfo.uid, cpi.exported)
11456                        == PackageManager.PERMISSION_GRANTED) {
11457                    return null;
11458                }
11459            }
11460        }
11461        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11462            return null;
11463        }
11464
11465        final String suffix;
11466        if (!cpi.exported) {
11467            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11468        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11469            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11470        } else {
11471            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11472        }
11473        final String msg = "Permission Denial: opening provider " + cpi.name
11474                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11475                + ", uid=" + callingUid + ")" + suffix;
11476        Slog.w(TAG, msg);
11477        return msg;
11478    }
11479
11480    /**
11481     * Returns if the ContentProvider has granted a uri to callingUid
11482     */
11483    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11484        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11485        if (perms != null) {
11486            for (int i=perms.size()-1; i>=0; i--) {
11487                GrantUri grantUri = perms.keyAt(i);
11488                if (grantUri.sourceUserId == userId || !checkUser) {
11489                    if (matchesProvider(grantUri.uri, cpi)) {
11490                        return true;
11491                    }
11492                }
11493            }
11494        }
11495        return false;
11496    }
11497
11498    /**
11499     * Returns true if the uri authority is one of the authorities specified in the provider.
11500     */
11501    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11502        String uriAuth = uri.getAuthority();
11503        String cpiAuth = cpi.authority;
11504        if (cpiAuth.indexOf(';') == -1) {
11505            return cpiAuth.equals(uriAuth);
11506        }
11507        String[] cpiAuths = cpiAuth.split(";");
11508        int length = cpiAuths.length;
11509        for (int i = 0; i < length; i++) {
11510            if (cpiAuths[i].equals(uriAuth)) return true;
11511        }
11512        return false;
11513    }
11514
11515    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11516            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11517        if (r != null) {
11518            for (int i=0; i<r.conProviders.size(); i++) {
11519                ContentProviderConnection conn = r.conProviders.get(i);
11520                if (conn.provider == cpr) {
11521                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11522                            "Adding provider requested by "
11523                            + r.processName + " from process "
11524                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11525                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11526                    if (stable) {
11527                        conn.stableCount++;
11528                        conn.numStableIncs++;
11529                    } else {
11530                        conn.unstableCount++;
11531                        conn.numUnstableIncs++;
11532                    }
11533                    return conn;
11534                }
11535            }
11536            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11537            if (stable) {
11538                conn.stableCount = 1;
11539                conn.numStableIncs = 1;
11540            } else {
11541                conn.unstableCount = 1;
11542                conn.numUnstableIncs = 1;
11543            }
11544            cpr.connections.add(conn);
11545            r.conProviders.add(conn);
11546            startAssociationLocked(r.uid, r.processName, r.curProcState,
11547                    cpr.uid, cpr.name, cpr.info.processName);
11548            return conn;
11549        }
11550        cpr.addExternalProcessHandleLocked(externalProcessToken);
11551        return null;
11552    }
11553
11554    boolean decProviderCountLocked(ContentProviderConnection conn,
11555            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11556        if (conn != null) {
11557            cpr = conn.provider;
11558            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11559                    "Removing provider requested by "
11560                    + conn.client.processName + " from process "
11561                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11562                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11563            if (stable) {
11564                conn.stableCount--;
11565            } else {
11566                conn.unstableCount--;
11567            }
11568            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11569                cpr.connections.remove(conn);
11570                conn.client.conProviders.remove(conn);
11571                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11572                    // The client is more important than last activity -- note the time this
11573                    // is happening, so we keep the old provider process around a bit as last
11574                    // activity to avoid thrashing it.
11575                    if (cpr.proc != null) {
11576                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11577                    }
11578                }
11579                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11580                return true;
11581            }
11582            return false;
11583        }
11584        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11585        return false;
11586    }
11587
11588    private void checkTime(long startTime, String where) {
11589        long now = SystemClock.uptimeMillis();
11590        if ((now-startTime) > 50) {
11591            // If we are taking more than 50ms, log about it.
11592            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11593        }
11594    }
11595
11596    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11597            PROC_SPACE_TERM,
11598            PROC_SPACE_TERM|PROC_PARENS,
11599            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11600    };
11601
11602    private final long[] mProcessStateStatsLongs = new long[1];
11603
11604    private boolean isProcessAliveLocked(ProcessRecord proc) {
11605        if (proc.pid <= 0) {
11606            if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
11607            return false;
11608        }
11609        if (proc.procStatFile == null) {
11610            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11611        }
11612        mProcessStateStatsLongs[0] = 0;
11613        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11614                mProcessStateStatsLongs, null)) {
11615            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11616            return false;
11617        }
11618        final long state = mProcessStateStatsLongs[0];
11619        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11620                + (char)state);
11621        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11622    }
11623
11624    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11625            String name, IBinder token, boolean stable, int userId) {
11626        ContentProviderRecord cpr;
11627        ContentProviderConnection conn = null;
11628        ProviderInfo cpi = null;
11629
11630        synchronized(this) {
11631            long startTime = SystemClock.uptimeMillis();
11632
11633            ProcessRecord r = null;
11634            if (caller != null) {
11635                r = getRecordForAppLocked(caller);
11636                if (r == null) {
11637                    throw new SecurityException(
11638                            "Unable to find app for caller " + caller
11639                          + " (pid=" + Binder.getCallingPid()
11640                          + ") when getting content provider " + name);
11641                }
11642            }
11643
11644            boolean checkCrossUser = true;
11645
11646            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11647
11648            // First check if this content provider has been published...
11649            cpr = mProviderMap.getProviderByName(name, userId);
11650            // If that didn't work, check if it exists for user 0 and then
11651            // verify that it's a singleton provider before using it.
11652            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11653                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11654                if (cpr != null) {
11655                    cpi = cpr.info;
11656                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11657                            cpi.name, cpi.flags)
11658                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11659                        userId = UserHandle.USER_SYSTEM;
11660                        checkCrossUser = false;
11661                    } else {
11662                        cpr = null;
11663                        cpi = null;
11664                    }
11665                }
11666            }
11667
11668            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11669            if (providerRunning) {
11670                cpi = cpr.info;
11671                String msg;
11672                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11673                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11674                        != null) {
11675                    throw new SecurityException(msg);
11676                }
11677                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11678
11679                if (r != null && cpr.canRunHere(r)) {
11680                    // This provider has been published or is in the process
11681                    // of being published...  but it is also allowed to run
11682                    // in the caller's process, so don't make a connection
11683                    // and just let the caller instantiate its own instance.
11684                    ContentProviderHolder holder = cpr.newHolder(null);
11685                    // don't give caller the provider object, it needs
11686                    // to make its own.
11687                    holder.provider = null;
11688                    return holder;
11689                }
11690                // Don't expose providers between normal apps and instant apps
11691                try {
11692                    if (AppGlobals.getPackageManager()
11693                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11694                        return null;
11695                    }
11696                } catch (RemoteException e) {
11697                }
11698
11699                final long origId = Binder.clearCallingIdentity();
11700
11701                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11702
11703                // In this case the provider instance already exists, so we can
11704                // return it right away.
11705                conn = incProviderCountLocked(r, cpr, token, stable);
11706                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11707                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11708                        // If this is a perceptible app accessing the provider,
11709                        // make sure to count it as being accessed and thus
11710                        // back up on the LRU list.  This is good because
11711                        // content providers are often expensive to start.
11712                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11713                        updateLruProcessLocked(cpr.proc, false, null);
11714                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11715                    }
11716                }
11717
11718                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11719                final int verifiedAdj = cpr.proc.verifiedAdj;
11720                boolean success = updateOomAdjLocked(cpr.proc, true);
11721                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11722                // if the process has been successfully adjusted.  So to reduce races with
11723                // it, we will check whether the process still exists.  Note that this doesn't
11724                // completely get rid of races with LMK killing the process, but should make
11725                // them much smaller.
11726                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11727                    success = false;
11728                }
11729                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11730                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11731                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11732                // NOTE: there is still a race here where a signal could be
11733                // pending on the process even though we managed to update its
11734                // adj level.  Not sure what to do about this, but at least
11735                // the race is now smaller.
11736                if (!success) {
11737                    // Uh oh...  it looks like the provider's process
11738                    // has been killed on us.  We need to wait for a new
11739                    // process to be started, and make sure its death
11740                    // doesn't kill our process.
11741                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11742                            + " is crashing; detaching " + r);
11743                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11744                    checkTime(startTime, "getContentProviderImpl: before appDied");
11745                    appDiedLocked(cpr.proc);
11746                    checkTime(startTime, "getContentProviderImpl: after appDied");
11747                    if (!lastRef) {
11748                        // This wasn't the last ref our process had on
11749                        // the provider...  we have now been killed, bail.
11750                        return null;
11751                    }
11752                    providerRunning = false;
11753                    conn = null;
11754                } else {
11755                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11756                }
11757
11758                Binder.restoreCallingIdentity(origId);
11759            }
11760
11761            if (!providerRunning) {
11762                try {
11763                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11764                    cpi = AppGlobals.getPackageManager().
11765                        resolveContentProvider(name,
11766                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11767                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11768                } catch (RemoteException ex) {
11769                }
11770                if (cpi == null) {
11771                    return null;
11772                }
11773                // If the provider is a singleton AND
11774                // (it's a call within the same user || the provider is a
11775                // privileged app)
11776                // Then allow connecting to the singleton provider
11777                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11778                        cpi.name, cpi.flags)
11779                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11780                if (singleton) {
11781                    userId = UserHandle.USER_SYSTEM;
11782                }
11783                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11784                checkTime(startTime, "getContentProviderImpl: got app info for user");
11785
11786                String msg;
11787                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11788                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11789                        != null) {
11790                    throw new SecurityException(msg);
11791                }
11792                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11793
11794                if (!mProcessesReady
11795                        && !cpi.processName.equals("system")) {
11796                    // If this content provider does not run in the system
11797                    // process, and the system is not yet ready to run other
11798                    // processes, then fail fast instead of hanging.
11799                    throw new IllegalArgumentException(
11800                            "Attempt to launch content provider before system ready");
11801                }
11802
11803                // Make sure that the user who owns this provider is running.  If not,
11804                // we don't want to allow it to run.
11805                if (!mUserController.isUserRunning(userId, 0)) {
11806                    Slog.w(TAG, "Unable to launch app "
11807                            + cpi.applicationInfo.packageName + "/"
11808                            + cpi.applicationInfo.uid + " for provider "
11809                            + name + ": user " + userId + " is stopped");
11810                    return null;
11811                }
11812
11813                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11814                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11815                cpr = mProviderMap.getProviderByClass(comp, userId);
11816                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11817                final boolean firstClass = cpr == null;
11818                if (firstClass) {
11819                    final long ident = Binder.clearCallingIdentity();
11820
11821                    // If permissions need a review before any of the app components can run,
11822                    // we return no provider and launch a review activity if the calling app
11823                    // is in the foreground.
11824                    if (mPermissionReviewRequired) {
11825                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11826                            return null;
11827                        }
11828                    }
11829
11830                    try {
11831                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11832                        ApplicationInfo ai =
11833                            AppGlobals.getPackageManager().
11834                                getApplicationInfo(
11835                                        cpi.applicationInfo.packageName,
11836                                        STOCK_PM_FLAGS, userId);
11837                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11838                        if (ai == null) {
11839                            Slog.w(TAG, "No package info for content provider "
11840                                    + cpi.name);
11841                            return null;
11842                        }
11843                        ai = getAppInfoForUser(ai, userId);
11844                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11845                    } catch (RemoteException ex) {
11846                        // pm is in same process, this will never happen.
11847                    } finally {
11848                        Binder.restoreCallingIdentity(ident);
11849                    }
11850                }
11851
11852                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11853
11854                if (r != null && cpr.canRunHere(r)) {
11855                    // If this is a multiprocess provider, then just return its
11856                    // info and allow the caller to instantiate it.  Only do
11857                    // this if the provider is the same user as the caller's
11858                    // process, or can run as root (so can be in any process).
11859                    return cpr.newHolder(null);
11860                }
11861
11862                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11863                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11864                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11865
11866                // This is single process, and our app is now connecting to it.
11867                // See if we are already in the process of launching this
11868                // provider.
11869                final int N = mLaunchingProviders.size();
11870                int i;
11871                for (i = 0; i < N; i++) {
11872                    if (mLaunchingProviders.get(i) == cpr) {
11873                        break;
11874                    }
11875                }
11876
11877                // If the provider is not already being launched, then get it
11878                // started.
11879                if (i >= N) {
11880                    final long origId = Binder.clearCallingIdentity();
11881
11882                    try {
11883                        // Content provider is now in use, its package can't be stopped.
11884                        try {
11885                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11886                            AppGlobals.getPackageManager().setPackageStoppedState(
11887                                    cpr.appInfo.packageName, false, userId);
11888                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11889                        } catch (RemoteException e) {
11890                        } catch (IllegalArgumentException e) {
11891                            Slog.w(TAG, "Failed trying to unstop package "
11892                                    + cpr.appInfo.packageName + ": " + e);
11893                        }
11894
11895                        // Use existing process if already started
11896                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11897                        ProcessRecord proc = getProcessRecordLocked(
11898                                cpi.processName, cpr.appInfo.uid, false);
11899                        if (proc != null && proc.thread != null && !proc.killed) {
11900                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11901                                    "Installing in existing process " + proc);
11902                            if (!proc.pubProviders.containsKey(cpi.name)) {
11903                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11904                                proc.pubProviders.put(cpi.name, cpr);
11905                                try {
11906                                    proc.thread.scheduleInstallProvider(cpi);
11907                                } catch (RemoteException e) {
11908                                }
11909                            }
11910                        } else {
11911                            checkTime(startTime, "getContentProviderImpl: before start process");
11912                            proc = startProcessLocked(cpi.processName,
11913                                    cpr.appInfo, false, 0, "content provider",
11914                                    new ComponentName(cpi.applicationInfo.packageName,
11915                                            cpi.name), false, false, false);
11916                            checkTime(startTime, "getContentProviderImpl: after start process");
11917                            if (proc == null) {
11918                                Slog.w(TAG, "Unable to launch app "
11919                                        + cpi.applicationInfo.packageName + "/"
11920                                        + cpi.applicationInfo.uid + " for provider "
11921                                        + name + ": process is bad");
11922                                return null;
11923                            }
11924                        }
11925                        cpr.launchingApp = proc;
11926                        mLaunchingProviders.add(cpr);
11927                    } finally {
11928                        Binder.restoreCallingIdentity(origId);
11929                    }
11930                }
11931
11932                checkTime(startTime, "getContentProviderImpl: updating data structures");
11933
11934                // Make sure the provider is published (the same provider class
11935                // may be published under multiple names).
11936                if (firstClass) {
11937                    mProviderMap.putProviderByClass(comp, cpr);
11938                }
11939
11940                mProviderMap.putProviderByName(name, cpr);
11941                conn = incProviderCountLocked(r, cpr, token, stable);
11942                if (conn != null) {
11943                    conn.waiting = true;
11944                }
11945            }
11946            checkTime(startTime, "getContentProviderImpl: done!");
11947
11948            grantEphemeralAccessLocked(userId, null /*intent*/,
11949                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11950        }
11951
11952        // Wait for the provider to be published...
11953        synchronized (cpr) {
11954            while (cpr.provider == null) {
11955                if (cpr.launchingApp == null) {
11956                    Slog.w(TAG, "Unable to launch app "
11957                            + cpi.applicationInfo.packageName + "/"
11958                            + cpi.applicationInfo.uid + " for provider "
11959                            + name + ": launching app became null");
11960                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11961                            UserHandle.getUserId(cpi.applicationInfo.uid),
11962                            cpi.applicationInfo.packageName,
11963                            cpi.applicationInfo.uid, name);
11964                    return null;
11965                }
11966                try {
11967                    if (DEBUG_MU) Slog.v(TAG_MU,
11968                            "Waiting to start provider " + cpr
11969                            + " launchingApp=" + cpr.launchingApp);
11970                    if (conn != null) {
11971                        conn.waiting = true;
11972                    }
11973                    cpr.wait();
11974                } catch (InterruptedException ex) {
11975                } finally {
11976                    if (conn != null) {
11977                        conn.waiting = false;
11978                    }
11979                }
11980            }
11981        }
11982        return cpr != null ? cpr.newHolder(conn) : null;
11983    }
11984
11985    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11986            ProcessRecord r, final int userId) {
11987        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11988                cpi.packageName, userId)) {
11989
11990            final boolean callerForeground = r == null || r.setSchedGroup
11991                    != ProcessList.SCHED_GROUP_BACKGROUND;
11992
11993            // Show a permission review UI only for starting from a foreground app
11994            if (!callerForeground) {
11995                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11996                        + cpi.packageName + " requires a permissions review");
11997                return false;
11998            }
11999
12000            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
12001            intent.addFlags(FLAG_ACTIVITY_NEW_TASK
12002                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
12003            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
12004
12005            if (DEBUG_PERMISSIONS_REVIEW) {
12006                Slog.i(TAG, "u" + userId + " Launching permission review "
12007                        + "for package " + cpi.packageName);
12008            }
12009
12010            final UserHandle userHandle = new UserHandle(userId);
12011            mHandler.post(new Runnable() {
12012                @Override
12013                public void run() {
12014                    mContext.startActivityAsUser(intent, userHandle);
12015                }
12016            });
12017
12018            return false;
12019        }
12020
12021        return true;
12022    }
12023
12024    /**
12025     * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
12026     * PackageManager could be unavailable at construction time and therefore needs to be accessed
12027     * on demand.
12028     */
12029    IPackageManager getPackageManager() {
12030        return AppGlobals.getPackageManager();
12031    }
12032
12033    ActivityStartController getActivityStartController() {
12034        return mActivityStartController;
12035    }
12036
12037    PackageManagerInternal getPackageManagerInternalLocked() {
12038        if (mPackageManagerInt == null) {
12039            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12040        }
12041        return mPackageManagerInt;
12042    }
12043
12044    @Override
12045    public final ContentProviderHolder getContentProvider(
12046            IApplicationThread caller, String name, int userId, boolean stable) {
12047        enforceNotIsolatedCaller("getContentProvider");
12048        if (caller == null) {
12049            String msg = "null IApplicationThread when getting content provider "
12050                    + name;
12051            Slog.w(TAG, msg);
12052            throw new SecurityException(msg);
12053        }
12054        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
12055        // with cross-user grant.
12056        return getContentProviderImpl(caller, name, null, stable, userId);
12057    }
12058
12059    public ContentProviderHolder getContentProviderExternal(
12060            String name, int userId, IBinder token) {
12061        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12062            "Do not have permission in call getContentProviderExternal()");
12063        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12064                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
12065        return getContentProviderExternalUnchecked(name, token, userId);
12066    }
12067
12068    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12069            IBinder token, int userId) {
12070        return getContentProviderImpl(null, name, token, true, userId);
12071    }
12072
12073    /**
12074     * Drop a content provider from a ProcessRecord's bookkeeping
12075     */
12076    public void removeContentProvider(IBinder connection, boolean stable) {
12077        enforceNotIsolatedCaller("removeContentProvider");
12078        long ident = Binder.clearCallingIdentity();
12079        try {
12080            synchronized (this) {
12081                ContentProviderConnection conn;
12082                try {
12083                    conn = (ContentProviderConnection)connection;
12084                } catch (ClassCastException e) {
12085                    String msg ="removeContentProvider: " + connection
12086                            + " not a ContentProviderConnection";
12087                    Slog.w(TAG, msg);
12088                    throw new IllegalArgumentException(msg);
12089                }
12090                if (conn == null) {
12091                    throw new NullPointerException("connection is null");
12092                }
12093                if (decProviderCountLocked(conn, null, null, stable)) {
12094                    updateOomAdjLocked();
12095                }
12096            }
12097        } finally {
12098            Binder.restoreCallingIdentity(ident);
12099        }
12100    }
12101
12102    public void removeContentProviderExternal(String name, IBinder token) {
12103        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12104            "Do not have permission in call removeContentProviderExternal()");
12105        int userId = UserHandle.getCallingUserId();
12106        long ident = Binder.clearCallingIdentity();
12107        try {
12108            removeContentProviderExternalUnchecked(name, token, userId);
12109        } finally {
12110            Binder.restoreCallingIdentity(ident);
12111        }
12112    }
12113
12114    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12115        synchronized (this) {
12116            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12117            if(cpr == null) {
12118                //remove from mProvidersByClass
12119                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12120                return;
12121            }
12122
12123            //update content provider record entry info
12124            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12125            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12126            if (localCpr.hasExternalProcessHandles()) {
12127                if (localCpr.removeExternalProcessHandleLocked(token)) {
12128                    updateOomAdjLocked();
12129                } else {
12130                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12131                            + " with no external reference for token: "
12132                            + token + ".");
12133                }
12134            } else {
12135                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12136                        + " with no external references.");
12137            }
12138        }
12139    }
12140
12141    public final void publishContentProviders(IApplicationThread caller,
12142            List<ContentProviderHolder> providers) {
12143        if (providers == null) {
12144            return;
12145        }
12146
12147        enforceNotIsolatedCaller("publishContentProviders");
12148        synchronized (this) {
12149            final ProcessRecord r = getRecordForAppLocked(caller);
12150            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12151            if (r == null) {
12152                throw new SecurityException(
12153                        "Unable to find app for caller " + caller
12154                      + " (pid=" + Binder.getCallingPid()
12155                      + ") when publishing content providers");
12156            }
12157
12158            final long origId = Binder.clearCallingIdentity();
12159
12160            final int N = providers.size();
12161            for (int i = 0; i < N; i++) {
12162                ContentProviderHolder src = providers.get(i);
12163                if (src == null || src.info == null || src.provider == null) {
12164                    continue;
12165                }
12166                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12167                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12168                if (dst != null) {
12169                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12170                    mProviderMap.putProviderByClass(comp, dst);
12171                    String names[] = dst.info.authority.split(";");
12172                    for (int j = 0; j < names.length; j++) {
12173                        mProviderMap.putProviderByName(names[j], dst);
12174                    }
12175
12176                    int launchingCount = mLaunchingProviders.size();
12177                    int j;
12178                    boolean wasInLaunchingProviders = false;
12179                    for (j = 0; j < launchingCount; j++) {
12180                        if (mLaunchingProviders.get(j) == dst) {
12181                            mLaunchingProviders.remove(j);
12182                            wasInLaunchingProviders = true;
12183                            j--;
12184                            launchingCount--;
12185                        }
12186                    }
12187                    if (wasInLaunchingProviders) {
12188                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12189                    }
12190                    synchronized (dst) {
12191                        dst.provider = src.provider;
12192                        dst.proc = r;
12193                        dst.notifyAll();
12194                    }
12195                    updateOomAdjLocked(r, true);
12196                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12197                            src.info.authority);
12198                }
12199            }
12200
12201            Binder.restoreCallingIdentity(origId);
12202        }
12203    }
12204
12205    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12206        ContentProviderConnection conn;
12207        try {
12208            conn = (ContentProviderConnection)connection;
12209        } catch (ClassCastException e) {
12210            String msg ="refContentProvider: " + connection
12211                    + " not a ContentProviderConnection";
12212            Slog.w(TAG, msg);
12213            throw new IllegalArgumentException(msg);
12214        }
12215        if (conn == null) {
12216            throw new NullPointerException("connection is null");
12217        }
12218
12219        synchronized (this) {
12220            if (stable > 0) {
12221                conn.numStableIncs += stable;
12222            }
12223            stable = conn.stableCount + stable;
12224            if (stable < 0) {
12225                throw new IllegalStateException("stableCount < 0: " + stable);
12226            }
12227
12228            if (unstable > 0) {
12229                conn.numUnstableIncs += unstable;
12230            }
12231            unstable = conn.unstableCount + unstable;
12232            if (unstable < 0) {
12233                throw new IllegalStateException("unstableCount < 0: " + unstable);
12234            }
12235
12236            if ((stable+unstable) <= 0) {
12237                throw new IllegalStateException("ref counts can't go to zero here: stable="
12238                        + stable + " unstable=" + unstable);
12239            }
12240            conn.stableCount = stable;
12241            conn.unstableCount = unstable;
12242            return !conn.dead;
12243        }
12244    }
12245
12246    public void unstableProviderDied(IBinder connection) {
12247        ContentProviderConnection conn;
12248        try {
12249            conn = (ContentProviderConnection)connection;
12250        } catch (ClassCastException e) {
12251            String msg ="refContentProvider: " + connection
12252                    + " not a ContentProviderConnection";
12253            Slog.w(TAG, msg);
12254            throw new IllegalArgumentException(msg);
12255        }
12256        if (conn == null) {
12257            throw new NullPointerException("connection is null");
12258        }
12259
12260        // Safely retrieve the content provider associated with the connection.
12261        IContentProvider provider;
12262        synchronized (this) {
12263            provider = conn.provider.provider;
12264        }
12265
12266        if (provider == null) {
12267            // Um, yeah, we're way ahead of you.
12268            return;
12269        }
12270
12271        // Make sure the caller is being honest with us.
12272        if (provider.asBinder().pingBinder()) {
12273            // Er, no, still looks good to us.
12274            synchronized (this) {
12275                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12276                        + " says " + conn + " died, but we don't agree");
12277                return;
12278            }
12279        }
12280
12281        // Well look at that!  It's dead!
12282        synchronized (this) {
12283            if (conn.provider.provider != provider) {
12284                // But something changed...  good enough.
12285                return;
12286            }
12287
12288            ProcessRecord proc = conn.provider.proc;
12289            if (proc == null || proc.thread == null) {
12290                // Seems like the process is already cleaned up.
12291                return;
12292            }
12293
12294            // As far as we're concerned, this is just like receiving a
12295            // death notification...  just a bit prematurely.
12296            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12297                    + ") early provider death");
12298            final long ident = Binder.clearCallingIdentity();
12299            try {
12300                appDiedLocked(proc);
12301            } finally {
12302                Binder.restoreCallingIdentity(ident);
12303            }
12304        }
12305    }
12306
12307    @Override
12308    public void appNotRespondingViaProvider(IBinder connection) {
12309        enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12310
12311        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12312        if (conn == null) {
12313            Slog.w(TAG, "ContentProviderConnection is null");
12314            return;
12315        }
12316
12317        final ProcessRecord host = conn.provider.proc;
12318        if (host == null) {
12319            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12320            return;
12321        }
12322
12323        mHandler.post(new Runnable() {
12324            @Override
12325            public void run() {
12326                mAppErrors.appNotResponding(host, null, null, false,
12327                        "ContentProvider not responding");
12328            }
12329        });
12330    }
12331
12332    public final void installSystemProviders() {
12333        List<ProviderInfo> providers;
12334        synchronized (this) {
12335            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12336            providers = generateApplicationProvidersLocked(app);
12337            if (providers != null) {
12338                for (int i=providers.size()-1; i>=0; i--) {
12339                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12340                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12341                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12342                                + ": not system .apk");
12343                        providers.remove(i);
12344                    }
12345                }
12346            }
12347        }
12348        if (providers != null) {
12349            mSystemThread.installSystemProviders(providers);
12350        }
12351
12352        mConstants.start(mContext.getContentResolver());
12353        mCoreSettingsObserver = new CoreSettingsObserver(this);
12354        mFontScaleSettingObserver = new FontScaleSettingObserver();
12355        GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12356
12357        // Now that the settings provider is published we can consider sending
12358        // in a rescue party.
12359        RescueParty.onSettingsProviderPublished(mContext);
12360
12361        //mUsageStatsService.monitorPackages();
12362    }
12363
12364    void startPersistentApps(int matchFlags) {
12365        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12366
12367        synchronized (this) {
12368            try {
12369                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12370                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12371                for (ApplicationInfo app : apps) {
12372                    if (!"android".equals(app.packageName)) {
12373                        addAppLocked(app, null, false, null /* ABI override */);
12374                    }
12375                }
12376            } catch (RemoteException ex) {
12377            }
12378        }
12379    }
12380
12381    /**
12382     * When a user is unlocked, we need to install encryption-unaware providers
12383     * belonging to any running apps.
12384     */
12385    void installEncryptionUnawareProviders(int userId) {
12386        // We're only interested in providers that are encryption unaware, and
12387        // we don't care about uninstalled apps, since there's no way they're
12388        // running at this point.
12389        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12390
12391        synchronized (this) {
12392            final int NP = mProcessNames.getMap().size();
12393            for (int ip = 0; ip < NP; ip++) {
12394                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12395                final int NA = apps.size();
12396                for (int ia = 0; ia < NA; ia++) {
12397                    final ProcessRecord app = apps.valueAt(ia);
12398                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12399
12400                    final int NG = app.pkgList.size();
12401                    for (int ig = 0; ig < NG; ig++) {
12402                        try {
12403                            final String pkgName = app.pkgList.keyAt(ig);
12404                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12405                                    .getPackageInfo(pkgName, matchFlags, userId);
12406                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12407                                for (ProviderInfo pi : pkgInfo.providers) {
12408                                    // TODO: keep in sync with generateApplicationProvidersLocked
12409                                    final boolean processMatch = Objects.equals(pi.processName,
12410                                            app.processName) || pi.multiprocess;
12411                                    final boolean userMatch = isSingleton(pi.processName,
12412                                            pi.applicationInfo, pi.name, pi.flags)
12413                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12414                                    if (processMatch && userMatch) {
12415                                        Log.v(TAG, "Installing " + pi);
12416                                        app.thread.scheduleInstallProvider(pi);
12417                                    } else {
12418                                        Log.v(TAG, "Skipping " + pi);
12419                                    }
12420                                }
12421                            }
12422                        } catch (RemoteException ignored) {
12423                        }
12424                    }
12425                }
12426            }
12427        }
12428    }
12429
12430    /**
12431     * Allows apps to retrieve the MIME type of a URI.
12432     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12433     * users, then it does not need permission to access the ContentProvider.
12434     * Either, it needs cross-user uri grants.
12435     *
12436     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12437     *
12438     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12439     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12440     */
12441    public String getProviderMimeType(Uri uri, int userId) {
12442        enforceNotIsolatedCaller("getProviderMimeType");
12443        final String name = uri.getAuthority();
12444        int callingUid = Binder.getCallingUid();
12445        int callingPid = Binder.getCallingPid();
12446        long ident = 0;
12447        boolean clearedIdentity = false;
12448        userId = mUserController.unsafeConvertIncomingUser(userId);
12449        if (canClearIdentity(callingPid, callingUid, userId)) {
12450            clearedIdentity = true;
12451            ident = Binder.clearCallingIdentity();
12452        }
12453        ContentProviderHolder holder = null;
12454        try {
12455            holder = getContentProviderExternalUnchecked(name, null, userId);
12456            if (holder != null) {
12457                return holder.provider.getType(uri);
12458            }
12459        } catch (RemoteException e) {
12460            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12461            return null;
12462        } catch (Exception e) {
12463            Log.w(TAG, "Exception while determining type of " + uri, e);
12464            return null;
12465        } finally {
12466            // We need to clear the identity to call removeContentProviderExternalUnchecked
12467            if (!clearedIdentity) {
12468                ident = Binder.clearCallingIdentity();
12469            }
12470            try {
12471                if (holder != null) {
12472                    removeContentProviderExternalUnchecked(name, null, userId);
12473                }
12474            } finally {
12475                Binder.restoreCallingIdentity(ident);
12476            }
12477        }
12478
12479        return null;
12480    }
12481
12482    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12483        if (UserHandle.getUserId(callingUid) == userId) {
12484            return true;
12485        }
12486        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12487                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12488                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12489                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12490                return true;
12491        }
12492        return false;
12493    }
12494
12495    // =========================================================
12496    // GLOBAL MANAGEMENT
12497    // =========================================================
12498
12499    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12500            boolean isolated, int isolatedUid) {
12501        String proc = customProcess != null ? customProcess : info.processName;
12502        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12503        final int userId = UserHandle.getUserId(info.uid);
12504        int uid = info.uid;
12505        if (isolated) {
12506            if (isolatedUid == 0) {
12507                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12508                while (true) {
12509                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12510                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12511                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12512                    }
12513                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12514                    mNextIsolatedProcessUid++;
12515                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12516                        // No process for this uid, use it.
12517                        break;
12518                    }
12519                    stepsLeft--;
12520                    if (stepsLeft <= 0) {
12521                        return null;
12522                    }
12523                }
12524            } else {
12525                // Special case for startIsolatedProcess (internal only), where
12526                // the uid of the isolated process is specified by the caller.
12527                uid = isolatedUid;
12528            }
12529            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12530
12531            // Register the isolated UID with this application so BatteryStats knows to
12532            // attribute resource usage to the application.
12533            //
12534            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12535            // about the process state of the isolated UID *before* it is registered with the
12536            // owning application.
12537            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12538        }
12539        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12540        if (!mBooted && !mBooting
12541                && userId == UserHandle.USER_SYSTEM
12542                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12543            r.persistent = true;
12544            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12545        }
12546        if (isolated && isolatedUid != 0) {
12547            // Special case for startIsolatedProcess (internal only) - assume the process
12548            // is required by the system server to prevent it being killed.
12549            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
12550        }
12551        addProcessNameLocked(r);
12552        return r;
12553    }
12554
12555    private boolean uidOnBackgroundWhitelist(final int uid) {
12556        final int appId = UserHandle.getAppId(uid);
12557        final int[] whitelist = mBackgroundAppIdWhitelist;
12558        final int N = whitelist.length;
12559        for (int i = 0; i < N; i++) {
12560            if (appId == whitelist[i]) {
12561                return true;
12562            }
12563        }
12564        return false;
12565    }
12566
12567    @Override
12568    public void backgroundWhitelistUid(final int uid) {
12569        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12570            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12571        }
12572
12573        if (DEBUG_BACKGROUND_CHECK) {
12574            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12575        }
12576        synchronized (this) {
12577            final int N = mBackgroundAppIdWhitelist.length;
12578            int[] newList = new int[N+1];
12579            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12580            newList[N] = UserHandle.getAppId(uid);
12581            mBackgroundAppIdWhitelist = newList;
12582        }
12583    }
12584
12585    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12586            String abiOverride) {
12587        ProcessRecord app;
12588        if (!isolated) {
12589            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12590                    info.uid, true);
12591        } else {
12592            app = null;
12593        }
12594
12595        if (app == null) {
12596            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12597            updateLruProcessLocked(app, false, null);
12598            updateOomAdjLocked();
12599        }
12600
12601        // This package really, really can not be stopped.
12602        try {
12603            AppGlobals.getPackageManager().setPackageStoppedState(
12604                    info.packageName, false, UserHandle.getUserId(app.uid));
12605        } catch (RemoteException e) {
12606        } catch (IllegalArgumentException e) {
12607            Slog.w(TAG, "Failed trying to unstop package "
12608                    + info.packageName + ": " + e);
12609        }
12610
12611        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12612            app.persistent = true;
12613            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12614        }
12615        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12616            mPersistentStartingProcesses.add(app);
12617            startProcessLocked(app, "added application",
12618                    customProcess != null ? customProcess : app.processName, abiOverride);
12619        }
12620
12621        return app;
12622    }
12623
12624    public void unhandledBack() {
12625        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12626                "unhandledBack()");
12627
12628        synchronized(this) {
12629            final long origId = Binder.clearCallingIdentity();
12630            try {
12631                getFocusedStack().unhandledBackLocked();
12632            } finally {
12633                Binder.restoreCallingIdentity(origId);
12634            }
12635        }
12636    }
12637
12638    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12639        enforceNotIsolatedCaller("openContentUri");
12640        final int userId = UserHandle.getCallingUserId();
12641        final Uri uri = Uri.parse(uriString);
12642        String name = uri.getAuthority();
12643        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12644        ParcelFileDescriptor pfd = null;
12645        if (cph != null) {
12646            // We record the binder invoker's uid in thread-local storage before
12647            // going to the content provider to open the file.  Later, in the code
12648            // that handles all permissions checks, we look for this uid and use
12649            // that rather than the Activity Manager's own uid.  The effect is that
12650            // we do the check against the caller's permissions even though it looks
12651            // to the content provider like the Activity Manager itself is making
12652            // the request.
12653            Binder token = new Binder();
12654            sCallerIdentity.set(new Identity(
12655                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12656            try {
12657                pfd = cph.provider.openFile(null, uri, "r", null, token);
12658            } catch (FileNotFoundException e) {
12659                // do nothing; pfd will be returned null
12660            } finally {
12661                // Ensure that whatever happens, we clean up the identity state
12662                sCallerIdentity.remove();
12663                // Ensure we're done with the provider.
12664                removeContentProviderExternalUnchecked(name, null, userId);
12665            }
12666        } else {
12667            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12668        }
12669        return pfd;
12670    }
12671
12672    // Actually is sleeping or shutting down or whatever else in the future
12673    // is an inactive state.
12674    boolean isSleepingOrShuttingDownLocked() {
12675        return isSleepingLocked() || mShuttingDown;
12676    }
12677
12678    boolean isShuttingDownLocked() {
12679        return mShuttingDown;
12680    }
12681
12682    boolean isSleepingLocked() {
12683        return mSleeping;
12684    }
12685
12686    void onWakefulnessChanged(int wakefulness) {
12687        synchronized(this) {
12688            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12689            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12690            mWakefulness = wakefulness;
12691
12692            if (wasAwake != isAwake) {
12693                // Also update state in a special way for running foreground services UI.
12694                mServices.updateScreenStateLocked(isAwake);
12695                mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12696                        .sendToTarget();
12697            }
12698        }
12699    }
12700
12701    void finishRunningVoiceLocked() {
12702        if (mRunningVoice != null) {
12703            mRunningVoice = null;
12704            mVoiceWakeLock.release();
12705            updateSleepIfNeededLocked();
12706        }
12707    }
12708
12709    void startTimeTrackingFocusedActivityLocked() {
12710        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12711        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12712            mCurAppTimeTracker.start(resumedActivity.packageName);
12713        }
12714    }
12715
12716    void updateSleepIfNeededLocked() {
12717        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12718        final boolean wasSleeping = mSleeping;
12719
12720        if (!shouldSleep) {
12721            // If wasSleeping is true, we need to wake up activity manager state from when
12722            // we started sleeping. In either case, we need to apply the sleep tokens, which
12723            // will wake up stacks or put them to sleep as appropriate.
12724            if (wasSleeping) {
12725                mSleeping = false;
12726                startTimeTrackingFocusedActivityLocked();
12727                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12728                mStackSupervisor.comeOutOfSleepIfNeededLocked();
12729            }
12730            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12731            if (wasSleeping) {
12732                updateOomAdjLocked();
12733            }
12734        } else if (!mSleeping && shouldSleep) {
12735            mSleeping = true;
12736            if (mCurAppTimeTracker != null) {
12737                mCurAppTimeTracker.stop();
12738            }
12739            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12740            mStackSupervisor.goingToSleepLocked();
12741            updateOomAdjLocked();
12742        }
12743    }
12744
12745    /** Pokes the task persister. */
12746    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12747        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12748    }
12749
12750    /**
12751     * Notifies all listeners when the pinned stack animation starts.
12752     */
12753    @Override
12754    public void notifyPinnedStackAnimationStarted() {
12755        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12756    }
12757
12758    /**
12759     * Notifies all listeners when the pinned stack animation ends.
12760     */
12761    @Override
12762    public void notifyPinnedStackAnimationEnded() {
12763        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12764    }
12765
12766    @Override
12767    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12768        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12769    }
12770
12771    @Override
12772    public boolean shutdown(int timeout) {
12773        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12774                != PackageManager.PERMISSION_GRANTED) {
12775            throw new SecurityException("Requires permission "
12776                    + android.Manifest.permission.SHUTDOWN);
12777        }
12778
12779        // TODO: Where should the corresponding '1' (start) write go?
12780        StatsLog.write(StatsLog.DEVICE_ON_STATUS_CHANGED, 0);
12781
12782        boolean timedout = false;
12783
12784        synchronized(this) {
12785            mShuttingDown = true;
12786            mStackSupervisor.prepareForShutdownLocked();
12787            updateEventDispatchingLocked();
12788            timedout = mStackSupervisor.shutdownLocked(timeout);
12789        }
12790
12791        mAppOpsService.shutdown();
12792        if (mUsageStatsService != null) {
12793            mUsageStatsService.prepareShutdown();
12794        }
12795        mBatteryStatsService.shutdown();
12796        synchronized (this) {
12797            mProcessStats.shutdownLocked();
12798            notifyTaskPersisterLocked(null, true);
12799        }
12800
12801        return timedout;
12802    }
12803
12804    public final void activitySlept(IBinder token) {
12805        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12806
12807        final long origId = Binder.clearCallingIdentity();
12808
12809        synchronized (this) {
12810            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12811            if (r != null) {
12812                mStackSupervisor.activitySleptLocked(r);
12813            }
12814        }
12815
12816        Binder.restoreCallingIdentity(origId);
12817    }
12818
12819    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12820        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12821        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12822        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12823            boolean wasRunningVoice = mRunningVoice != null;
12824            mRunningVoice = session;
12825            if (!wasRunningVoice) {
12826                mVoiceWakeLock.acquire();
12827                updateSleepIfNeededLocked();
12828            }
12829        }
12830    }
12831
12832    private void updateEventDispatchingLocked() {
12833        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12834    }
12835
12836    @Override
12837    public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12838        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12839                != PackageManager.PERMISSION_GRANTED) {
12840            throw new SecurityException("Requires permission "
12841                    + android.Manifest.permission.DEVICE_POWER);
12842        }
12843
12844        synchronized(this) {
12845            long ident = Binder.clearCallingIdentity();
12846            try {
12847                mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12848            } finally {
12849                Binder.restoreCallingIdentity(ident);
12850            }
12851        }
12852
12853        mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12854                .sendToTarget();
12855    }
12856
12857    @Override
12858    public void notifyLockedProfile(@UserIdInt int userId) {
12859        try {
12860            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12861                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12862            }
12863        } catch (RemoteException ex) {
12864            throw new SecurityException("Fail to check is caller a privileged app", ex);
12865        }
12866
12867        synchronized (this) {
12868            final long ident = Binder.clearCallingIdentity();
12869            try {
12870                if (mUserController.shouldConfirmCredentials(userId)) {
12871                    if (mKeyguardController.isKeyguardLocked()) {
12872                        // Showing launcher to avoid user entering credential twice.
12873                        final int currentUserId = mUserController.getCurrentUserId();
12874                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12875                    }
12876                    mStackSupervisor.lockAllProfileTasks(userId);
12877                }
12878            } finally {
12879                Binder.restoreCallingIdentity(ident);
12880            }
12881        }
12882    }
12883
12884    @Override
12885    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12886        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12887        synchronized (this) {
12888            final long ident = Binder.clearCallingIdentity();
12889            try {
12890                intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
12891                        FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
12892                        FLAG_ACTIVITY_TASK_ON_HOME);
12893                ActivityOptions activityOptions = options != null
12894                        ? new ActivityOptions(options)
12895                        : ActivityOptions.makeBasic();
12896                activityOptions.setLaunchTaskId(
12897                        mStackSupervisor.getHomeActivity().getTask().taskId);
12898                mContext.startActivityAsUser(intent, activityOptions.toBundle(),
12899                        UserHandle.CURRENT);
12900            } finally {
12901                Binder.restoreCallingIdentity(ident);
12902            }
12903        }
12904    }
12905
12906    @Override
12907    public void stopAppSwitches() {
12908        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12909                != PackageManager.PERMISSION_GRANTED) {
12910            throw new SecurityException("viewquires permission "
12911                    + android.Manifest.permission.STOP_APP_SWITCHES);
12912        }
12913
12914        synchronized(this) {
12915            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12916                    + APP_SWITCH_DELAY_TIME;
12917            mDidAppSwitch = false;
12918            mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
12919        }
12920    }
12921
12922    public void resumeAppSwitches() {
12923        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12924                != PackageManager.PERMISSION_GRANTED) {
12925            throw new SecurityException("Requires permission "
12926                    + android.Manifest.permission.STOP_APP_SWITCHES);
12927        }
12928
12929        synchronized(this) {
12930            // Note that we don't execute any pending app switches... we will
12931            // let those wait until either the timeout, or the next start
12932            // activity request.
12933            mAppSwitchesAllowedTime = 0;
12934        }
12935    }
12936
12937    boolean checkAllowAppSwitchUid(int uid) {
12938        ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
12939        if (types != null) {
12940            for (int i = types.size() - 1; i >= 0; i--) {
12941                if (types.valueAt(i).intValue() == uid) {
12942                    return true;
12943                }
12944            }
12945        }
12946        return false;
12947    }
12948
12949    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12950            int callingPid, int callingUid, String name) {
12951        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12952            return true;
12953        }
12954
12955        int perm = checkComponentPermission(
12956                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12957                sourceUid, -1, true);
12958        if (perm == PackageManager.PERMISSION_GRANTED) {
12959            return true;
12960        }
12961        if (checkAllowAppSwitchUid(sourceUid)) {
12962            return true;
12963        }
12964
12965        // If the actual IPC caller is different from the logical source, then
12966        // also see if they are allowed to control app switches.
12967        if (callingUid != -1 && callingUid != sourceUid) {
12968            perm = checkComponentPermission(
12969                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12970                    callingUid, -1, true);
12971            if (perm == PackageManager.PERMISSION_GRANTED) {
12972                return true;
12973            }
12974            if (checkAllowAppSwitchUid(callingUid)) {
12975                return true;
12976            }
12977        }
12978
12979        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12980        return false;
12981    }
12982
12983    public void setDebugApp(String packageName, boolean waitForDebugger,
12984            boolean persistent) {
12985        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12986                "setDebugApp()");
12987
12988        long ident = Binder.clearCallingIdentity();
12989        try {
12990            // Note that this is not really thread safe if there are multiple
12991            // callers into it at the same time, but that's not a situation we
12992            // care about.
12993            if (persistent) {
12994                final ContentResolver resolver = mContext.getContentResolver();
12995                Settings.Global.putString(
12996                    resolver, Settings.Global.DEBUG_APP,
12997                    packageName);
12998                Settings.Global.putInt(
12999                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13000                    waitForDebugger ? 1 : 0);
13001            }
13002
13003            synchronized (this) {
13004                if (!persistent) {
13005                    mOrigDebugApp = mDebugApp;
13006                    mOrigWaitForDebugger = mWaitForDebugger;
13007                }
13008                mDebugApp = packageName;
13009                mWaitForDebugger = waitForDebugger;
13010                mDebugTransient = !persistent;
13011                if (packageName != null) {
13012                    forceStopPackageLocked(packageName, -1, false, false, true, true,
13013                            false, UserHandle.USER_ALL, "set debug app");
13014                }
13015            }
13016        } finally {
13017            Binder.restoreCallingIdentity(ident);
13018        }
13019    }
13020
13021    void setTrackAllocationApp(ApplicationInfo app, String processName) {
13022        synchronized (this) {
13023            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13024            if (!isDebuggable) {
13025                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13026                    throw new SecurityException("Process not debuggable: " + app.packageName);
13027                }
13028            }
13029
13030            mTrackAllocationApp = processName;
13031        }
13032    }
13033
13034    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
13035        synchronized (this) {
13036            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13037            if (!isDebuggable) {
13038                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13039                    throw new SecurityException("Process not debuggable: " + app.packageName);
13040                }
13041            }
13042            mProfileApp = processName;
13043
13044            if (mProfilerInfo != null) {
13045                if (mProfilerInfo.profileFd != null) {
13046                    try {
13047                        mProfilerInfo.profileFd.close();
13048                    } catch (IOException e) {
13049                    }
13050                }
13051            }
13052            mProfilerInfo = new ProfilerInfo(profilerInfo);
13053            mProfileType = 0;
13054        }
13055    }
13056
13057    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
13058        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13059        if (!isDebuggable) {
13060            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13061                throw new SecurityException("Process not debuggable: " + app.packageName);
13062            }
13063        }
13064        mNativeDebuggingApp = processName;
13065    }
13066
13067    @Override
13068    public void setAlwaysFinish(boolean enabled) {
13069        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13070                "setAlwaysFinish()");
13071
13072        long ident = Binder.clearCallingIdentity();
13073        try {
13074            Settings.Global.putInt(
13075                    mContext.getContentResolver(),
13076                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13077
13078            synchronized (this) {
13079                mAlwaysFinishActivities = enabled;
13080            }
13081        } finally {
13082            Binder.restoreCallingIdentity(ident);
13083        }
13084    }
13085
13086    @Override
13087    public void setActivityController(IActivityController controller, boolean imAMonkey) {
13088        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13089                "setActivityController()");
13090        synchronized (this) {
13091            mController = controller;
13092            mControllerIsAMonkey = imAMonkey;
13093            Watchdog.getInstance().setActivityController(controller);
13094        }
13095    }
13096
13097    @Override
13098    public void setUserIsMonkey(boolean userIsMonkey) {
13099        synchronized (this) {
13100            synchronized (mPidsSelfLocked) {
13101                final int callingPid = Binder.getCallingPid();
13102                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13103                if (proc == null) {
13104                    throw new SecurityException("Unknown process: " + callingPid);
13105                }
13106                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13107                    throw new SecurityException("Only an instrumentation process "
13108                            + "with a UiAutomation can call setUserIsMonkey");
13109                }
13110            }
13111            mUserIsMonkey = userIsMonkey;
13112        }
13113    }
13114
13115    @Override
13116    public boolean isUserAMonkey() {
13117        synchronized (this) {
13118            // If there is a controller also implies the user is a monkey.
13119            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13120        }
13121    }
13122
13123    /**
13124     * @deprecated This method is only used by a few internal components and it will soon be
13125     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13126     * No new code should be calling it.
13127     */
13128    @Deprecated
13129    @Override
13130    public void requestBugReport(int bugreportType) {
13131        String extraOptions = null;
13132        switch (bugreportType) {
13133            case ActivityManager.BUGREPORT_OPTION_FULL:
13134                // Default options.
13135                break;
13136            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13137                extraOptions = "bugreportplus";
13138                break;
13139            case ActivityManager.BUGREPORT_OPTION_REMOTE:
13140                extraOptions = "bugreportremote";
13141                break;
13142            case ActivityManager.BUGREPORT_OPTION_WEAR:
13143                extraOptions = "bugreportwear";
13144                break;
13145            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13146                extraOptions = "bugreporttelephony";
13147                break;
13148            default:
13149                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13150                        + bugreportType);
13151        }
13152        // Always log caller, even if it does not have permission to dump.
13153        String type = extraOptions == null ? "bugreport" : extraOptions;
13154        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13155
13156        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13157        if (extraOptions != null) {
13158            SystemProperties.set("dumpstate.options", extraOptions);
13159        }
13160        SystemProperties.set("ctl.start", "bugreport");
13161    }
13162
13163    /**
13164     * @deprecated This method is only used by a few internal components and it will soon be
13165     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13166     * No new code should be calling it.
13167     */
13168    @Deprecated
13169    @Override
13170    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13171
13172        if (!TextUtils.isEmpty(shareTitle)) {
13173            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13174                String errorStr = "shareTitle should be less than " +
13175                        MAX_BUGREPORT_TITLE_SIZE + " characters";
13176                throw new IllegalArgumentException(errorStr);
13177            } else {
13178                if (!TextUtils.isEmpty(shareDescription)) {
13179                    int length;
13180                    try {
13181                        length = shareDescription.getBytes("UTF-8").length;
13182                    } catch (UnsupportedEncodingException e) {
13183                        String errorStr = "shareDescription: UnsupportedEncodingException";
13184                        throw new IllegalArgumentException(errorStr);
13185                    }
13186                    if (length > SystemProperties.PROP_VALUE_MAX) {
13187                        String errorStr = "shareTitle should be less than " +
13188                                SystemProperties.PROP_VALUE_MAX + " bytes";
13189                        throw new IllegalArgumentException(errorStr);
13190                    } else {
13191                        SystemProperties.set("dumpstate.options.description", shareDescription);
13192                    }
13193                }
13194                SystemProperties.set("dumpstate.options.title", shareTitle);
13195            }
13196        }
13197
13198        Slog.d(TAG, "Bugreport notification title " + shareTitle
13199                + " description " + shareDescription);
13200        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13201    }
13202
13203    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13204        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13205    }
13206
13207    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13208        if (r != null && (r.instr != null || r.usingWrapper)) {
13209            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13210        }
13211        return KEY_DISPATCHING_TIMEOUT;
13212    }
13213
13214    @Override
13215    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13216        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13217                != PackageManager.PERMISSION_GRANTED) {
13218            throw new SecurityException("Requires permission "
13219                    + android.Manifest.permission.FILTER_EVENTS);
13220        }
13221        ProcessRecord proc;
13222        long timeout;
13223        synchronized (this) {
13224            synchronized (mPidsSelfLocked) {
13225                proc = mPidsSelfLocked.get(pid);
13226            }
13227            timeout = getInputDispatchingTimeoutLocked(proc);
13228        }
13229
13230        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13231            return -1;
13232        }
13233
13234        return timeout;
13235    }
13236
13237    /**
13238     * Handle input dispatching timeouts.
13239     * Returns whether input dispatching should be aborted or not.
13240     */
13241    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13242            final ActivityRecord activity, final ActivityRecord parent,
13243            final boolean aboveSystem, String reason) {
13244        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13245                != PackageManager.PERMISSION_GRANTED) {
13246            throw new SecurityException("Requires permission "
13247                    + android.Manifest.permission.FILTER_EVENTS);
13248        }
13249
13250        final String annotation;
13251        if (reason == null) {
13252            annotation = "Input dispatching timed out";
13253        } else {
13254            annotation = "Input dispatching timed out (" + reason + ")";
13255        }
13256
13257        if (proc != null) {
13258            synchronized (this) {
13259                if (proc.debugging) {
13260                    return false;
13261                }
13262
13263                if (proc.instr != null) {
13264                    Bundle info = new Bundle();
13265                    info.putString("shortMsg", "keyDispatchingTimedOut");
13266                    info.putString("longMsg", annotation);
13267                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13268                    return true;
13269                }
13270            }
13271            mHandler.post(new Runnable() {
13272                @Override
13273                public void run() {
13274                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13275                }
13276            });
13277        }
13278
13279        return true;
13280    }
13281
13282    @Override
13283    public Bundle getAssistContextExtras(int requestType) {
13284        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13285                null, null, true /* focused */, true /* newSessionId */,
13286                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13287        if (pae == null) {
13288            return null;
13289        }
13290        synchronized (pae) {
13291            while (!pae.haveResult) {
13292                try {
13293                    pae.wait();
13294                } catch (InterruptedException e) {
13295                }
13296            }
13297        }
13298        synchronized (this) {
13299            buildAssistBundleLocked(pae, pae.result);
13300            mPendingAssistExtras.remove(pae);
13301            mUiHandler.removeCallbacks(pae);
13302        }
13303        return pae.extras;
13304    }
13305
13306    @Override
13307    public boolean isAssistDataAllowedOnCurrentActivity() {
13308        int userId;
13309        synchronized (this) {
13310            final ActivityStack focusedStack = getFocusedStack();
13311            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
13312                return false;
13313            }
13314
13315            final ActivityRecord activity = focusedStack.getTopActivity();
13316            if (activity == null) {
13317                return false;
13318            }
13319            userId = activity.userId;
13320        }
13321        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13322                Context.DEVICE_POLICY_SERVICE);
13323        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13324    }
13325
13326    @Override
13327    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13328        long ident = Binder.clearCallingIdentity();
13329        try {
13330            synchronized (this) {
13331                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13332                ActivityRecord top = getFocusedStack().getTopActivity();
13333                if (top != caller) {
13334                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13335                            + " is not current top " + top);
13336                    return false;
13337                }
13338                if (!top.nowVisible) {
13339                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13340                            + " is not visible");
13341                    return false;
13342                }
13343            }
13344            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13345                    token);
13346        } finally {
13347            Binder.restoreCallingIdentity(ident);
13348        }
13349    }
13350
13351    @Override
13352    public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
13353            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13354        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13355                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13356                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13357    }
13358
13359    @Override
13360    public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
13361            IBinder activityToken, int flags) {
13362        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13363                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13364                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13365    }
13366
13367    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13368            IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13369            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13370            int flags) {
13371        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13372                "enqueueAssistContext()");
13373
13374        synchronized (this) {
13375            ActivityRecord activity = getFocusedStack().getTopActivity();
13376            if (activity == null) {
13377                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13378                return null;
13379            }
13380            if (activity.app == null || activity.app.thread == null) {
13381                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13382                return null;
13383            }
13384            if (focused) {
13385                if (activityToken != null) {
13386                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13387                    if (activity != caller) {
13388                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13389                                + " is not current top " + activity);
13390                        return null;
13391                    }
13392                }
13393            } else {
13394                activity = ActivityRecord.forTokenLocked(activityToken);
13395                if (activity == null) {
13396                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13397                            + " couldn't be found");
13398                    return null;
13399                }
13400                if (activity.app == null || activity.app.thread == null) {
13401                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13402                    return null;
13403                }
13404            }
13405
13406            PendingAssistExtras pae;
13407            Bundle extras = new Bundle();
13408            if (args != null) {
13409                extras.putAll(args);
13410            }
13411            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13412            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13413
13414            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13415                    userHandle);
13416            pae.isHome = activity.isActivityTypeHome();
13417
13418            // Increment the sessionId if necessary
13419            if (newSessionId) {
13420                mViSessionId++;
13421            }
13422            try {
13423                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13424                        mViSessionId, flags);
13425                mPendingAssistExtras.add(pae);
13426                mUiHandler.postDelayed(pae, timeout);
13427            } catch (RemoteException e) {
13428                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13429                return null;
13430            }
13431            return pae;
13432        }
13433    }
13434
13435    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13436        IAssistDataReceiver receiver;
13437        synchronized (this) {
13438            mPendingAssistExtras.remove(pae);
13439            receiver = pae.receiver;
13440        }
13441        if (receiver != null) {
13442            // Caller wants result sent back to them.
13443            Bundle sendBundle = new Bundle();
13444            // At least return the receiver extras
13445            sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13446            try {
13447                pae.receiver.onHandleAssistData(sendBundle);
13448            } catch (RemoteException e) {
13449            }
13450        }
13451    }
13452
13453    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13454        if (result != null) {
13455            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13456        }
13457        if (pae.hint != null) {
13458            pae.extras.putBoolean(pae.hint, true);
13459        }
13460    }
13461
13462    /** Called from an app when assist data is ready. */
13463    @Override
13464    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13465            AssistContent content, Uri referrer) {
13466        PendingAssistExtras pae = (PendingAssistExtras)token;
13467        synchronized (pae) {
13468            pae.result = extras;
13469            pae.structure = structure;
13470            pae.content = content;
13471            if (referrer != null) {
13472                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13473            }
13474            if (structure != null) {
13475                structure.setHomeActivity(pae.isHome);
13476            }
13477            pae.haveResult = true;
13478            pae.notifyAll();
13479            if (pae.intent == null && pae.receiver == null) {
13480                // Caller is just waiting for the result.
13481                return;
13482            }
13483        }
13484        // We are now ready to launch the assist activity.
13485        IAssistDataReceiver sendReceiver = null;
13486        Bundle sendBundle = null;
13487        synchronized (this) {
13488            buildAssistBundleLocked(pae, extras);
13489            boolean exists = mPendingAssistExtras.remove(pae);
13490            mUiHandler.removeCallbacks(pae);
13491            if (!exists) {
13492                // Timed out.
13493                return;
13494            }
13495            if ((sendReceiver=pae.receiver) != null) {
13496                // Caller wants result sent back to them.
13497                sendBundle = new Bundle();
13498                sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
13499                sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
13500                sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
13501                sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13502            }
13503        }
13504        if (sendReceiver != null) {
13505            try {
13506                sendReceiver.onHandleAssistData(sendBundle);
13507            } catch (RemoteException e) {
13508            }
13509            return;
13510        }
13511
13512        final long ident = Binder.clearCallingIdentity();
13513        try {
13514            if (TextUtils.equals(pae.intent.getAction(),
13515                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13516                pae.intent.putExtras(pae.extras);
13517                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13518            } else {
13519                pae.intent.replaceExtras(pae.extras);
13520                pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
13521                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
13522                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13523                closeSystemDialogs("assist");
13524
13525                try {
13526                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13527                } catch (ActivityNotFoundException e) {
13528                    Slog.w(TAG, "No activity to handle assist action.", e);
13529                }
13530            }
13531        } finally {
13532            Binder.restoreCallingIdentity(ident);
13533        }
13534    }
13535
13536    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13537            Bundle args) {
13538        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13539                true /* focused */, true /* newSessionId */, userHandle, args,
13540                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13541    }
13542
13543    public void registerProcessObserver(IProcessObserver observer) {
13544        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13545                "registerProcessObserver()");
13546        synchronized (this) {
13547            mProcessObservers.register(observer);
13548        }
13549    }
13550
13551    @Override
13552    public void unregisterProcessObserver(IProcessObserver observer) {
13553        synchronized (this) {
13554            mProcessObservers.unregister(observer);
13555        }
13556    }
13557
13558    @Override
13559    public int getUidProcessState(int uid, String callingPackage) {
13560        if (!hasUsageStatsPermission(callingPackage)) {
13561            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13562                    "getUidProcessState");
13563        }
13564
13565        synchronized (this) {
13566            UidRecord uidRec = mActiveUids.get(uid);
13567            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13568        }
13569    }
13570
13571    @Override
13572    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13573            String callingPackage) {
13574        if (!hasUsageStatsPermission(callingPackage)) {
13575            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13576                    "registerUidObserver");
13577        }
13578        synchronized (this) {
13579            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13580                    callingPackage, which, cutpoint));
13581        }
13582    }
13583
13584    @Override
13585    public void unregisterUidObserver(IUidObserver observer) {
13586        synchronized (this) {
13587            mUidObservers.unregister(observer);
13588        }
13589    }
13590
13591    @Override
13592    public boolean convertFromTranslucent(IBinder token) {
13593        final long origId = Binder.clearCallingIdentity();
13594        try {
13595            synchronized (this) {
13596                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13597                if (r == null) {
13598                    return false;
13599                }
13600                final boolean translucentChanged = r.changeWindowTranslucency(true);
13601                if (translucentChanged) {
13602                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13603                }
13604                mWindowManager.setAppFullscreen(token, true);
13605                return translucentChanged;
13606            }
13607        } finally {
13608            Binder.restoreCallingIdentity(origId);
13609        }
13610    }
13611
13612    @Override
13613    public boolean convertToTranslucent(IBinder token, Bundle options) {
13614        SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
13615        final long origId = Binder.clearCallingIdentity();
13616        try {
13617            synchronized (this) {
13618                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13619                if (r == null) {
13620                    return false;
13621                }
13622                final TaskRecord task = r.getTask();
13623                int index = task.mActivities.lastIndexOf(r);
13624                if (index > 0) {
13625                    ActivityRecord under = task.mActivities.get(index - 1);
13626                    under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
13627                }
13628                final boolean translucentChanged = r.changeWindowTranslucency(false);
13629                if (translucentChanged) {
13630                    r.getStack().convertActivityToTranslucent(r);
13631                }
13632                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13633                mWindowManager.setAppFullscreen(token, false);
13634                return translucentChanged;
13635            }
13636        } finally {
13637            Binder.restoreCallingIdentity(origId);
13638        }
13639    }
13640
13641    @Override
13642    public Bundle getActivityOptions(IBinder token) {
13643        final long origId = Binder.clearCallingIdentity();
13644        try {
13645            synchronized (this) {
13646                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13647                if (r != null) {
13648                    final ActivityOptions activityOptions = r.takeOptionsLocked();
13649                    return activityOptions == null ? null : activityOptions.toBundle();
13650                }
13651                return null;
13652            }
13653        } finally {
13654            Binder.restoreCallingIdentity(origId);
13655        }
13656    }
13657
13658    @Override
13659    public void setImmersive(IBinder token, boolean immersive) {
13660        synchronized(this) {
13661            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13662            if (r == null) {
13663                throw new IllegalArgumentException();
13664            }
13665            r.immersive = immersive;
13666
13667            // update associated state if we're frontmost
13668            if (r == mStackSupervisor.getResumedActivityLocked()) {
13669                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13670                applyUpdateLockStateLocked(r);
13671            }
13672        }
13673    }
13674
13675    @Override
13676    public boolean isImmersive(IBinder token) {
13677        synchronized (this) {
13678            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13679            if (r == null) {
13680                throw new IllegalArgumentException();
13681            }
13682            return r.immersive;
13683        }
13684    }
13685
13686    @Override
13687    public void setVrThread(int tid) {
13688        enforceSystemHasVrFeature();
13689        synchronized (this) {
13690            synchronized (mPidsSelfLocked) {
13691                final int pid = Binder.getCallingPid();
13692                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13693                mVrController.setVrThreadLocked(tid, pid, proc);
13694            }
13695        }
13696    }
13697
13698    @Override
13699    public void setPersistentVrThread(int tid) {
13700        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13701            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13702                    + Binder.getCallingPid()
13703                    + ", uid=" + Binder.getCallingUid()
13704                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13705            Slog.w(TAG, msg);
13706            throw new SecurityException(msg);
13707        }
13708        enforceSystemHasVrFeature();
13709        synchronized (this) {
13710            synchronized (mPidsSelfLocked) {
13711                final int pid = Binder.getCallingPid();
13712                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13713                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13714            }
13715        }
13716    }
13717
13718    /**
13719     * Schedule the given thread a normal scheduling priority.
13720     *
13721     * @param tid the tid of the thread to adjust the scheduling of.
13722     * @param suppressLogs {@code true} if any error logging should be disabled.
13723     *
13724     * @return {@code true} if this succeeded.
13725     */
13726    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13727        try {
13728            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13729            return true;
13730        } catch (IllegalArgumentException e) {
13731            if (!suppressLogs) {
13732                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13733            }
13734        } catch (SecurityException e) {
13735            if (!suppressLogs) {
13736                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13737            }
13738        }
13739        return false;
13740    }
13741
13742    /**
13743     * Schedule the given thread an FIFO scheduling priority.
13744     *
13745     * @param tid the tid of the thread to adjust the scheduling of.
13746     * @param suppressLogs {@code true} if any error logging should be disabled.
13747     *
13748     * @return {@code true} if this succeeded.
13749     */
13750    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13751        try {
13752            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13753            return true;
13754        } catch (IllegalArgumentException e) {
13755            if (!suppressLogs) {
13756                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13757            }
13758        } catch (SecurityException e) {
13759            if (!suppressLogs) {
13760                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13761            }
13762        }
13763        return false;
13764    }
13765
13766    /**
13767     * Check that we have the features required for VR-related API calls, and throw an exception if
13768     * not.
13769     */
13770    private void enforceSystemHasVrFeature() {
13771        if (!mContext.getPackageManager().hasSystemFeature(
13772                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
13773            throw new UnsupportedOperationException("VR mode not supported on this device!");
13774        }
13775    }
13776
13777    @Override
13778    public void setRenderThread(int tid) {
13779        synchronized (this) {
13780            ProcessRecord proc;
13781            int pid = Binder.getCallingPid();
13782            if (pid == Process.myPid()) {
13783                demoteSystemServerRenderThread(tid);
13784                return;
13785            }
13786            synchronized (mPidsSelfLocked) {
13787                proc = mPidsSelfLocked.get(pid);
13788                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13789                    // ensure the tid belongs to the process
13790                    if (!isThreadInProcess(pid, tid)) {
13791                        throw new IllegalArgumentException(
13792                            "Render thread does not belong to process");
13793                    }
13794                    proc.renderThreadTid = tid;
13795                    if (DEBUG_OOM_ADJ) {
13796                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13797                    }
13798                    // promote to FIFO now
13799                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13800                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13801                        if (mUseFifoUiScheduling) {
13802                            setThreadScheduler(proc.renderThreadTid,
13803                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13804                        } else {
13805                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13806                        }
13807                    }
13808                } else {
13809                    if (DEBUG_OOM_ADJ) {
13810                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13811                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13812                               mUseFifoUiScheduling);
13813                    }
13814                }
13815            }
13816        }
13817    }
13818
13819    /**
13820     * We only use RenderThread in system_server to store task snapshots to the disk, which should
13821     * happen in the background. Thus, demote render thread from system_server to a lower priority.
13822     *
13823     * @param tid the tid of the RenderThread
13824     */
13825    private void demoteSystemServerRenderThread(int tid) {
13826        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13827    }
13828
13829    @Override
13830    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13831        enforceSystemHasVrFeature();
13832
13833        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13834
13835        ActivityRecord r;
13836        synchronized (this) {
13837            r = ActivityRecord.isInStackLocked(token);
13838        }
13839
13840        if (r == null) {
13841            throw new IllegalArgumentException();
13842        }
13843
13844        int err;
13845        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13846                VrManagerInternal.NO_ERROR) {
13847            return err;
13848        }
13849
13850        synchronized(this) {
13851            r.requestedVrComponent = (enabled) ? packageName : null;
13852
13853            // Update associated state if this activity is currently focused
13854            if (r == mStackSupervisor.getResumedActivityLocked()) {
13855                applyUpdateVrModeLocked(r);
13856            }
13857            return 0;
13858        }
13859    }
13860
13861    @Override
13862    public boolean isVrModePackageEnabled(ComponentName packageName) {
13863        enforceSystemHasVrFeature();
13864
13865        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13866
13867        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13868                VrManagerInternal.NO_ERROR;
13869    }
13870
13871    public boolean isTopActivityImmersive() {
13872        enforceNotIsolatedCaller("startActivity");
13873        synchronized (this) {
13874            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13875            return (r != null) ? r.immersive : false;
13876        }
13877    }
13878
13879    /**
13880     * @return whether the system should disable UI modes incompatible with VR mode.
13881     */
13882    boolean shouldDisableNonVrUiLocked() {
13883        return mVrController.shouldDisableNonVrUiLocked();
13884    }
13885
13886    @Override
13887    public boolean isTopOfTask(IBinder token) {
13888        synchronized (this) {
13889            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13890            if (r == null) {
13891                throw new IllegalArgumentException();
13892            }
13893            return r.getTask().getTopActivity() == r;
13894        }
13895    }
13896
13897    @Override
13898    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13899        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13900            String msg = "Permission Denial: setHasTopUi() from pid="
13901                    + Binder.getCallingPid()
13902                    + ", uid=" + Binder.getCallingUid()
13903                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13904            Slog.w(TAG, msg);
13905            throw new SecurityException(msg);
13906        }
13907        final int pid = Binder.getCallingPid();
13908        final long origId = Binder.clearCallingIdentity();
13909        try {
13910            synchronized (this) {
13911                boolean changed = false;
13912                ProcessRecord pr;
13913                synchronized (mPidsSelfLocked) {
13914                    pr = mPidsSelfLocked.get(pid);
13915                    if (pr == null) {
13916                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13917                        return;
13918                    }
13919                    if (pr.hasTopUi != hasTopUi) {
13920                        if (DEBUG_OOM_ADJ) {
13921                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13922                        }
13923                        pr.hasTopUi = hasTopUi;
13924                        changed = true;
13925                    }
13926                }
13927                if (changed) {
13928                    updateOomAdjLocked(pr, true);
13929                }
13930            }
13931        } finally {
13932            Binder.restoreCallingIdentity(origId);
13933        }
13934    }
13935
13936    public final void enterSafeMode() {
13937        synchronized(this) {
13938            // It only makes sense to do this before the system is ready
13939            // and started launching other packages.
13940            if (!mSystemReady) {
13941                try {
13942                    AppGlobals.getPackageManager().enterSafeMode();
13943                } catch (RemoteException e) {
13944                }
13945            }
13946
13947            mSafeMode = true;
13948        }
13949    }
13950
13951    public final void showSafeModeOverlay() {
13952        View v = LayoutInflater.from(mContext).inflate(
13953                com.android.internal.R.layout.safe_mode, null);
13954        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13955        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13956        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13957        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13958        lp.gravity = Gravity.BOTTOM | Gravity.START;
13959        lp.format = v.getBackground().getOpacity();
13960        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13961                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13962        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13963        ((WindowManager)mContext.getSystemService(
13964                Context.WINDOW_SERVICE)).addView(v, lp);
13965    }
13966
13967    @Override
13968    public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
13969            String sourcePkg, String tag) {
13970        if (workSource != null && workSource.isEmpty()) {
13971            workSource = null;
13972        }
13973
13974        if (sourceUid <= 0 && workSource == null) {
13975            // Try and derive a UID to attribute things to based on the caller.
13976            if (sender != null) {
13977                if (!(sender instanceof PendingIntentRecord)) {
13978                    return;
13979                }
13980
13981                final PendingIntentRecord rec = (PendingIntentRecord) sender;
13982                final int callerUid = Binder.getCallingUid();
13983                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
13984            } else {
13985                // TODO(narayan): Should we throw an exception in this case ? It means that we
13986                // haven't been able to derive a UID to attribute things to.
13987                return;
13988            }
13989        }
13990
13991        if (DEBUG_POWER) {
13992            Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
13993                    + ", workSource=" + workSource + ", tag=" + tag + "]");
13994        }
13995
13996        mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
13997    }
13998
13999    @Override
14000    public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14001            String tag) {
14002        if (workSource != null && workSource.isEmpty()) {
14003            workSource = null;
14004        }
14005
14006        if (sourceUid <= 0 && workSource == null) {
14007            // Try and derive a UID to attribute things to based on the caller.
14008            if (sender != null) {
14009                if (!(sender instanceof PendingIntentRecord)) {
14010                    return;
14011                }
14012
14013                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14014                final int callerUid = Binder.getCallingUid();
14015                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14016            } else {
14017                // TODO(narayan): Should we throw an exception in this case ? It means that we
14018                // haven't been able to derive a UID to attribute things to.
14019                return;
14020            }
14021        }
14022
14023        if (DEBUG_POWER) {
14024            Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14025                    ", tag=" + tag + "]");
14026        }
14027
14028        mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14029    }
14030
14031    @Override
14032    public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14033            String tag) {
14034        if (workSource != null && workSource.isEmpty()) {
14035            workSource = null;
14036        }
14037
14038        if (sourceUid <= 0 && workSource == null) {
14039            // Try and derive a UID to attribute things to based on the caller.
14040            if (sender != null) {
14041                if (!(sender instanceof PendingIntentRecord)) {
14042                    return;
14043                }
14044
14045                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14046                final int callerUid = Binder.getCallingUid();
14047                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14048            } else {
14049                // TODO(narayan): Should we throw an exception in this case ? It means that we
14050                // haven't been able to derive a UID to attribute things to.
14051                return;
14052            }
14053        }
14054
14055        if (DEBUG_POWER) {
14056            Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14057                    ", tag=" + tag + "]");
14058        }
14059
14060        mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
14061    }
14062
14063    public boolean killPids(int[] pids, String pReason, boolean secure) {
14064        if (Binder.getCallingUid() != SYSTEM_UID) {
14065            throw new SecurityException("killPids only available to the system");
14066        }
14067        String reason = (pReason == null) ? "Unknown" : pReason;
14068        // XXX Note: don't acquire main activity lock here, because the window
14069        // manager calls in with its locks held.
14070
14071        boolean killed = false;
14072        synchronized (mPidsSelfLocked) {
14073            int worstType = 0;
14074            for (int i=0; i<pids.length; i++) {
14075                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14076                if (proc != null) {
14077                    int type = proc.setAdj;
14078                    if (type > worstType) {
14079                        worstType = type;
14080                    }
14081                }
14082            }
14083
14084            // If the worst oom_adj is somewhere in the cached proc LRU range,
14085            // then constrain it so we will kill all cached procs.
14086            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14087                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14088                worstType = ProcessList.CACHED_APP_MIN_ADJ;
14089            }
14090
14091            // If this is not a secure call, don't let it kill processes that
14092            // are important.
14093            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14094                worstType = ProcessList.SERVICE_ADJ;
14095            }
14096
14097            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14098            for (int i=0; i<pids.length; i++) {
14099                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14100                if (proc == null) {
14101                    continue;
14102                }
14103                int adj = proc.setAdj;
14104                if (adj >= worstType && !proc.killedByAm) {
14105                    proc.kill(reason, true);
14106                    killed = true;
14107                }
14108            }
14109        }
14110        return killed;
14111    }
14112
14113    @Override
14114    public void killUid(int appId, int userId, String reason) {
14115        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14116        synchronized (this) {
14117            final long identity = Binder.clearCallingIdentity();
14118            try {
14119                killPackageProcessesLocked(null, appId, userId,
14120                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14121                        reason != null ? reason : "kill uid");
14122            } finally {
14123                Binder.restoreCallingIdentity(identity);
14124            }
14125        }
14126    }
14127
14128    @Override
14129    public boolean killProcessesBelowForeground(String reason) {
14130        if (Binder.getCallingUid() != SYSTEM_UID) {
14131            throw new SecurityException("killProcessesBelowForeground() only available to system");
14132        }
14133
14134        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14135    }
14136
14137    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14138        if (Binder.getCallingUid() != SYSTEM_UID) {
14139            throw new SecurityException("killProcessesBelowAdj() only available to system");
14140        }
14141
14142        boolean killed = false;
14143        synchronized (mPidsSelfLocked) {
14144            final int size = mPidsSelfLocked.size();
14145            for (int i = 0; i < size; i++) {
14146                final int pid = mPidsSelfLocked.keyAt(i);
14147                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14148                if (proc == null) continue;
14149
14150                final int adj = proc.setAdj;
14151                if (adj > belowAdj && !proc.killedByAm) {
14152                    proc.kill(reason, true);
14153                    killed = true;
14154                }
14155            }
14156        }
14157        return killed;
14158    }
14159
14160    @Override
14161    public void hang(final IBinder who, boolean allowRestart) {
14162        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14163                != PackageManager.PERMISSION_GRANTED) {
14164            throw new SecurityException("Requires permission "
14165                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14166        }
14167
14168        final IBinder.DeathRecipient death = new DeathRecipient() {
14169            @Override
14170            public void binderDied() {
14171                synchronized (this) {
14172                    notifyAll();
14173                }
14174            }
14175        };
14176
14177        try {
14178            who.linkToDeath(death, 0);
14179        } catch (RemoteException e) {
14180            Slog.w(TAG, "hang: given caller IBinder is already dead.");
14181            return;
14182        }
14183
14184        synchronized (this) {
14185            Watchdog.getInstance().setAllowRestart(allowRestart);
14186            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14187            synchronized (death) {
14188                while (who.isBinderAlive()) {
14189                    try {
14190                        death.wait();
14191                    } catch (InterruptedException e) {
14192                    }
14193                }
14194            }
14195            Watchdog.getInstance().setAllowRestart(true);
14196        }
14197    }
14198
14199    @Override
14200    public void restart() {
14201        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14202                != PackageManager.PERMISSION_GRANTED) {
14203            throw new SecurityException("Requires permission "
14204                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14205        }
14206
14207        Log.i(TAG, "Sending shutdown broadcast...");
14208
14209        BroadcastReceiver br = new BroadcastReceiver() {
14210            @Override public void onReceive(Context context, Intent intent) {
14211                // Now the broadcast is done, finish up the low-level shutdown.
14212                Log.i(TAG, "Shutting down activity manager...");
14213                shutdown(10000);
14214                Log.i(TAG, "Shutdown complete, restarting!");
14215                killProcess(myPid());
14216                System.exit(10);
14217            }
14218        };
14219
14220        // First send the high-level shut down broadcast.
14221        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14222        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14223        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
14224        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
14225        mContext.sendOrderedBroadcastAsUser(intent,
14226                UserHandle.ALL, null, br, mHandler, 0, null, null);
14227        */
14228        br.onReceive(mContext, intent);
14229    }
14230
14231    private long getLowRamTimeSinceIdle(long now) {
14232        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
14233    }
14234
14235    @Override
14236    public void performIdleMaintenance() {
14237        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14238                != PackageManager.PERMISSION_GRANTED) {
14239            throw new SecurityException("Requires permission "
14240                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14241        }
14242
14243        synchronized (this) {
14244            final long now = SystemClock.uptimeMillis();
14245            final long timeSinceLastIdle = now - mLastIdleTime;
14246            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
14247            mLastIdleTime = now;
14248            mLowRamTimeSinceLastIdle = 0;
14249            if (mLowRamStartTime != 0) {
14250                mLowRamStartTime = now;
14251            }
14252
14253            StringBuilder sb = new StringBuilder(128);
14254            sb.append("Idle maintenance over ");
14255            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14256            sb.append(" low RAM for ");
14257            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14258            Slog.i(TAG, sb.toString());
14259
14260            // If at least 1/3 of our time since the last idle period has been spent
14261            // with RAM low, then we want to kill processes.
14262            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14263
14264            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14265                ProcessRecord proc = mLruProcesses.get(i);
14266                if (proc.notCachedSinceIdle) {
14267                    if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
14268                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14269                        if (doKilling && proc.initialIdlePss != 0
14270                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14271                            sb = new StringBuilder(128);
14272                            sb.append("Kill");
14273                            sb.append(proc.processName);
14274                            sb.append(" in idle maint: pss=");
14275                            sb.append(proc.lastPss);
14276                            sb.append(", swapPss=");
14277                            sb.append(proc.lastSwapPss);
14278                            sb.append(", initialPss=");
14279                            sb.append(proc.initialIdlePss);
14280                            sb.append(", period=");
14281                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14282                            sb.append(", lowRamPeriod=");
14283                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14284                            Slog.wtfQuiet(TAG, sb.toString());
14285                            proc.kill("idle maint (pss " + proc.lastPss
14286                                    + " from " + proc.initialIdlePss + ")", true);
14287                        }
14288                    }
14289                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14290                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14291                    proc.notCachedSinceIdle = true;
14292                    proc.initialIdlePss = 0;
14293                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14294                            mTestPssMode, isSleepingLocked(), now);
14295                }
14296            }
14297
14298            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14299            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14300        }
14301    }
14302
14303    @Override
14304    public void sendIdleJobTrigger() {
14305        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14306                != PackageManager.PERMISSION_GRANTED) {
14307            throw new SecurityException("Requires permission "
14308                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14309        }
14310
14311        final long ident = Binder.clearCallingIdentity();
14312        try {
14313            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14314                    .setPackage("android")
14315                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14316            broadcastIntent(null, intent, null, null, 0, null, null, null,
14317                    OP_NONE, null, true, false, UserHandle.USER_ALL);
14318        } finally {
14319            Binder.restoreCallingIdentity(ident);
14320        }
14321    }
14322
14323    private void retrieveSettings() {
14324        final ContentResolver resolver = mContext.getContentResolver();
14325        final boolean freeformWindowManagement =
14326                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14327                        || Settings.Global.getInt(
14328                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14329
14330        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14331        final boolean supportsPictureInPicture = supportsMultiWindow &&
14332                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14333        final boolean supportsSplitScreenMultiWindow =
14334                ActivityManager.supportsSplitScreenMultiWindow(mContext);
14335        final boolean supportsMultiDisplay = mContext.getPackageManager()
14336                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14337        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14338        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14339        final boolean alwaysFinishActivities =
14340                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14341        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14342        final boolean forceResizable = Settings.Global.getInt(
14343                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14344        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14345                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14346        final boolean supportsLeanbackOnly =
14347                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14348
14349        // Transfer any global setting for forcing RTL layout, into a System Property
14350        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14351
14352        final Configuration configuration = new Configuration();
14353        Settings.System.getConfiguration(resolver, configuration);
14354        if (forceRtl) {
14355            // This will take care of setting the correct layout direction flags
14356            configuration.setLayoutDirection(configuration.locale);
14357        }
14358
14359        synchronized (this) {
14360            mDebugApp = mOrigDebugApp = debugApp;
14361            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14362            mAlwaysFinishActivities = alwaysFinishActivities;
14363            mSupportsLeanbackOnly = supportsLeanbackOnly;
14364            mForceResizableActivities = forceResizable;
14365            final boolean multiWindowFormEnabled = freeformWindowManagement
14366                    || supportsSplitScreenMultiWindow
14367                    || supportsPictureInPicture
14368                    || supportsMultiDisplay;
14369            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14370                mSupportsMultiWindow = true;
14371                mSupportsFreeformWindowManagement = freeformWindowManagement;
14372                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14373                mSupportsPictureInPicture = supportsPictureInPicture;
14374                mSupportsMultiDisplay = supportsMultiDisplay;
14375            } else {
14376                mSupportsMultiWindow = false;
14377                mSupportsFreeformWindowManagement = false;
14378                mSupportsSplitScreenMultiWindow = false;
14379                mSupportsPictureInPicture = false;
14380                mSupportsMultiDisplay = false;
14381            }
14382            mWindowManager.setForceResizableTasks(mForceResizableActivities);
14383            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14384            // This happens before any activities are started, so we can change global configuration
14385            // in-place.
14386            updateConfigurationLocked(configuration, null, true);
14387            final Configuration globalConfig = getGlobalConfiguration();
14388            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14389
14390            // Load resources only after the current configuration has been set.
14391            final Resources res = mContext.getResources();
14392            mThumbnailWidth = res.getDimensionPixelSize(
14393                    com.android.internal.R.dimen.thumbnail_width);
14394            mThumbnailHeight = res.getDimensionPixelSize(
14395                    com.android.internal.R.dimen.thumbnail_height);
14396            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14397                    com.android.internal.R.string.config_appsNotReportingCrashes));
14398            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14399                    com.android.internal.R.bool.config_customUserSwitchUi);
14400            mUserController.mMaxRunningUsers = res.getInteger(
14401                    com.android.internal.R.integer.config_multiuserMaxRunningUsers);
14402
14403            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14404                mFullscreenThumbnailScale = (float) res
14405                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14406                    (float) globalConfig.screenWidthDp;
14407            } else {
14408                mFullscreenThumbnailScale = res.getFraction(
14409                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14410            }
14411            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14412        }
14413    }
14414
14415    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14416        traceLog.traceBegin("PhaseActivityManagerReady");
14417        synchronized(this) {
14418            if (mSystemReady) {
14419                // If we're done calling all the receivers, run the next "boot phase" passed in
14420                // by the SystemServer
14421                if (goingCallback != null) {
14422                    goingCallback.run();
14423                }
14424                return;
14425            }
14426
14427            mLocalDeviceIdleController
14428                    = LocalServices.getService(DeviceIdleController.LocalService.class);
14429            mAssistUtils = new AssistUtils(mContext);
14430            mVrController.onSystemReady();
14431            // Make sure we have the current profile info, since it is needed for security checks.
14432            mUserController.onSystemReady();
14433            mRecentTasks.onSystemReadyLocked();
14434            mAppOpsService.systemReady();
14435            mSystemReady = true;
14436        }
14437
14438        try {
14439            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14440                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14441                    .getSerial();
14442        } catch (RemoteException e) {}
14443
14444        ArrayList<ProcessRecord> procsToKill = null;
14445        synchronized(mPidsSelfLocked) {
14446            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14447                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14448                if (!isAllowedWhileBooting(proc.info)){
14449                    if (procsToKill == null) {
14450                        procsToKill = new ArrayList<ProcessRecord>();
14451                    }
14452                    procsToKill.add(proc);
14453                }
14454            }
14455        }
14456
14457        synchronized(this) {
14458            if (procsToKill != null) {
14459                for (int i=procsToKill.size()-1; i>=0; i--) {
14460                    ProcessRecord proc = procsToKill.get(i);
14461                    Slog.i(TAG, "Removing system update proc: " + proc);
14462                    removeProcessLocked(proc, true, false, "system update done");
14463                }
14464            }
14465
14466            // Now that we have cleaned up any update processes, we
14467            // are ready to start launching real processes and know that
14468            // we won't trample on them any more.
14469            mProcessesReady = true;
14470        }
14471
14472        Slog.i(TAG, "System now ready");
14473        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14474            SystemClock.uptimeMillis());
14475
14476        synchronized(this) {
14477            // Make sure we have no pre-ready processes sitting around.
14478
14479            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14480                ResolveInfo ri = mContext.getPackageManager()
14481                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14482                                STOCK_PM_FLAGS);
14483                CharSequence errorMsg = null;
14484                if (ri != null) {
14485                    ActivityInfo ai = ri.activityInfo;
14486                    ApplicationInfo app = ai.applicationInfo;
14487                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14488                        mTopAction = Intent.ACTION_FACTORY_TEST;
14489                        mTopData = null;
14490                        mTopComponent = new ComponentName(app.packageName,
14491                                ai.name);
14492                    } else {
14493                        errorMsg = mContext.getResources().getText(
14494                                com.android.internal.R.string.factorytest_not_system);
14495                    }
14496                } else {
14497                    errorMsg = mContext.getResources().getText(
14498                            com.android.internal.R.string.factorytest_no_action);
14499                }
14500                if (errorMsg != null) {
14501                    mTopAction = null;
14502                    mTopData = null;
14503                    mTopComponent = null;
14504                    Message msg = Message.obtain();
14505                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14506                    msg.getData().putCharSequence("msg", errorMsg);
14507                    mUiHandler.sendMessage(msg);
14508                }
14509            }
14510        }
14511
14512        retrieveSettings();
14513        final int currentUserId = mUserController.getCurrentUserId();
14514        synchronized (this) {
14515            readGrantedUriPermissionsLocked();
14516        }
14517
14518        final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
14519        if (pmi != null) {
14520            pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
14521                    state -> updateForceBackgroundCheck(state.batterySaverEnabled));
14522            updateForceBackgroundCheck(
14523                    pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
14524        } else {
14525            Slog.wtf(TAG, "PowerManagerInternal not found.");
14526        }
14527
14528        if (goingCallback != null) goingCallback.run();
14529        traceLog.traceBegin("ActivityManagerStartApps");
14530        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14531                Integer.toString(currentUserId), currentUserId);
14532        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14533                Integer.toString(currentUserId), currentUserId);
14534        mSystemServiceManager.startUser(currentUserId);
14535
14536        synchronized (this) {
14537            // Only start up encryption-aware persistent apps; once user is
14538            // unlocked we'll come back around and start unaware apps
14539            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14540
14541            // Start up initial activity.
14542            mBooting = true;
14543            // Enable home activity for system user, so that the system can always boot. We don't
14544            // do this when the system user is not setup since the setup wizard should be the one
14545            // to handle home activity in this case.
14546            if (UserManager.isSplitSystemUser() &&
14547                    Settings.Secure.getInt(mContext.getContentResolver(),
14548                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14549                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14550                try {
14551                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14552                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14553                            UserHandle.USER_SYSTEM);
14554                } catch (RemoteException e) {
14555                    throw e.rethrowAsRuntimeException();
14556                }
14557            }
14558            startHomeActivityLocked(currentUserId, "systemReady");
14559
14560            try {
14561                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14562                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14563                            + " data partition or your device will be unstable.");
14564                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14565                }
14566            } catch (RemoteException e) {
14567            }
14568
14569            if (!Build.isBuildConsistent()) {
14570                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14571                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14572            }
14573
14574            long ident = Binder.clearCallingIdentity();
14575            try {
14576                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14577                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14578                        | Intent.FLAG_RECEIVER_FOREGROUND);
14579                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14580                broadcastIntentLocked(null, null, intent,
14581                        null, null, 0, null, null, null, OP_NONE,
14582                        null, false, false, MY_PID, SYSTEM_UID,
14583                        currentUserId);
14584                intent = new Intent(Intent.ACTION_USER_STARTING);
14585                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14586                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14587                broadcastIntentLocked(null, null, intent,
14588                        null, new IIntentReceiver.Stub() {
14589                            @Override
14590                            public void performReceive(Intent intent, int resultCode, String data,
14591                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14592                                    throws RemoteException {
14593                            }
14594                        }, 0, null, null,
14595                        new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
14596                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14597            } catch (Throwable t) {
14598                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14599            } finally {
14600                Binder.restoreCallingIdentity(ident);
14601            }
14602            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14603            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
14604
14605            BinderInternal.nSetBinderProxyCountEnabled(true);
14606            BinderInternal.setBinderProxyCountCallback(
14607                    new BinderInternal.BinderProxyLimitListener() {
14608                        @Override
14609                        public void onLimitReached(int uid) {
14610                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
14611                                    + Process.myUid());
14612                            if (uid == Process.SYSTEM_UID) {
14613                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
14614                            } else {
14615                                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
14616                                        "Too many Binders sent to SYSTEM");
14617                            }
14618                        }
14619                    }, mHandler);
14620
14621            traceLog.traceEnd(); // ActivityManagerStartApps
14622            traceLog.traceEnd(); // PhaseActivityManagerReady
14623        }
14624    }
14625
14626    private void updateForceBackgroundCheck(boolean enabled) {
14627        synchronized (this) {
14628            if (mForceBackgroundCheck != enabled) {
14629                mForceBackgroundCheck = enabled;
14630
14631                if (DEBUG_BACKGROUND_CHECK) {
14632                    Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
14633                }
14634
14635                if (mForceBackgroundCheck) {
14636                    // Stop background services for idle UIDs.
14637                    doStopUidForIdleUidsLocked();
14638                }
14639            }
14640        }
14641    }
14642
14643    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14644        synchronized (this) {
14645            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14646        }
14647    }
14648
14649    void skipCurrentReceiverLocked(ProcessRecord app) {
14650        for (BroadcastQueue queue : mBroadcastQueues) {
14651            queue.skipCurrentReceiverLocked(app);
14652        }
14653    }
14654
14655    /**
14656     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14657     * The application process will exit immediately after this call returns.
14658     * @param app object of the crashing app, null for the system server
14659     * @param crashInfo describing the exception
14660     */
14661    public void handleApplicationCrash(IBinder app,
14662            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14663        ProcessRecord r = findAppProcess(app, "Crash");
14664        final String processName = app == null ? "system_server"
14665                : (r == null ? "unknown" : r.processName);
14666
14667        handleApplicationCrashInner("crash", r, processName, crashInfo);
14668    }
14669
14670    /* Native crash reporting uses this inner version because it needs to be somewhat
14671     * decoupled from the AM-managed cleanup lifecycle
14672     */
14673    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14674            ApplicationErrorReport.CrashInfo crashInfo) {
14675        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14676                UserHandle.getUserId(Binder.getCallingUid()), processName,
14677                r == null ? -1 : r.info.flags,
14678                crashInfo.exceptionClassName,
14679                crashInfo.exceptionMessage,
14680                crashInfo.throwFileName,
14681                crashInfo.throwLineNumber);
14682
14683        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14684
14685        mAppErrors.crashApplication(r, crashInfo);
14686    }
14687
14688    public void handleApplicationStrictModeViolation(
14689            IBinder app,
14690            int violationMask,
14691            StrictMode.ViolationInfo info) {
14692        // We're okay if the ProcessRecord is missing; it probably means that
14693        // we're reporting a violation from the system process itself.
14694        final ProcessRecord r = findAppProcess(app, "StrictMode");
14695
14696        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14697            Integer stackFingerprint = info.hashCode();
14698            boolean logIt = true;
14699            synchronized (mAlreadyLoggedViolatedStacks) {
14700                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14701                    logIt = false;
14702                    // TODO: sub-sample into EventLog for these, with
14703                    // the info.durationMillis?  Then we'd get
14704                    // the relative pain numbers, without logging all
14705                    // the stack traces repeatedly.  We'd want to do
14706                    // likewise in the client code, which also does
14707                    // dup suppression, before the Binder call.
14708                } else {
14709                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14710                        mAlreadyLoggedViolatedStacks.clear();
14711                    }
14712                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14713                }
14714            }
14715            if (logIt) {
14716                logStrictModeViolationToDropBox(r, info);
14717            }
14718        }
14719
14720        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14721            AppErrorResult result = new AppErrorResult();
14722            synchronized (this) {
14723                final long origId = Binder.clearCallingIdentity();
14724
14725                Message msg = Message.obtain();
14726                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14727                HashMap<String, Object> data = new HashMap<String, Object>();
14728                data.put("result", result);
14729                data.put("app", r);
14730                data.put("violationMask", violationMask);
14731                data.put("info", info);
14732                msg.obj = data;
14733                mUiHandler.sendMessage(msg);
14734
14735                Binder.restoreCallingIdentity(origId);
14736            }
14737            int res = result.get();
14738            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14739        }
14740    }
14741
14742    // Depending on the policy in effect, there could be a bunch of
14743    // these in quick succession so we try to batch these together to
14744    // minimize disk writes, number of dropbox entries, and maximize
14745    // compression, by having more fewer, larger records.
14746    private void logStrictModeViolationToDropBox(
14747            ProcessRecord process,
14748            StrictMode.ViolationInfo info) {
14749        if (info == null) {
14750            return;
14751        }
14752        final boolean isSystemApp = process == null ||
14753                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14754                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14755        final String processName = process == null ? "unknown" : process.processName;
14756        final DropBoxManager dbox = (DropBoxManager)
14757                mContext.getSystemService(Context.DROPBOX_SERVICE);
14758
14759        // Exit early if the dropbox isn't configured to accept this report type.
14760        final String dropboxTag = processClass(process) + "_strictmode";
14761        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14762
14763        final StringBuilder sb = new StringBuilder(1024);
14764        synchronized (sb) {
14765            appendDropBoxProcessHeaders(process, processName, sb);
14766            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14767            sb.append("System-App: ").append(isSystemApp).append("\n");
14768            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14769            if (info.violationNumThisLoop != 0) {
14770                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14771            }
14772            if (info.numAnimationsRunning != 0) {
14773                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14774            }
14775            if (info.broadcastIntentAction != null) {
14776                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14777            }
14778            if (info.durationMillis != -1) {
14779                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14780            }
14781            if (info.numInstances != -1) {
14782                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14783            }
14784            if (info.tags != null) {
14785                for (String tag : info.tags) {
14786                    sb.append("Span-Tag: ").append(tag).append("\n");
14787                }
14788            }
14789            sb.append("\n");
14790            sb.append(info.getStackTrace());
14791            sb.append("\n");
14792            if (info.getViolationDetails() != null) {
14793                sb.append(info.getViolationDetails());
14794                sb.append("\n");
14795            }
14796        }
14797
14798        final String res = sb.toString();
14799        IoThread.getHandler().post(() -> {
14800            dbox.addText(dropboxTag, res);
14801        });
14802    }
14803
14804    /**
14805     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14806     * @param app object of the crashing app, null for the system server
14807     * @param tag reported by the caller
14808     * @param system whether this wtf is coming from the system
14809     * @param crashInfo describing the context of the error
14810     * @return true if the process should exit immediately (WTF is fatal)
14811     */
14812    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14813            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14814        final int callingUid = Binder.getCallingUid();
14815        final int callingPid = Binder.getCallingPid();
14816
14817        if (system) {
14818            // If this is coming from the system, we could very well have low-level
14819            // system locks held, so we want to do this all asynchronously.  And we
14820            // never want this to become fatal, so there is that too.
14821            mHandler.post(new Runnable() {
14822                @Override public void run() {
14823                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14824                }
14825            });
14826            return false;
14827        }
14828
14829        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14830                crashInfo);
14831
14832        final boolean isFatal = Build.IS_ENG || Settings.Global
14833                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14834        final boolean isSystem = (r == null) || r.persistent;
14835
14836        if (isFatal && !isSystem) {
14837            mAppErrors.crashApplication(r, crashInfo);
14838            return true;
14839        } else {
14840            return false;
14841        }
14842    }
14843
14844    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14845            final ApplicationErrorReport.CrashInfo crashInfo) {
14846        final ProcessRecord r = findAppProcess(app, "WTF");
14847        final String processName = app == null ? "system_server"
14848                : (r == null ? "unknown" : r.processName);
14849
14850        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14851                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14852
14853        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14854
14855        return r;
14856    }
14857
14858    /**
14859     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14860     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14861     */
14862    private ProcessRecord findAppProcess(IBinder app, String reason) {
14863        if (app == null) {
14864            return null;
14865        }
14866
14867        synchronized (this) {
14868            final int NP = mProcessNames.getMap().size();
14869            for (int ip=0; ip<NP; ip++) {
14870                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14871                final int NA = apps.size();
14872                for (int ia=0; ia<NA; ia++) {
14873                    ProcessRecord p = apps.valueAt(ia);
14874                    if (p.thread != null && p.thread.asBinder() == app) {
14875                        return p;
14876                    }
14877                }
14878            }
14879
14880            Slog.w(TAG, "Can't find mystery application for " + reason
14881                    + " from pid=" + Binder.getCallingPid()
14882                    + " uid=" + Binder.getCallingUid() + ": " + app);
14883            return null;
14884        }
14885    }
14886
14887    /**
14888     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14889     * to append various headers to the dropbox log text.
14890     */
14891    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14892            StringBuilder sb) {
14893        // Watchdog thread ends up invoking this function (with
14894        // a null ProcessRecord) to add the stack file to dropbox.
14895        // Do not acquire a lock on this (am) in such cases, as it
14896        // could cause a potential deadlock, if and when watchdog
14897        // is invoked due to unavailability of lock on am and it
14898        // would prevent watchdog from killing system_server.
14899        if (process == null) {
14900            sb.append("Process: ").append(processName).append("\n");
14901            return;
14902        }
14903        // Note: ProcessRecord 'process' is guarded by the service
14904        // instance.  (notably process.pkgList, which could otherwise change
14905        // concurrently during execution of this method)
14906        synchronized (this) {
14907            sb.append("Process: ").append(processName).append("\n");
14908            sb.append("PID: ").append(process.pid).append("\n");
14909            int flags = process.info.flags;
14910            IPackageManager pm = AppGlobals.getPackageManager();
14911            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14912            for (int ip=0; ip<process.pkgList.size(); ip++) {
14913                String pkg = process.pkgList.keyAt(ip);
14914                sb.append("Package: ").append(pkg);
14915                try {
14916                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14917                    if (pi != null) {
14918                        sb.append(" v").append(pi.getLongVersionCode());
14919                        if (pi.versionName != null) {
14920                            sb.append(" (").append(pi.versionName).append(")");
14921                        }
14922                    }
14923                } catch (RemoteException e) {
14924                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14925                }
14926                sb.append("\n");
14927            }
14928            if (process.info.isInstantApp()) {
14929                sb.append("Instant-App: true\n");
14930            }
14931        }
14932    }
14933
14934    private static String processClass(ProcessRecord process) {
14935        if (process == null || process.pid == MY_PID) {
14936            return "system_server";
14937        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14938            return "system_app";
14939        } else {
14940            return "data_app";
14941        }
14942    }
14943
14944    private volatile long mWtfClusterStart;
14945    private volatile int mWtfClusterCount;
14946
14947    /**
14948     * Write a description of an error (crash, WTF, ANR) to the drop box.
14949     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14950     * @param process which caused the error, null means the system server
14951     * @param activity which triggered the error, null if unknown
14952     * @param parent activity related to the error, null if unknown
14953     * @param subject line related to the error, null if absent
14954     * @param report in long form describing the error, null if absent
14955     * @param dataFile text file to include in the report, null if none
14956     * @param crashInfo giving an application stack trace, null if absent
14957     */
14958    public void addErrorToDropBox(String eventType,
14959            ProcessRecord process, String processName, ActivityRecord activity,
14960            ActivityRecord parent, String subject,
14961            final String report, final File dataFile,
14962            final ApplicationErrorReport.CrashInfo crashInfo) {
14963        // NOTE -- this must never acquire the ActivityManagerService lock,
14964        // otherwise the watchdog may be prevented from resetting the system.
14965
14966        // Bail early if not published yet
14967        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14968        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14969
14970        // Exit early if the dropbox isn't configured to accept this report type.
14971        final String dropboxTag = processClass(process) + "_" + eventType;
14972        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14973
14974        // Log to StatsLog before the rate-limiting.
14975        // The logging below is adapated from appendDropboxProcessHeaders.
14976        StatsLog.write(StatsLog.DROPBOX_ERROR_CHANGED,
14977                process != null ? process.uid : -1,
14978                dropboxTag,
14979                processName,
14980                process != null ? process.pid : -1,
14981                (process != null && process.info != null) ?
14982                        (process.info.isInstantApp() ? 1 : 0) : -1,
14983                activity != null ? activity.shortComponentName : null,
14984                activity != null ? activity.packageName : null,
14985                process != null ? (process.isInterestingToUserLocked() ? 1 : 0) : -1);
14986
14987        // Rate-limit how often we're willing to do the heavy lifting below to
14988        // collect and record logs; currently 5 logs per 10 second period.
14989        final long now = SystemClock.elapsedRealtime();
14990        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14991            mWtfClusterStart = now;
14992            mWtfClusterCount = 1;
14993        } else {
14994            if (mWtfClusterCount++ >= 5) return;
14995        }
14996
14997        final StringBuilder sb = new StringBuilder(1024);
14998        appendDropBoxProcessHeaders(process, processName, sb);
14999        if (process != null) {
15000            sb.append("Foreground: ")
15001                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
15002                    .append("\n");
15003        }
15004        if (activity != null) {
15005            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15006        }
15007        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15008            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15009        }
15010        if (parent != null && parent != activity) {
15011            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15012        }
15013        if (subject != null) {
15014            sb.append("Subject: ").append(subject).append("\n");
15015        }
15016        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15017        if (Debug.isDebuggerConnected()) {
15018            sb.append("Debugger: Connected\n");
15019        }
15020        sb.append("\n");
15021
15022        // Do the rest in a worker thread to avoid blocking the caller on I/O
15023        // (After this point, we shouldn't access AMS internal data structures.)
15024        Thread worker = new Thread("Error dump: " + dropboxTag) {
15025            @Override
15026            public void run() {
15027                if (report != null) {
15028                    sb.append(report);
15029                }
15030
15031                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
15032                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
15033                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
15034                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
15035
15036                if (dataFile != null && maxDataFileSize > 0) {
15037                    try {
15038                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15039                                    "\n\n[[TRUNCATED]]"));
15040                    } catch (IOException e) {
15041                        Slog.e(TAG, "Error reading " + dataFile, e);
15042                    }
15043                }
15044                if (crashInfo != null && crashInfo.stackTrace != null) {
15045                    sb.append(crashInfo.stackTrace);
15046                }
15047
15048                if (lines > 0) {
15049                    sb.append("\n");
15050
15051                    // Merge several logcat streams, and take the last N lines
15052                    InputStreamReader input = null;
15053                    try {
15054                        java.lang.Process logcat = new ProcessBuilder(
15055                                "/system/bin/timeout", "-k", "15s", "10s",
15056                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
15057                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
15058                                        .redirectErrorStream(true).start();
15059
15060                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
15061                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
15062                        input = new InputStreamReader(logcat.getInputStream());
15063
15064                        int num;
15065                        char[] buf = new char[8192];
15066                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
15067                    } catch (IOException e) {
15068                        Slog.e(TAG, "Error running logcat", e);
15069                    } finally {
15070                        if (input != null) try { input.close(); } catch (IOException e) {}
15071                    }
15072                }
15073
15074                dbox.addText(dropboxTag, sb.toString());
15075            }
15076        };
15077
15078        if (process == null) {
15079            // If process is null, we are being called from some internal code
15080            // and may be about to die -- run this synchronously.
15081            final int oldMask = StrictMode.allowThreadDiskWritesMask();
15082            try {
15083                worker.run();
15084            } finally {
15085                StrictMode.setThreadPolicyMask(oldMask);
15086            }
15087        } else {
15088            worker.start();
15089        }
15090    }
15091
15092    @Override
15093    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15094        enforceNotIsolatedCaller("getProcessesInErrorState");
15095        // assume our apps are happy - lazy create the list
15096        List<ActivityManager.ProcessErrorStateInfo> errList = null;
15097
15098        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15099                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15100        int userId = UserHandle.getUserId(Binder.getCallingUid());
15101
15102        synchronized (this) {
15103
15104            // iterate across all processes
15105            for (int i=mLruProcesses.size()-1; i>=0; i--) {
15106                ProcessRecord app = mLruProcesses.get(i);
15107                if (!allUsers && app.userId != userId) {
15108                    continue;
15109                }
15110                if ((app.thread != null) && (app.crashing || app.notResponding)) {
15111                    // This one's in trouble, so we'll generate a report for it
15112                    // crashes are higher priority (in case there's a crash *and* an anr)
15113                    ActivityManager.ProcessErrorStateInfo report = null;
15114                    if (app.crashing) {
15115                        report = app.crashingReport;
15116                    } else if (app.notResponding) {
15117                        report = app.notRespondingReport;
15118                    }
15119
15120                    if (report != null) {
15121                        if (errList == null) {
15122                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15123                        }
15124                        errList.add(report);
15125                    } else {
15126                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
15127                                " crashing = " + app.crashing +
15128                                " notResponding = " + app.notResponding);
15129                    }
15130                }
15131            }
15132        }
15133
15134        return errList;
15135    }
15136
15137    static int procStateToImportance(int procState, int memAdj,
15138            ActivityManager.RunningAppProcessInfo currApp,
15139            int clientTargetSdk) {
15140        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15141                procState, clientTargetSdk);
15142        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15143            currApp.lru = memAdj;
15144        } else {
15145            currApp.lru = 0;
15146        }
15147        return imp;
15148    }
15149
15150    private void fillInProcMemInfo(ProcessRecord app,
15151            ActivityManager.RunningAppProcessInfo outInfo,
15152            int clientTargetSdk) {
15153        outInfo.pid = app.pid;
15154        outInfo.uid = app.info.uid;
15155        if (mHeavyWeightProcess == app) {
15156            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15157        }
15158        if (app.persistent) {
15159            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15160        }
15161        if (app.activities.size() > 0) {
15162            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15163        }
15164        outInfo.lastTrimLevel = app.trimMemoryLevel;
15165        int adj = app.curAdj;
15166        int procState = app.curProcState;
15167        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15168        outInfo.importanceReasonCode = app.adjTypeCode;
15169        outInfo.processState = app.curProcState;
15170    }
15171
15172    @Override
15173    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15174        enforceNotIsolatedCaller("getRunningAppProcesses");
15175
15176        final int callingUid = Binder.getCallingUid();
15177        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15178
15179        // Lazy instantiation of list
15180        List<ActivityManager.RunningAppProcessInfo> runList = null;
15181        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15182                callingUid) == PackageManager.PERMISSION_GRANTED;
15183        final int userId = UserHandle.getUserId(callingUid);
15184        final boolean allUids = isGetTasksAllowed(
15185                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
15186
15187        synchronized (this) {
15188            // Iterate across all processes
15189            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15190                ProcessRecord app = mLruProcesses.get(i);
15191                if ((!allUsers && app.userId != userId)
15192                        || (!allUids && app.uid != callingUid)) {
15193                    continue;
15194                }
15195                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15196                    // Generate process state info for running application
15197                    ActivityManager.RunningAppProcessInfo currApp =
15198                        new ActivityManager.RunningAppProcessInfo(app.processName,
15199                                app.pid, app.getPackageList());
15200                    fillInProcMemInfo(app, currApp, clientTargetSdk);
15201                    if (app.adjSource instanceof ProcessRecord) {
15202                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15203                        currApp.importanceReasonImportance =
15204                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
15205                                        app.adjSourceProcState);
15206                    } else if (app.adjSource instanceof ActivityRecord) {
15207                        ActivityRecord r = (ActivityRecord)app.adjSource;
15208                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15209                    }
15210                    if (app.adjTarget instanceof ComponentName) {
15211                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15212                    }
15213                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15214                    //        + " lru=" + currApp.lru);
15215                    if (runList == null) {
15216                        runList = new ArrayList<>();
15217                    }
15218                    runList.add(currApp);
15219                }
15220            }
15221        }
15222        return runList;
15223    }
15224
15225    @Override
15226    public List<ApplicationInfo> getRunningExternalApplications() {
15227        enforceNotIsolatedCaller("getRunningExternalApplications");
15228        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
15229        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
15230        if (runningApps != null && runningApps.size() > 0) {
15231            Set<String> extList = new HashSet<String>();
15232            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
15233                if (app.pkgList != null) {
15234                    for (String pkg : app.pkgList) {
15235                        extList.add(pkg);
15236                    }
15237                }
15238            }
15239            IPackageManager pm = AppGlobals.getPackageManager();
15240            for (String pkg : extList) {
15241                try {
15242                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
15243                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
15244                        retList.add(info);
15245                    }
15246                } catch (RemoteException e) {
15247                }
15248            }
15249        }
15250        return retList;
15251    }
15252
15253    @Override
15254    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15255        enforceNotIsolatedCaller("getMyMemoryState");
15256
15257        final int callingUid = Binder.getCallingUid();
15258        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15259
15260        synchronized (this) {
15261            ProcessRecord proc;
15262            synchronized (mPidsSelfLocked) {
15263                proc = mPidsSelfLocked.get(Binder.getCallingPid());
15264            }
15265            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15266        }
15267    }
15268
15269    @Override
15270    public int getMemoryTrimLevel() {
15271        enforceNotIsolatedCaller("getMyMemoryState");
15272        synchronized (this) {
15273            return mLastMemoryLevel;
15274        }
15275    }
15276
15277    @Override
15278    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15279            FileDescriptor err, String[] args, ShellCallback callback,
15280            ResultReceiver resultReceiver) {
15281        (new ActivityManagerShellCommand(this, false)).exec(
15282                this, in, out, err, args, callback, resultReceiver);
15283    }
15284
15285    SleepToken acquireSleepToken(String tag, int displayId) {
15286        synchronized (this) {
15287            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15288            updateSleepIfNeededLocked();
15289            return token;
15290        }
15291    }
15292
15293    @Override
15294    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15295        PriorityDump.dump(mPriorityDumper, fd, pw, args);
15296    }
15297
15298    /**
15299     * Wrapper function to print out debug data filtered by specified arguments.
15300    */
15301    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
15302        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15303
15304        boolean dumpAll = false;
15305        boolean dumpClient = false;
15306        boolean dumpCheckin = false;
15307        boolean dumpCheckinFormat = false;
15308        boolean dumpVisibleStacksOnly = false;
15309        boolean dumpFocusedStackOnly = false;
15310        String dumpPackage = null;
15311
15312        int opti = 0;
15313        while (opti < args.length) {
15314            String opt = args[opti];
15315            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15316                break;
15317            }
15318            opti++;
15319            if ("-a".equals(opt)) {
15320                dumpAll = true;
15321            } else if ("-c".equals(opt)) {
15322                dumpClient = true;
15323            } else if ("-v".equals(opt)) {
15324                dumpVisibleStacksOnly = true;
15325            } else if ("-f".equals(opt)) {
15326                dumpFocusedStackOnly = true;
15327            } else if ("-p".equals(opt)) {
15328                if (opti < args.length) {
15329                    dumpPackage = args[opti];
15330                    opti++;
15331                } else {
15332                    pw.println("Error: -p option requires package argument");
15333                    return;
15334                }
15335                dumpClient = true;
15336            } else if ("--checkin".equals(opt)) {
15337                dumpCheckin = dumpCheckinFormat = true;
15338            } else if ("-C".equals(opt)) {
15339                dumpCheckinFormat = true;
15340            } else if ("-h".equals(opt)) {
15341                ActivityManagerShellCommand.dumpHelp(pw, true);
15342                return;
15343            } else {
15344                pw.println("Unknown argument: " + opt + "; use -h for help");
15345            }
15346        }
15347
15348        long origId = Binder.clearCallingIdentity();
15349
15350        if (useProto) {
15351            final ProtoOutputStream proto = new ProtoOutputStream(fd);
15352            String cmd = opti < args.length ? args[opti] : "";
15353            opti++;
15354
15355            if ("activities".equals(cmd) || "a".equals(cmd)) {
15356                // output proto is ActivityStackSupervisorProto
15357                synchronized (this) {
15358                    writeActivitiesToProtoLocked(proto);
15359                }
15360            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15361                // output proto is BroadcastProto
15362                synchronized (this) {
15363                    writeBroadcastsToProtoLocked(proto);
15364                }
15365            } else if ("provider".equals(cmd)) {
15366                String[] newArgs;
15367                String name;
15368                if (opti >= args.length) {
15369                    name = null;
15370                    newArgs = EMPTY_STRING_ARRAY;
15371                } else {
15372                    name = args[opti];
15373                    opti++;
15374                    newArgs = new String[args.length - opti];
15375                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15376                            args.length - opti);
15377                }
15378                if (!dumpProviderProto(fd, pw, name, newArgs)) {
15379                    pw.println("No providers match: " + name);
15380                    pw.println("Use -h for help.");
15381                }
15382            } else if ("service".equals(cmd)) {
15383                mServices.writeToProto(proto);
15384            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15385                if (opti < args.length) {
15386                    dumpPackage = args[opti];
15387                    opti++;
15388                }
15389                // output proto is ProcessProto
15390                synchronized (this) {
15391                    writeProcessesToProtoLocked(proto, dumpPackage);
15392                }
15393            } else {
15394                // default option, dump everything, output is ActivityManagerServiceProto
15395                synchronized (this) {
15396                    long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
15397                    writeActivitiesToProtoLocked(proto);
15398                    proto.end(activityToken);
15399
15400                    long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
15401                    writeBroadcastsToProtoLocked(proto);
15402                    proto.end(broadcastToken);
15403
15404                    long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
15405                    mServices.writeToProto(proto);
15406                    proto.end(serviceToken);
15407
15408                    long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
15409                    writeProcessesToProtoLocked(proto, dumpPackage);
15410                    proto.end(processToken);
15411                }
15412            }
15413            proto.flush();
15414            Binder.restoreCallingIdentity(origId);
15415            return;
15416        }
15417
15418        int dumpAppId = getAppId(dumpPackage);
15419        boolean more = false;
15420        // Is the caller requesting to dump a particular piece of data?
15421        if (opti < args.length) {
15422            String cmd = args[opti];
15423            opti++;
15424            if ("activities".equals(cmd) || "a".equals(cmd)) {
15425                synchronized (this) {
15426                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15427                }
15428            } else if ("lastanr".equals(cmd)) {
15429                synchronized (this) {
15430                    dumpLastANRLocked(pw);
15431                }
15432            } else if ("starter".equals(cmd)) {
15433                synchronized (this) {
15434                    dumpActivityStarterLocked(pw, dumpPackage);
15435                }
15436            } else if ("containers".equals(cmd)) {
15437                synchronized (this) {
15438                    dumpActivityContainersLocked(pw);
15439                }
15440            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15441                synchronized (this) {
15442                    if (mRecentTasks != null) {
15443                        mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
15444                    }
15445                }
15446            } else if ("binder-proxies".equals(cmd)) {
15447                if (opti >= args.length) {
15448                    dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
15449                            "Counts of Binder Proxies held by SYSTEM");
15450                } else {
15451                    String uid = args[opti];
15452                    opti++;
15453                    // Ensure Binder Proxy Count is as up to date as possible
15454                    System.gc();
15455                    System.runFinalization();
15456                    System.gc();
15457                    pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
15458                }
15459            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15460                if (opti < args.length) {
15461                    dumpPackage = args[opti];
15462                    opti++;
15463                }
15464                synchronized (this) {
15465                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15466                }
15467            } else if ("broadcast-stats".equals(cmd)) {
15468                if (opti < args.length) {
15469                    dumpPackage = args[opti];
15470                    opti++;
15471                }
15472                synchronized (this) {
15473                    if (dumpCheckinFormat) {
15474                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15475                                dumpPackage);
15476                    } else {
15477                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15478                    }
15479                }
15480            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15481                if (opti < args.length) {
15482                    dumpPackage = args[opti];
15483                    opti++;
15484                }
15485                synchronized (this) {
15486                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15487                }
15488            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15489                if (opti < args.length) {
15490                    dumpPackage = args[opti];
15491                    opti++;
15492                }
15493                synchronized (this) {
15494                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
15495                }
15496            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15497                synchronized (this) {
15498                    dumpOomLocked(fd, pw, args, opti, true);
15499                }
15500            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15501                synchronized (this) {
15502                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15503                }
15504            } else if ("provider".equals(cmd)) {
15505                String[] newArgs;
15506                String name;
15507                if (opti >= args.length) {
15508                    name = null;
15509                    newArgs = EMPTY_STRING_ARRAY;
15510                } else {
15511                    name = args[opti];
15512                    opti++;
15513                    newArgs = new String[args.length - opti];
15514                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15515                }
15516                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15517                    pw.println("No providers match: " + name);
15518                    pw.println("Use -h for help.");
15519                }
15520            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15521                synchronized (this) {
15522                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15523                }
15524            } else if ("service".equals(cmd)) {
15525                String[] newArgs;
15526                String name;
15527                if (opti >= args.length) {
15528                    name = null;
15529                    newArgs = EMPTY_STRING_ARRAY;
15530                } else {
15531                    name = args[opti];
15532                    opti++;
15533                    newArgs = new String[args.length - opti];
15534                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15535                            args.length - opti);
15536                }
15537                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15538                    pw.println("No services match: " + name);
15539                    pw.println("Use -h for help.");
15540                }
15541            } else if ("package".equals(cmd)) {
15542                String[] newArgs;
15543                if (opti >= args.length) {
15544                    pw.println("package: no package name specified");
15545                    pw.println("Use -h for help.");
15546                } else {
15547                    dumpPackage = args[opti];
15548                    opti++;
15549                    newArgs = new String[args.length - opti];
15550                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15551                            args.length - opti);
15552                    args = newArgs;
15553                    opti = 0;
15554                    more = true;
15555                }
15556            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15557                synchronized (this) {
15558                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15559                }
15560            } else if ("settings".equals(cmd)) {
15561                synchronized (this) {
15562                    mConstants.dump(pw);
15563                }
15564            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15565                if (dumpClient) {
15566                    ActiveServices.ServiceDumper dumper;
15567                    synchronized (this) {
15568                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15569                                dumpPackage);
15570                    }
15571                    dumper.dumpWithClient();
15572                } else {
15573                    synchronized (this) {
15574                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15575                                dumpPackage).dumpLocked();
15576                    }
15577                }
15578            } else if ("locks".equals(cmd)) {
15579                LockGuard.dump(fd, pw, args);
15580            } else {
15581                // Dumping a single activity?
15582                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15583                        dumpFocusedStackOnly)) {
15584                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15585                    int res = shell.exec(this, null, fd, null, args, null,
15586                            new ResultReceiver(null));
15587                    if (res < 0) {
15588                        pw.println("Bad activity command, or no activities match: " + cmd);
15589                        pw.println("Use -h for help.");
15590                    }
15591                }
15592            }
15593            if (!more) {
15594                Binder.restoreCallingIdentity(origId);
15595                return;
15596            }
15597        }
15598
15599        // No piece of data specified, dump everything.
15600        if (dumpCheckinFormat) {
15601            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15602        } else if (dumpClient) {
15603            ActiveServices.ServiceDumper sdumper;
15604            synchronized (this) {
15605                mConstants.dump(pw);
15606                pw.println();
15607                if (dumpAll) {
15608                    pw.println("-------------------------------------------------------------------------------");
15609                }
15610                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15611                pw.println();
15612                if (dumpAll) {
15613                    pw.println("-------------------------------------------------------------------------------");
15614                }
15615                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15616                pw.println();
15617                if (dumpAll) {
15618                    pw.println("-------------------------------------------------------------------------------");
15619                }
15620                if (dumpAll || dumpPackage != null) {
15621                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15622                    pw.println();
15623                    if (dumpAll) {
15624                        pw.println("-------------------------------------------------------------------------------");
15625                    }
15626                }
15627                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15628                pw.println();
15629                if (dumpAll) {
15630                    pw.println("-------------------------------------------------------------------------------");
15631                }
15632                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15633                pw.println();
15634                if (dumpAll) {
15635                    pw.println("-------------------------------------------------------------------------------");
15636                }
15637                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15638                        dumpPackage);
15639            }
15640            sdumper.dumpWithClient();
15641            pw.println();
15642            synchronized (this) {
15643                if (dumpAll) {
15644                    pw.println("-------------------------------------------------------------------------------");
15645                }
15646                if (mRecentTasks != null) {
15647                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
15648                }
15649                pw.println();
15650                if (dumpAll) {
15651                    pw.println("-------------------------------------------------------------------------------");
15652                }
15653                dumpLastANRLocked(pw);
15654                pw.println();
15655                if (dumpAll) {
15656                    pw.println("-------------------------------------------------------------------------------");
15657                }
15658                dumpActivityStarterLocked(pw, dumpPackage);
15659                pw.println();
15660                if (dumpAll) {
15661                    pw.println("-------------------------------------------------------------------------------");
15662                }
15663                dumpActivityContainersLocked(pw);
15664                pw.println();
15665                if (dumpAll) {
15666                    pw.println("-------------------------------------------------------------------------------");
15667                }
15668                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15669                if (mAssociations.size() > 0) {
15670                    pw.println();
15671                    if (dumpAll) {
15672                        pw.println("-------------------------------------------------------------------------------");
15673                    }
15674                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15675                }
15676                pw.println();
15677                if (dumpAll) {
15678                    pw.println("-------------------------------------------------------------------------------");
15679                }
15680                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
15681            }
15682
15683        } else {
15684            synchronized (this) {
15685                mConstants.dump(pw);
15686                pw.println();
15687                if (dumpAll) {
15688                    pw.println("-------------------------------------------------------------------------------");
15689                }
15690                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15691                pw.println();
15692                if (dumpAll) {
15693                    pw.println("-------------------------------------------------------------------------------");
15694                }
15695                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15696                pw.println();
15697                if (dumpAll) {
15698                    pw.println("-------------------------------------------------------------------------------");
15699                }
15700                if (dumpAll || dumpPackage != null) {
15701                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15702                    pw.println();
15703                    if (dumpAll) {
15704                        pw.println("-------------------------------------------------------------------------------");
15705                    }
15706                }
15707                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15708                pw.println();
15709                if (dumpAll) {
15710                    pw.println("-------------------------------------------------------------------------------");
15711                }
15712                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15713                pw.println();
15714                if (dumpAll) {
15715                    pw.println("-------------------------------------------------------------------------------");
15716                }
15717                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15718                        .dumpLocked();
15719                pw.println();
15720                if (dumpAll) {
15721                    pw.println("-------------------------------------------------------------------------------");
15722                }
15723                if (mRecentTasks != null) {
15724                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
15725                }
15726                pw.println();
15727                if (dumpAll) {
15728                    pw.println("-------------------------------------------------------------------------------");
15729                }
15730                dumpLastANRLocked(pw);
15731                pw.println();
15732                if (dumpAll) {
15733                    pw.println("-------------------------------------------------------------------------------");
15734                }
15735                dumpActivityStarterLocked(pw, dumpPackage);
15736                pw.println();
15737                if (dumpAll) {
15738                    pw.println("-------------------------------------------------------------------------------");
15739                }
15740                dumpActivityContainersLocked(pw);
15741                pw.println();
15742                if (dumpAll) {
15743                    pw.println("-------------------------------------------------------------------------------");
15744                }
15745                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15746                if (mAssociations.size() > 0) {
15747                    pw.println();
15748                    if (dumpAll) {
15749                        pw.println("-------------------------------------------------------------------------------");
15750                    }
15751                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15752                }
15753                pw.println();
15754                if (dumpAll) {
15755                    pw.println("-------------------------------------------------------------------------------");
15756                }
15757                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
15758            }
15759        }
15760        Binder.restoreCallingIdentity(origId);
15761    }
15762
15763    private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
15764        // The output proto of "activity --proto activities" is ActivityStackSupervisorProto
15765        mStackSupervisor.writeToProto(proto);
15766    }
15767
15768    private void dumpLastANRLocked(PrintWriter pw) {
15769        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15770        if (mLastANRState == null) {
15771            pw.println("  <no ANR has occurred since boot>");
15772        } else {
15773            pw.println(mLastANRState);
15774        }
15775    }
15776
15777    private void dumpActivityContainersLocked(PrintWriter pw) {
15778        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
15779        mStackSupervisor.dumpChildrenNames(pw, " ");
15780        pw.println(" ");
15781    }
15782
15783    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15784        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15785        mActivityStartController.dump(pw, "", dumpPackage);
15786    }
15787
15788    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15789            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15790        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15791                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15792    }
15793
15794    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15795            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15796        pw.println(header);
15797
15798        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15799                dumpPackage);
15800        boolean needSep = printedAnything;
15801
15802        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15803                mStackSupervisor.getResumedActivityLocked(),
15804                dumpPackage, needSep, "  ResumedActivity: ");
15805        if (printed) {
15806            printedAnything = true;
15807            needSep = false;
15808        }
15809
15810        if (dumpPackage == null) {
15811            if (needSep) {
15812                pw.println();
15813            }
15814            printedAnything = true;
15815            mStackSupervisor.dump(pw, "  ");
15816        }
15817
15818        if (!printedAnything) {
15819            pw.println("  (nothing)");
15820        }
15821    }
15822
15823    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15824            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15825        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15826
15827        int dumpUid = 0;
15828        if (dumpPackage != null) {
15829            IPackageManager pm = AppGlobals.getPackageManager();
15830            try {
15831                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15832            } catch (RemoteException e) {
15833            }
15834        }
15835
15836        boolean printedAnything = false;
15837
15838        final long now = SystemClock.uptimeMillis();
15839
15840        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15841            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15842                    = mAssociations.valueAt(i1);
15843            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15844                SparseArray<ArrayMap<String, Association>> sourceUids
15845                        = targetComponents.valueAt(i2);
15846                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15847                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15848                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15849                        Association ass = sourceProcesses.valueAt(i4);
15850                        if (dumpPackage != null) {
15851                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15852                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15853                                continue;
15854                            }
15855                        }
15856                        printedAnything = true;
15857                        pw.print("  ");
15858                        pw.print(ass.mTargetProcess);
15859                        pw.print("/");
15860                        UserHandle.formatUid(pw, ass.mTargetUid);
15861                        pw.print(" <- ");
15862                        pw.print(ass.mSourceProcess);
15863                        pw.print("/");
15864                        UserHandle.formatUid(pw, ass.mSourceUid);
15865                        pw.println();
15866                        pw.print("    via ");
15867                        pw.print(ass.mTargetComponent.flattenToShortString());
15868                        pw.println();
15869                        pw.print("    ");
15870                        long dur = ass.mTime;
15871                        if (ass.mNesting > 0) {
15872                            dur += now - ass.mStartTime;
15873                        }
15874                        TimeUtils.formatDuration(dur, pw);
15875                        pw.print(" (");
15876                        pw.print(ass.mCount);
15877                        pw.print(" times)");
15878                        pw.print("  ");
15879                        for (int i=0; i<ass.mStateTimes.length; i++) {
15880                            long amt = ass.mStateTimes[i];
15881                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15882                                amt += now - ass.mLastStateUptime;
15883                            }
15884                            if (amt != 0) {
15885                                pw.print(" ");
15886                                pw.print(ProcessList.makeProcStateString(
15887                                            i + ActivityManager.MIN_PROCESS_STATE));
15888                                pw.print("=");
15889                                TimeUtils.formatDuration(amt, pw);
15890                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15891                                    pw.print("*");
15892                                }
15893                            }
15894                        }
15895                        pw.println();
15896                        if (ass.mNesting > 0) {
15897                            pw.print("    Currently active: ");
15898                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15899                            pw.println();
15900                        }
15901                    }
15902                }
15903            }
15904
15905        }
15906
15907        if (!printedAnything) {
15908            pw.println("  (nothing)");
15909        }
15910    }
15911
15912    private int getAppId(String dumpPackage) {
15913        if (dumpPackage != null) {
15914            try {
15915                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15916                        dumpPackage, 0);
15917                return UserHandle.getAppId(info.uid);
15918            } catch (NameNotFoundException e) {
15919                e.printStackTrace();
15920            }
15921        }
15922        return -1;
15923    }
15924
15925    boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
15926                String header, boolean needSep) {
15927        boolean printed = false;
15928        for (int i=0; i<uids.size(); i++) {
15929            UidRecord uidRec = uids.valueAt(i);
15930            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
15931                continue;
15932            }
15933            if (!printed) {
15934                printed = true;
15935                if (needSep) {
15936                    pw.println();
15937                }
15938                pw.print("  ");
15939                pw.println(header);
15940                needSep = true;
15941            }
15942            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15943            pw.print(": "); pw.println(uidRec);
15944        }
15945        return printed;
15946    }
15947
15948    boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
15949        if(counts != null) {
15950            pw.println(header);
15951            for (int i = 0; i < counts.size(); i++) {
15952                final int uid = counts.keyAt(i);
15953                final int binderCount = counts.valueAt(i);
15954                pw.print("    UID ");
15955                pw.print(uid);
15956                pw.print(", binder count = ");
15957                pw.print(binderCount);
15958                pw.print(", package(s)= ");
15959                final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
15960                if (pkgNames != null) {
15961                    for (int j = 0; j < pkgNames.length; j++) {
15962                        pw.print(pkgNames[j]);
15963                        pw.print("; ");
15964                    }
15965                } else {
15966                    pw.print("NO PACKAGE NAME FOUND");
15967                }
15968                pw.println();
15969            }
15970            pw.println();
15971            return true;
15972        }
15973        return false;
15974    }
15975
15976    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15977            int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
15978        boolean needSep = false;
15979        int numPers = 0;
15980
15981        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15982
15983        if (dumpAll) {
15984            final int NP = mProcessNames.getMap().size();
15985            for (int ip=0; ip<NP; ip++) {
15986                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15987                final int NA = procs.size();
15988                for (int ia=0; ia<NA; ia++) {
15989                    ProcessRecord r = procs.valueAt(ia);
15990                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15991                        continue;
15992                    }
15993                    if (!needSep) {
15994                        pw.println("  All known processes:");
15995                        needSep = true;
15996                    }
15997                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15998                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15999                        pw.print(" "); pw.println(r);
16000                    r.dump(pw, "    ");
16001                    if (r.persistent) {
16002                        numPers++;
16003                    }
16004                }
16005            }
16006        }
16007
16008        if (mIsolatedProcesses.size() > 0) {
16009            boolean printed = false;
16010            for (int i=0; i<mIsolatedProcesses.size(); i++) {
16011                ProcessRecord r = mIsolatedProcesses.valueAt(i);
16012                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16013                    continue;
16014                }
16015                if (!printed) {
16016                    if (needSep) {
16017                        pw.println();
16018                    }
16019                    pw.println("  Isolated process list (sorted by uid):");
16020                    printed = true;
16021                    needSep = true;
16022                }
16023                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
16024                pw.println(r);
16025            }
16026        }
16027
16028        if (mActiveInstrumentation.size() > 0) {
16029            boolean printed = false;
16030            for (int i=0; i<mActiveInstrumentation.size(); i++) {
16031                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16032                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16033                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16034                    continue;
16035                }
16036                if (!printed) {
16037                    if (needSep) {
16038                        pw.println();
16039                    }
16040                    pw.println("  Active instrumentation:");
16041                    printed = true;
16042                    needSep = true;
16043                }
16044                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
16045                pw.println(ai);
16046                ai.dump(pw, "      ");
16047            }
16048        }
16049
16050        if (mActiveUids.size() > 0) {
16051            if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16052                needSep = true;
16053            }
16054        }
16055        if (dumpAll) {
16056            if (mValidateUids.size() > 0) {
16057                if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16058                        needSep)) {
16059                    needSep = true;
16060                }
16061            }
16062        }
16063
16064        if (mLruProcesses.size() > 0) {
16065            if (needSep) {
16066                pw.println();
16067            }
16068            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16069                    pw.print(" total, non-act at ");
16070                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16071                    pw.print(", non-svc at ");
16072                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16073                    pw.println("):");
16074            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
16075            needSep = true;
16076        }
16077
16078        if (dumpAll || dumpPackage != null) {
16079            synchronized (mPidsSelfLocked) {
16080                boolean printed = false;
16081                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16082                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16083                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16084                        continue;
16085                    }
16086                    if (!printed) {
16087                        if (needSep) pw.println();
16088                        needSep = true;
16089                        pw.println("  PID mappings:");
16090                        printed = true;
16091                    }
16092                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16093                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16094                }
16095            }
16096        }
16097
16098        if (mImportantProcesses.size() > 0) {
16099            synchronized (mPidsSelfLocked) {
16100                boolean printed = false;
16101                for (int i = 0; i< mImportantProcesses.size(); i++) {
16102                    ProcessRecord r = mPidsSelfLocked.get(
16103                            mImportantProcesses.valueAt(i).pid);
16104                    if (dumpPackage != null && (r == null
16105                            || !r.pkgList.containsKey(dumpPackage))) {
16106                        continue;
16107                    }
16108                    if (!printed) {
16109                        if (needSep) pw.println();
16110                        needSep = true;
16111                        pw.println("  Foreground Processes:");
16112                        printed = true;
16113                    }
16114                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
16115                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16116                }
16117            }
16118        }
16119
16120        if (mPersistentStartingProcesses.size() > 0) {
16121            if (needSep) pw.println();
16122            needSep = true;
16123            pw.println("  Persisent processes that are starting:");
16124            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
16125                    "Starting Norm", "Restarting PERS", dumpPackage);
16126        }
16127
16128        if (mRemovedProcesses.size() > 0) {
16129            if (needSep) pw.println();
16130            needSep = true;
16131            pw.println("  Processes that are being removed:");
16132            dumpProcessList(pw, this, mRemovedProcesses, "    ",
16133                    "Removed Norm", "Removed PERS", dumpPackage);
16134        }
16135
16136        if (mProcessesOnHold.size() > 0) {
16137            if (needSep) pw.println();
16138            needSep = true;
16139            pw.println("  Processes that are on old until the system is ready:");
16140            dumpProcessList(pw, this, mProcessesOnHold, "    ",
16141                    "OnHold Norm", "OnHold PERS", dumpPackage);
16142        }
16143
16144        needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16145
16146        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16147
16148        if (dumpPackage == null) {
16149            pw.println();
16150            needSep = false;
16151            mUserController.dump(pw, dumpAll);
16152        }
16153        if (mHomeProcess != null && (dumpPackage == null
16154                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16155            if (needSep) {
16156                pw.println();
16157                needSep = false;
16158            }
16159            pw.println("  mHomeProcess: " + mHomeProcess);
16160        }
16161        if (mPreviousProcess != null && (dumpPackage == null
16162                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16163            if (needSep) {
16164                pw.println();
16165                needSep = false;
16166            }
16167            pw.println("  mPreviousProcess: " + mPreviousProcess);
16168        }
16169        if (dumpAll && (mPreviousProcess == null || dumpPackage == null
16170                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16171            StringBuilder sb = new StringBuilder(128);
16172            sb.append("  mPreviousProcessVisibleTime: ");
16173            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
16174            pw.println(sb);
16175        }
16176        if (mHeavyWeightProcess != null && (dumpPackage == null
16177                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16178            if (needSep) {
16179                pw.println();
16180                needSep = false;
16181            }
16182            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16183        }
16184        if (dumpAll && mPendingStarts.size() > 0) {
16185            if (needSep) pw.println();
16186            needSep = true;
16187            pw.println("  mPendingStarts: ");
16188            for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
16189                pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
16190            }
16191        }
16192        if (dumpPackage == null) {
16193            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
16194            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
16195        }
16196        if (dumpAll) {
16197            if (dumpPackage == null) {
16198                pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
16199            }
16200            if (mCompatModePackages.getPackages().size() > 0) {
16201                boolean printed = false;
16202                for (Map.Entry<String, Integer> entry
16203                        : mCompatModePackages.getPackages().entrySet()) {
16204                    String pkg = entry.getKey();
16205                    int mode = entry.getValue();
16206                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
16207                        continue;
16208                    }
16209                    if (!printed) {
16210                        pw.println("  mScreenCompatPackages:");
16211                        printed = true;
16212                    }
16213                    pw.print("    "); pw.print(pkg); pw.print(": ");
16214                            pw.print(mode); pw.println();
16215                }
16216            }
16217            final int NI = mUidObservers.getRegisteredCallbackCount();
16218            boolean printed = false;
16219            for (int i=0; i<NI; i++) {
16220                final UidObserverRegistration reg = (UidObserverRegistration)
16221                        mUidObservers.getRegisteredCallbackCookie(i);
16222                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16223                    if (!printed) {
16224                        pw.println("  mUidObservers:");
16225                        printed = true;
16226                    }
16227                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
16228                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
16229                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
16230                        pw.print(" IDLE");
16231                    }
16232                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
16233                        pw.print(" ACT" );
16234                    }
16235                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
16236                        pw.print(" GONE");
16237                    }
16238                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
16239                        pw.print(" STATE");
16240                        pw.print(" (cut="); pw.print(reg.cutpoint);
16241                        pw.print(")");
16242                    }
16243                    pw.println();
16244                    if (reg.lastProcStates != null) {
16245                        final int NJ = reg.lastProcStates.size();
16246                        for (int j=0; j<NJ; j++) {
16247                            pw.print("      Last ");
16248                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
16249                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
16250                        }
16251                    }
16252                }
16253            }
16254            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
16255            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
16256            if (mPendingTempWhitelist.size() > 0) {
16257                pw.println("  mPendingTempWhitelist:");
16258                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
16259                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
16260                    pw.print("    ");
16261                    UserHandle.formatUid(pw, ptw.targetUid);
16262                    pw.print(": ");
16263                    TimeUtils.formatDuration(ptw.duration, pw);
16264                    pw.print(" ");
16265                    pw.println(ptw.tag);
16266                }
16267            }
16268        }
16269        if (dumpPackage == null) {
16270            pw.println("  mWakefulness="
16271                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
16272            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
16273            pw.println("  mSleeping=" + mSleeping);
16274            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
16275            if (mRunningVoice != null) {
16276                pw.println("  mRunningVoice=" + mRunningVoice);
16277                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
16278            }
16279            pw.println("  mVrController=" + mVrController);
16280        }
16281        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16282                || mOrigWaitForDebugger) {
16283            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16284                    || dumpPackage.equals(mOrigDebugApp)) {
16285                if (needSep) {
16286                    pw.println();
16287                    needSep = false;
16288                }
16289                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
16290                        + " mDebugTransient=" + mDebugTransient
16291                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
16292            }
16293        }
16294        if (mCurAppTimeTracker != null) {
16295            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
16296        }
16297        if (mMemWatchProcesses.getMap().size() > 0) {
16298            pw.println("  Mem watch processes:");
16299            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
16300                    = mMemWatchProcesses.getMap();
16301            for (int i=0; i<procs.size(); i++) {
16302                final String proc = procs.keyAt(i);
16303                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16304                for (int j=0; j<uids.size(); j++) {
16305                    if (needSep) {
16306                        pw.println();
16307                        needSep = false;
16308                    }
16309                    StringBuilder sb = new StringBuilder();
16310                    sb.append("    ").append(proc).append('/');
16311                    UserHandle.formatUid(sb, uids.keyAt(j));
16312                    Pair<Long, String> val = uids.valueAt(j);
16313                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
16314                    if (val.second != null) {
16315                        sb.append(", report to ").append(val.second);
16316                    }
16317                    pw.println(sb.toString());
16318                }
16319            }
16320            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
16321            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
16322            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
16323                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
16324        }
16325        if (mTrackAllocationApp != null) {
16326            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16327                if (needSep) {
16328                    pw.println();
16329                    needSep = false;
16330                }
16331                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
16332            }
16333        }
16334        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16335                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16336            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16337                if (needSep) {
16338                    pw.println();
16339                    needSep = false;
16340                }
16341                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16342                if (mProfilerInfo != null) {
16343                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16344                            mProfilerInfo.profileFd);
16345                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16346                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16347                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16348                    pw.println("  mProfileType=" + mProfileType);
16349                }
16350            }
16351        }
16352        if (mNativeDebuggingApp != null) {
16353            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16354                if (needSep) {
16355                    pw.println();
16356                    needSep = false;
16357                }
16358                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16359            }
16360        }
16361        if (mAllowAppSwitchUids.size() > 0) {
16362            boolean printed = false;
16363            for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
16364                ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
16365                for (int j = 0; j < types.size(); j++) {
16366                    if (dumpPackage == null ||
16367                            UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
16368                        if (needSep) {
16369                            pw.println();
16370                            needSep = false;
16371                        }
16372                        if (!printed) {
16373                            pw.println("  mAllowAppSwitchUids:");
16374                            printed = true;
16375                        }
16376                        pw.print("    User ");
16377                        pw.print(mAllowAppSwitchUids.keyAt(i));
16378                        pw.print(": Type ");
16379                        pw.print(types.keyAt(j));
16380                        pw.print(" = ");
16381                        UserHandle.formatUid(pw, types.valueAt(j).intValue());
16382                        pw.println();
16383                    }
16384                }
16385            }
16386        }
16387        if (dumpPackage == null) {
16388            if (mAlwaysFinishActivities) {
16389                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16390            }
16391            if (mController != null) {
16392                pw.println("  mController=" + mController
16393                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16394            }
16395            if (dumpAll) {
16396                pw.println("  Total persistent processes: " + numPers);
16397                pw.println("  mProcessesReady=" + mProcessesReady
16398                        + " mSystemReady=" + mSystemReady
16399                        + " mBooted=" + mBooted
16400                        + " mFactoryTest=" + mFactoryTest);
16401                pw.println("  mBooting=" + mBooting
16402                        + " mCallFinishBooting=" + mCallFinishBooting
16403                        + " mBootAnimationComplete=" + mBootAnimationComplete);
16404                pw.print("  mLastPowerCheckUptime=");
16405                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16406                        pw.println("");
16407                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16408                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16409                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16410                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16411                        + " (" + mLruProcesses.size() + " total)"
16412                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16413                        + " mNumServiceProcs=" + mNumServiceProcs
16414                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16415                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16416                        + " mLastMemoryLevel=" + mLastMemoryLevel
16417                        + " mLastNumProcesses=" + mLastNumProcesses);
16418                long now = SystemClock.uptimeMillis();
16419                pw.print("  mLastIdleTime=");
16420                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
16421                        pw.print(" mLowRamSinceLastIdle=");
16422                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16423                        pw.println();
16424            }
16425        }
16426        pw.println("  mForceBackgroundCheck=" + mForceBackgroundCheck);
16427    }
16428
16429    void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
16430        int numPers = 0;
16431
16432        final int NP = mProcessNames.getMap().size();
16433        for (int ip=0; ip<NP; ip++) {
16434            SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16435            final int NA = procs.size();
16436            for (int ia = 0; ia<NA; ia++) {
16437                ProcessRecord r = procs.valueAt(ia);
16438                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16439                    continue;
16440                }
16441                r.writeToProto(proto, ProcessesProto.PROCS);
16442                if (r.persistent) {
16443                    numPers++;
16444                }
16445            }
16446        }
16447
16448        for (int i=0; i<mIsolatedProcesses.size(); i++) {
16449            ProcessRecord r = mIsolatedProcesses.valueAt(i);
16450            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16451                continue;
16452            }
16453            r.writeToProto(proto, ProcessesProto.ISOLATED_PROCS);
16454        }
16455
16456        for (int i=0; i<mActiveInstrumentation.size(); i++) {
16457            ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16458            if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16459                    && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16460                continue;
16461            }
16462            ai.writeToProto(proto, ProcessesProto.ACTIVE_INSTRUMENTATIONS);
16463        }
16464
16465        int whichAppId = getAppId(dumpPackage);
16466        for (int i=0; i<mActiveUids.size(); i++) {
16467            UidRecord uidRec = mActiveUids.valueAt(i);
16468            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16469                continue;
16470            }
16471            uidRec.writeToProto(proto, ProcessesProto.ACTIVE_UIDS);
16472        }
16473
16474        for (int i=0; i<mValidateUids.size(); i++) {
16475            UidRecord uidRec = mValidateUids.valueAt(i);
16476            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16477                continue;
16478            }
16479            uidRec.writeToProto(proto, ProcessesProto.VALIDATE_UIDS);
16480        }
16481
16482        if (mLruProcesses.size() > 0) {
16483            long lruToken = proto.start(ProcessesProto.LRU_PROCS);
16484            int total = mLruProcesses.size();
16485            proto.write(ProcessesProto.LruProcesses.SIZE, total);
16486            proto.write(ProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
16487            proto.write(ProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
16488            writeProcessOomListToProto(proto, ProcessesProto.LruProcesses.LIST, this,
16489                    mLruProcesses,false, dumpPackage);
16490            proto.end(lruToken);
16491        }
16492
16493        if (dumpPackage != null) {
16494            synchronized (mPidsSelfLocked) {
16495                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16496                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16497                    if (!r.pkgList.containsKey(dumpPackage)) {
16498                        continue;
16499                    }
16500                    r.writeToProto(proto, ProcessesProto.PIDS_SELF_LOCKED);
16501                }
16502            }
16503        }
16504
16505        if (mImportantProcesses.size() > 0) {
16506            synchronized (mPidsSelfLocked) {
16507                for (int i=0; i<mImportantProcesses.size(); i++) {
16508                    ImportanceToken it = mImportantProcesses.valueAt(i);
16509                    ProcessRecord r = mPidsSelfLocked.get(it.pid);
16510                    if (dumpPackage != null && (r == null
16511                            || !r.pkgList.containsKey(dumpPackage))) {
16512                        continue;
16513                    }
16514                    it.writeToProto(proto, ProcessesProto.IMPORTANT_PROCS);
16515                }
16516            }
16517        }
16518
16519        for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
16520            ProcessRecord r = mPersistentStartingProcesses.get(i);
16521            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16522                continue;
16523            }
16524            r.writeToProto(proto, ProcessesProto.PERSISTENT_STARTING_PROCS);
16525        }
16526
16527        for (int i=0; i<mRemovedProcesses.size(); i++) {
16528            ProcessRecord r = mRemovedProcesses.get(i);
16529            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16530                continue;
16531            }
16532            r.writeToProto(proto, ProcessesProto.REMOVED_PROCS);
16533        }
16534
16535        for (int i=0; i<mProcessesOnHold.size(); i++) {
16536            ProcessRecord r = mProcessesOnHold.get(i);
16537            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16538                continue;
16539            }
16540            r.writeToProto(proto, ProcessesProto.ON_HOLD_PROCS);
16541        }
16542
16543        writeProcessesToGcToProto(proto, ProcessesProto.GC_PROCS, dumpPackage);
16544        mAppErrors.writeToProto(proto, ProcessesProto.APP_ERRORS, dumpPackage);
16545
16546        if (dumpPackage == null) {
16547            mUserController.writeToProto(proto, ProcessesProto.USER_CONTROLLER);
16548            getGlobalConfiguration().writeToProto(proto, ProcessesProto.GLOBAL_CONFIGURATION);
16549            proto.write(ProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
16550        }
16551
16552        if (mHomeProcess != null && (dumpPackage == null
16553                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16554            mHomeProcess.writeToProto(proto, ProcessesProto.HOME_PROC);
16555        }
16556
16557        if (mPreviousProcess != null && (dumpPackage == null
16558                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16559            mPreviousProcess.writeToProto(proto, ProcessesProto.PREVIOUS_PROC);
16560            proto.write(ProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
16561        }
16562
16563        if (mHeavyWeightProcess != null && (dumpPackage == null
16564                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16565            mHeavyWeightProcess.writeToProto(proto, ProcessesProto.HEAVY_WEIGHT_PROC);
16566        }
16567
16568        for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
16569            String pkg = entry.getKey();
16570            int mode = entry.getValue();
16571            if (dumpPackage == null || dumpPackage.equals(pkg)) {
16572                long compatToken = proto.start(ProcessesProto.SCREEN_COMPAT_PACKAGES);
16573                proto.write(ProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
16574                proto.write(ProcessesProto.ScreenCompatPackage.MODE, mode);
16575                proto.end(compatToken);
16576            }
16577        }
16578
16579        final int NI = mUidObservers.getRegisteredCallbackCount();
16580        for (int i=0; i<NI; i++) {
16581            final UidObserverRegistration reg = (UidObserverRegistration)
16582                    mUidObservers.getRegisteredCallbackCookie(i);
16583            if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16584                reg.writeToProto(proto, ProcessesProto.UID_OBSERVERS);
16585            }
16586        }
16587
16588        for (int v : mDeviceIdleWhitelist) {
16589            proto.write(ProcessesProto.DEVICE_IDLE_WHITELIST, v);
16590        }
16591
16592        for (int v : mDeviceIdleTempWhitelist) {
16593            proto.write(ProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
16594        }
16595
16596        if (mPendingTempWhitelist.size() > 0) {
16597            for (int i=0; i < mPendingTempWhitelist.size(); i++) {
16598                mPendingTempWhitelist.valueAt(i).writeToProto(proto,
16599                        ProcessesProto.PENDING_TEMP_WHITELIST);
16600            }
16601        }
16602
16603        if (dumpPackage == null) {
16604            final long sleepToken = proto.start(ProcessesProto.SLEEP_STATUS);
16605            proto.write(ProcessesProto.SleepStatus.WAKEFULNESS,
16606                    PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
16607            for (SleepToken st : mStackSupervisor.mSleepTokens) {
16608                proto.write(ProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
16609            }
16610            proto.write(ProcessesProto.SleepStatus.SLEEPING, mSleeping);
16611            proto.write(ProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
16612            proto.write(ProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
16613            proto.end(sleepToken);
16614
16615            if (mRunningVoice != null) {
16616                final long vrToken = proto.start(ProcessesProto.RUNNING_VOICE);
16617                proto.write(ProcessesProto.VoiceProto.SESSION, mRunningVoice.toString());
16618                mVoiceWakeLock.writeToProto(proto, ProcessesProto.VoiceProto.WAKELOCK);
16619                proto.end(vrToken);
16620            }
16621
16622            mVrController.writeToProto(proto, ProcessesProto.VR_CONTROLLER);
16623        }
16624
16625        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16626                || mOrigWaitForDebugger) {
16627            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16628                    || dumpPackage.equals(mOrigDebugApp)) {
16629                final long debugAppToken = proto.start(ProcessesProto.DEBUG);
16630                proto.write(ProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
16631                proto.write(ProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
16632                proto.write(ProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
16633                proto.write(ProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
16634                proto.end(debugAppToken);
16635            }
16636        }
16637
16638        if (mCurAppTimeTracker != null) {
16639            mCurAppTimeTracker.writeToProto(proto, ProcessesProto.CURRENT_TRACKER, true);
16640        }
16641
16642        if (mMemWatchProcesses.getMap().size() > 0) {
16643            final long token = proto.start(ProcessesProto.MEM_WATCH_PROCESSES);
16644            ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
16645            for (int i=0; i<procs.size(); i++) {
16646                final String proc = procs.keyAt(i);
16647                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16648                final long ptoken = proto.start(ProcessesProto.MemWatchProcess.PROCS);
16649                proto.write(ProcessesProto.MemWatchProcess.Process.NAME, proc);
16650                for (int j=0; j<uids.size(); j++) {
16651                    final long utoken = proto.start(ProcessesProto.MemWatchProcess.Process.MEM_STATS);
16652                    Pair<Long, String> val = uids.valueAt(j);
16653                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
16654                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
16655                            DebugUtils.sizeValueToString(val.first, new StringBuilder()));
16656                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
16657                    proto.end(utoken);
16658                }
16659                proto.end(ptoken);
16660            }
16661
16662            final long dtoken = proto.start(ProcessesProto.MemWatchProcess.DUMP);
16663            proto.write(ProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
16664            proto.write(ProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
16665            proto.write(ProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
16666            proto.write(ProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
16667            proto.end(dtoken);
16668
16669            proto.end(token);
16670        }
16671
16672        if (mTrackAllocationApp != null) {
16673            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16674                proto.write(ProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
16675            }
16676        }
16677
16678        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16679                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16680            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16681                final long token = proto.start(ProcessesProto.PROFILE);
16682                proto.write(ProcessesProto.Profile.APP_NAME, mProfileApp);
16683                mProfileProc.writeToProto(proto,ProcessesProto.Profile.PROC);
16684                if (mProfilerInfo != null) {
16685                    mProfilerInfo.writeToProto(proto, ProcessesProto.Profile.INFO);
16686                    proto.write(ProcessesProto.Profile.TYPE, mProfileType);
16687                }
16688                proto.end(token);
16689            }
16690        }
16691
16692        if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16693            proto.write(ProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
16694        }
16695
16696        if (dumpPackage == null) {
16697            proto.write(ProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
16698            if (mController != null) {
16699                final long token = proto.start(ProcessesProto.CONTROLLER);
16700                proto.write(ProcessesProto.Controller.CONTROLLER, mController.toString());
16701                proto.write(ProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
16702                proto.end(token);
16703            }
16704            proto.write(ProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
16705            proto.write(ProcessesProto.PROCESSES_READY, mProcessesReady);
16706            proto.write(ProcessesProto.SYSTEM_READY, mSystemReady);
16707            proto.write(ProcessesProto.BOOTED, mBooted);
16708            proto.write(ProcessesProto.FACTORY_TEST, mFactoryTest);
16709            proto.write(ProcessesProto.BOOTING, mBooting);
16710            proto.write(ProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
16711            proto.write(ProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
16712            proto.write(ProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
16713            mStackSupervisor.mGoingToSleep.writeToProto(proto, ProcessesProto.GOING_TO_SLEEP);
16714            mStackSupervisor.mLaunchingActivity.writeToProto(proto, ProcessesProto.LAUNCHING_ACTIVITY);
16715            proto.write(ProcessesProto.ADJ_SEQ, mAdjSeq);
16716            proto.write(ProcessesProto.LRU_SEQ, mLruSeq);
16717            proto.write(ProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
16718            proto.write(ProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
16719            proto.write(ProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
16720            proto.write(ProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
16721            proto.write(ProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
16722            proto.write(ProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
16723            long now = SystemClock.uptimeMillis();
16724            ProtoUtils.toDuration(proto, ProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
16725            proto.write(ProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
16726        }
16727
16728    }
16729
16730    void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
16731        if (mProcessesToGc.size() > 0) {
16732            long now = SystemClock.uptimeMillis();
16733            for (int i=0; i<mProcessesToGc.size(); i++) {
16734                ProcessRecord r = mProcessesToGc.get(i);
16735                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16736                    continue;
16737                }
16738                final long token = proto.start(fieldId);
16739                r.writeToProto(proto, ProcessToGcProto.PROC);
16740                proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
16741                proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
16742                proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
16743                proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
16744                proto.end(token);
16745            }
16746        }
16747    }
16748
16749    boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
16750        if (mProcessesToGc.size() > 0) {
16751            boolean printed = false;
16752            long now = SystemClock.uptimeMillis();
16753            for (int i=0; i<mProcessesToGc.size(); i++) {
16754                ProcessRecord proc = mProcessesToGc.get(i);
16755                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16756                    continue;
16757                }
16758                if (!printed) {
16759                    if (needSep) pw.println();
16760                    needSep = true;
16761                    pw.println("  Processes that are waiting to GC:");
16762                    printed = true;
16763                }
16764                pw.print("    Process "); pw.println(proc);
16765                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16766                        pw.print(", last gced=");
16767                        pw.print(now-proc.lastRequestedGc);
16768                        pw.print(" ms ago, last lowMem=");
16769                        pw.print(now-proc.lastLowMemory);
16770                        pw.println(" ms ago");
16771
16772            }
16773        }
16774        return needSep;
16775    }
16776
16777    void printOomLevel(PrintWriter pw, String name, int adj) {
16778        pw.print("    ");
16779        if (adj >= 0) {
16780            pw.print(' ');
16781            if (adj < 10) pw.print(' ');
16782        } else {
16783            if (adj > -10) pw.print(' ');
16784        }
16785        pw.print(adj);
16786        pw.print(": ");
16787        pw.print(name);
16788        pw.print(" (");
16789        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16790        pw.println(")");
16791    }
16792
16793    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16794            int opti, boolean dumpAll) {
16795        boolean needSep = false;
16796
16797        if (mLruProcesses.size() > 0) {
16798            if (needSep) pw.println();
16799            needSep = true;
16800            pw.println("  OOM levels:");
16801            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16802            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16803            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16804            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16805            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16806            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16807            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16808            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16809            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16810            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16811            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16812            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16813            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16814            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16815
16816            if (needSep) pw.println();
16817            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16818                    pw.print(" total, non-act at ");
16819                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16820                    pw.print(", non-svc at ");
16821                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16822                    pw.println("):");
16823            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16824            needSep = true;
16825        }
16826
16827        dumpProcessesToGc(pw, needSep, null);
16828
16829        pw.println();
16830        pw.println("  mHomeProcess: " + mHomeProcess);
16831        pw.println("  mPreviousProcess: " + mPreviousProcess);
16832        if (mHeavyWeightProcess != null) {
16833            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16834        }
16835
16836        return true;
16837    }
16838
16839    /**
16840     * There are three ways to call this:
16841     *  - no provider specified: dump all the providers
16842     *  - a flattened component name that matched an existing provider was specified as the
16843     *    first arg: dump that one provider
16844     *  - the first arg isn't the flattened component name of an existing provider:
16845     *    dump all providers whose component contains the first arg as a substring
16846     */
16847    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16848            int opti, boolean dumpAll) {
16849        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16850    }
16851
16852    /**
16853     * Similar to the dumpProvider, but only dumps the first matching provider.
16854     * The provider is responsible for dumping as proto.
16855     */
16856    protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
16857            String[] args) {
16858        return mProviderMap.dumpProviderProto(fd, pw, name, args);
16859    }
16860
16861    static class ItemMatcher {
16862        ArrayList<ComponentName> components;
16863        ArrayList<String> strings;
16864        ArrayList<Integer> objects;
16865        boolean all;
16866
16867        ItemMatcher() {
16868            all = true;
16869        }
16870
16871        void build(String name) {
16872            ComponentName componentName = ComponentName.unflattenFromString(name);
16873            if (componentName != null) {
16874                if (components == null) {
16875                    components = new ArrayList<ComponentName>();
16876                }
16877                components.add(componentName);
16878                all = false;
16879            } else {
16880                int objectId = 0;
16881                // Not a '/' separated full component name; maybe an object ID?
16882                try {
16883                    objectId = Integer.parseInt(name, 16);
16884                    if (objects == null) {
16885                        objects = new ArrayList<Integer>();
16886                    }
16887                    objects.add(objectId);
16888                    all = false;
16889                } catch (RuntimeException e) {
16890                    // Not an integer; just do string match.
16891                    if (strings == null) {
16892                        strings = new ArrayList<String>();
16893                    }
16894                    strings.add(name);
16895                    all = false;
16896                }
16897            }
16898        }
16899
16900        int build(String[] args, int opti) {
16901            for (; opti<args.length; opti++) {
16902                String name = args[opti];
16903                if ("--".equals(name)) {
16904                    return opti+1;
16905                }
16906                build(name);
16907            }
16908            return opti;
16909        }
16910
16911        boolean match(Object object, ComponentName comp) {
16912            if (all) {
16913                return true;
16914            }
16915            if (components != null) {
16916                for (int i=0; i<components.size(); i++) {
16917                    if (components.get(i).equals(comp)) {
16918                        return true;
16919                    }
16920                }
16921            }
16922            if (objects != null) {
16923                for (int i=0; i<objects.size(); i++) {
16924                    if (System.identityHashCode(object) == objects.get(i)) {
16925                        return true;
16926                    }
16927                }
16928            }
16929            if (strings != null) {
16930                String flat = comp.flattenToString();
16931                for (int i=0; i<strings.size(); i++) {
16932                    if (flat.contains(strings.get(i))) {
16933                        return true;
16934                    }
16935                }
16936            }
16937            return false;
16938        }
16939    }
16940
16941    /**
16942     * There are three things that cmd can be:
16943     *  - a flattened component name that matches an existing activity
16944     *  - the cmd arg isn't the flattened component name of an existing activity:
16945     *    dump all activity whose component contains the cmd as a substring
16946     *  - A hex number of the ActivityRecord object instance.
16947     *
16948     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16949     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16950     */
16951    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16952            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16953        ArrayList<ActivityRecord> activities;
16954
16955        synchronized (this) {
16956            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16957                    dumpFocusedStackOnly);
16958        }
16959
16960        if (activities.size() <= 0) {
16961            return false;
16962        }
16963
16964        String[] newArgs = new String[args.length - opti];
16965        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16966
16967        TaskRecord lastTask = null;
16968        boolean needSep = false;
16969        for (int i=activities.size()-1; i>=0; i--) {
16970            ActivityRecord r = activities.get(i);
16971            if (needSep) {
16972                pw.println();
16973            }
16974            needSep = true;
16975            synchronized (this) {
16976                final TaskRecord task = r.getTask();
16977                if (lastTask != task) {
16978                    lastTask = task;
16979                    pw.print("TASK "); pw.print(lastTask.affinity);
16980                            pw.print(" id="); pw.print(lastTask.taskId);
16981                            pw.print(" userId="); pw.println(lastTask.userId);
16982                    if (dumpAll) {
16983                        lastTask.dump(pw, "  ");
16984                    }
16985                }
16986            }
16987            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16988        }
16989        return true;
16990    }
16991
16992    /**
16993     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16994     * there is a thread associated with the activity.
16995     */
16996    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16997            final ActivityRecord r, String[] args, boolean dumpAll) {
16998        String innerPrefix = prefix + "  ";
16999        synchronized (this) {
17000            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
17001                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
17002                    pw.print(" pid=");
17003                    if (r.app != null) pw.println(r.app.pid);
17004                    else pw.println("(not running)");
17005            if (dumpAll) {
17006                r.dump(pw, innerPrefix);
17007            }
17008        }
17009        if (r.app != null && r.app.thread != null) {
17010            // flush anything that is already in the PrintWriter since the thread is going
17011            // to write to the file descriptor directly
17012            pw.flush();
17013            try {
17014                TransferPipe tp = new TransferPipe();
17015                try {
17016                    r.app.thread.dumpActivity(tp.getWriteFd(),
17017                            r.appToken, innerPrefix, args);
17018                    tp.go(fd);
17019                } finally {
17020                    tp.kill();
17021                }
17022            } catch (IOException e) {
17023                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
17024            } catch (RemoteException e) {
17025                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
17026            }
17027        }
17028    }
17029
17030    void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
17031        if (mRegisteredReceivers.size() > 0) {
17032            Iterator it = mRegisteredReceivers.values().iterator();
17033            while (it.hasNext()) {
17034                ReceiverList r = (ReceiverList)it.next();
17035                r.writeToProto(proto, BroadcastProto.RECEIVER_LIST);
17036            }
17037        }
17038        mReceiverResolver.writeToProto(proto, BroadcastProto.RECEIVER_RESOLVER);
17039        for (BroadcastQueue q : mBroadcastQueues) {
17040            q.writeToProto(proto, BroadcastProto.BROADCAST_QUEUE);
17041        }
17042        for (int user=0; user<mStickyBroadcasts.size(); user++) {
17043            long token = proto.start(BroadcastProto.STICKY_BROADCASTS);
17044            proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
17045            for (Map.Entry<String, ArrayList<Intent>> ent
17046                    : mStickyBroadcasts.valueAt(user).entrySet()) {
17047                long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
17048                proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
17049                for (Intent intent : ent.getValue()) {
17050                    intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
17051                            false, true, true, false);
17052                }
17053                proto.end(actionToken);
17054            }
17055            proto.end(token);
17056        }
17057
17058        long handlerToken = proto.start(BroadcastProto.HANDLER);
17059        proto.write(BroadcastProto.MainHandler.HANDLER, mHandler.toString());
17060        mHandler.getLooper().writeToProto(proto, BroadcastProto.MainHandler.LOOPER);
17061        proto.end(handlerToken);
17062    }
17063
17064    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17065            int opti, boolean dumpAll, String dumpPackage) {
17066        boolean needSep = false;
17067        boolean onlyHistory = false;
17068        boolean printedAnything = false;
17069
17070        if ("history".equals(dumpPackage)) {
17071            if (opti < args.length && "-s".equals(args[opti])) {
17072                dumpAll = false;
17073            }
17074            onlyHistory = true;
17075            dumpPackage = null;
17076        }
17077
17078        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
17079        if (!onlyHistory && dumpAll) {
17080            if (mRegisteredReceivers.size() > 0) {
17081                boolean printed = false;
17082                Iterator it = mRegisteredReceivers.values().iterator();
17083                while (it.hasNext()) {
17084                    ReceiverList r = (ReceiverList)it.next();
17085                    if (dumpPackage != null && (r.app == null ||
17086                            !dumpPackage.equals(r.app.info.packageName))) {
17087                        continue;
17088                    }
17089                    if (!printed) {
17090                        pw.println("  Registered Receivers:");
17091                        needSep = true;
17092                        printed = true;
17093                        printedAnything = true;
17094                    }
17095                    pw.print("  * "); pw.println(r);
17096                    r.dump(pw, "    ");
17097                }
17098            }
17099
17100            if (mReceiverResolver.dump(pw, needSep ?
17101                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
17102                    "    ", dumpPackage, false, false)) {
17103                needSep = true;
17104                printedAnything = true;
17105            }
17106        }
17107
17108        for (BroadcastQueue q : mBroadcastQueues) {
17109            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17110            printedAnything |= needSep;
17111        }
17112
17113        needSep = true;
17114
17115        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17116            for (int user=0; user<mStickyBroadcasts.size(); user++) {
17117                if (needSep) {
17118                    pw.println();
17119                }
17120                needSep = true;
17121                printedAnything = true;
17122                pw.print("  Sticky broadcasts for user ");
17123                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
17124                StringBuilder sb = new StringBuilder(128);
17125                for (Map.Entry<String, ArrayList<Intent>> ent
17126                        : mStickyBroadcasts.valueAt(user).entrySet()) {
17127                    pw.print("  * Sticky action "); pw.print(ent.getKey());
17128                    if (dumpAll) {
17129                        pw.println(":");
17130                        ArrayList<Intent> intents = ent.getValue();
17131                        final int N = intents.size();
17132                        for (int i=0; i<N; i++) {
17133                            sb.setLength(0);
17134                            sb.append("    Intent: ");
17135                            intents.get(i).toShortString(sb, false, true, false, false);
17136                            pw.println(sb.toString());
17137                            Bundle bundle = intents.get(i).getExtras();
17138                            if (bundle != null) {
17139                                pw.print("      ");
17140                                pw.println(bundle.toString());
17141                            }
17142                        }
17143                    } else {
17144                        pw.println("");
17145                    }
17146                }
17147            }
17148        }
17149
17150        if (!onlyHistory && dumpAll) {
17151            pw.println();
17152            for (BroadcastQueue queue : mBroadcastQueues) {
17153                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
17154                        + queue.mBroadcastsScheduled);
17155            }
17156            pw.println("  mHandler:");
17157            mHandler.dump(new PrintWriterPrinter(pw), "    ");
17158            needSep = true;
17159            printedAnything = true;
17160        }
17161
17162        if (!printedAnything) {
17163            pw.println("  (nothing)");
17164        }
17165    }
17166
17167    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17168            int opti, boolean dumpAll, String dumpPackage) {
17169        if (mCurBroadcastStats == null) {
17170            return;
17171        }
17172
17173        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
17174        final long now = SystemClock.elapsedRealtime();
17175        if (mLastBroadcastStats != null) {
17176            pw.print("  Last stats (from ");
17177            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
17178            pw.print(" to ");
17179            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
17180            pw.print(", ");
17181            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
17182                    - mLastBroadcastStats.mStartUptime, pw);
17183            pw.println(" uptime):");
17184            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17185                pw.println("    (nothing)");
17186            }
17187            pw.println();
17188        }
17189        pw.print("  Current stats (from ");
17190        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
17191        pw.print(" to now, ");
17192        TimeUtils.formatDuration(SystemClock.uptimeMillis()
17193                - mCurBroadcastStats.mStartUptime, pw);
17194        pw.println(" uptime):");
17195        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17196            pw.println("    (nothing)");
17197        }
17198    }
17199
17200    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17201            int opti, boolean fullCheckin, String dumpPackage) {
17202        if (mCurBroadcastStats == null) {
17203            return;
17204        }
17205
17206        if (mLastBroadcastStats != null) {
17207            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17208            if (fullCheckin) {
17209                mLastBroadcastStats = null;
17210                return;
17211            }
17212        }
17213        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17214        if (fullCheckin) {
17215            mCurBroadcastStats = null;
17216        }
17217    }
17218
17219    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17220            int opti, boolean dumpAll, String dumpPackage) {
17221        boolean needSep;
17222        boolean printedAnything = false;
17223
17224        ItemMatcher matcher = new ItemMatcher();
17225        matcher.build(args, opti);
17226
17227        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
17228
17229        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
17230        printedAnything |= needSep;
17231
17232        if (mLaunchingProviders.size() > 0) {
17233            boolean printed = false;
17234            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
17235                ContentProviderRecord r = mLaunchingProviders.get(i);
17236                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
17237                    continue;
17238                }
17239                if (!printed) {
17240                    if (needSep) pw.println();
17241                    needSep = true;
17242                    pw.println("  Launching content providers:");
17243                    printed = true;
17244                    printedAnything = true;
17245                }
17246                pw.print("  Launching #"); pw.print(i); pw.print(": ");
17247                        pw.println(r);
17248            }
17249        }
17250
17251        if (!printedAnything) {
17252            pw.println("  (nothing)");
17253        }
17254    }
17255
17256    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17257            int opti, boolean dumpAll, String dumpPackage) {
17258        boolean needSep = false;
17259        boolean printedAnything = false;
17260
17261        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
17262
17263        if (mGrantedUriPermissions.size() > 0) {
17264            boolean printed = false;
17265            int dumpUid = -2;
17266            if (dumpPackage != null) {
17267                try {
17268                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
17269                            MATCH_ANY_USER, 0);
17270                } catch (NameNotFoundException e) {
17271                    dumpUid = -1;
17272                }
17273            }
17274            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
17275                int uid = mGrantedUriPermissions.keyAt(i);
17276                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
17277                    continue;
17278                }
17279                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
17280                if (!printed) {
17281                    if (needSep) pw.println();
17282                    needSep = true;
17283                    pw.println("  Granted Uri Permissions:");
17284                    printed = true;
17285                    printedAnything = true;
17286                }
17287                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
17288                for (UriPermission perm : perms.values()) {
17289                    pw.print("    "); pw.println(perm);
17290                    if (dumpAll) {
17291                        perm.dump(pw, "      ");
17292                    }
17293                }
17294            }
17295        }
17296
17297        if (!printedAnything) {
17298            pw.println("  (nothing)");
17299        }
17300    }
17301
17302    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17303            int opti, boolean dumpAll, String dumpPackage) {
17304        boolean printed = false;
17305
17306        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
17307
17308        if (mIntentSenderRecords.size() > 0) {
17309            // Organize these by package name, so they are easier to read.
17310            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
17311            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
17312            final Iterator<WeakReference<PendingIntentRecord>> it
17313                    = mIntentSenderRecords.values().iterator();
17314            while (it.hasNext()) {
17315                WeakReference<PendingIntentRecord> ref = it.next();
17316                PendingIntentRecord rec = ref != null ? ref.get() : null;
17317                if (rec == null) {
17318                    weakRefs.add(ref);
17319                    continue;
17320                }
17321                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
17322                    continue;
17323                }
17324                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
17325                if (list == null) {
17326                    list = new ArrayList<>();
17327                    byPackage.put(rec.key.packageName, list);
17328                }
17329                list.add(rec);
17330            }
17331            for (int i = 0; i < byPackage.size(); i++) {
17332                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
17333                printed = true;
17334                pw.print("  * "); pw.print(byPackage.keyAt(i));
17335                pw.print(": "); pw.print(intents.size()); pw.println(" items");
17336                for (int j = 0; j < intents.size(); j++) {
17337                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
17338                    if (dumpAll) {
17339                        intents.get(j).dump(pw, "      ");
17340                    }
17341                }
17342            }
17343            if (weakRefs.size() > 0) {
17344                printed = true;
17345                pw.println("  * WEAK REFS:");
17346                for (int i = 0; i < weakRefs.size(); i++) {
17347                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
17348                }
17349            }
17350        }
17351
17352        if (!printed) {
17353            pw.println("  (nothing)");
17354        }
17355    }
17356
17357    private static final int dumpProcessList(PrintWriter pw,
17358            ActivityManagerService service, List list,
17359            String prefix, String normalLabel, String persistentLabel,
17360            String dumpPackage) {
17361        int numPers = 0;
17362        final int N = list.size()-1;
17363        for (int i=N; i>=0; i--) {
17364            ProcessRecord r = (ProcessRecord)list.get(i);
17365            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17366                continue;
17367            }
17368            pw.println(String.format("%s%s #%2d: %s",
17369                    prefix, (r.persistent ? persistentLabel : normalLabel),
17370                    i, r.toString()));
17371            if (r.persistent) {
17372                numPers++;
17373            }
17374        }
17375        return numPers;
17376    }
17377
17378    private static final ArrayList<Pair<ProcessRecord, Integer>>
17379        sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
17380        ArrayList<Pair<ProcessRecord, Integer>> list
17381                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
17382        for (int i=0; i<origList.size(); i++) {
17383            ProcessRecord r = origList.get(i);
17384            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17385                continue;
17386            }
17387            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
17388        }
17389
17390        Comparator<Pair<ProcessRecord, Integer>> comparator
17391                = new Comparator<Pair<ProcessRecord, Integer>>() {
17392            @Override
17393            public int compare(Pair<ProcessRecord, Integer> object1,
17394                    Pair<ProcessRecord, Integer> object2) {
17395                if (object1.first.setAdj != object2.first.setAdj) {
17396                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
17397                }
17398                if (object1.first.setProcState != object2.first.setProcState) {
17399                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
17400                }
17401                if (object1.second.intValue() != object2.second.intValue()) {
17402                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
17403                }
17404                return 0;
17405            }
17406        };
17407
17408        Collections.sort(list, comparator);
17409        return list;
17410    }
17411
17412    private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
17413            ActivityManagerService service, List<ProcessRecord> origList,
17414            boolean inclDetails, String dumpPackage) {
17415        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17416        if (list.isEmpty()) return false;
17417
17418        final long curUptime = SystemClock.uptimeMillis();
17419
17420        for (int i = list.size() - 1; i >= 0; i--) {
17421            ProcessRecord r = list.get(i).first;
17422            long token = proto.start(fieldId);
17423            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17424            proto.write(ProcessOomProto.PERSISTENT, r.persistent);
17425            proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
17426            proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
17427            int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
17428            switch (r.setSchedGroup) {
17429                case ProcessList.SCHED_GROUP_BACKGROUND:
17430                    schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
17431                    break;
17432                case ProcessList.SCHED_GROUP_DEFAULT:
17433                    schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
17434                    break;
17435                case ProcessList.SCHED_GROUP_TOP_APP:
17436                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
17437                    break;
17438                case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
17439                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
17440                    break;
17441            }
17442            if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
17443                proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
17444            }
17445            if (r.foregroundActivities) {
17446                proto.write(ProcessOomProto.ACTIVITIES, true);
17447            } else if (r.foregroundServices) {
17448                proto.write(ProcessOomProto.SERVICES, true);
17449            }
17450            proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
17451            proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
17452            r.writeToProto(proto, ProcessOomProto.PROC);
17453            proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
17454            if (r.adjSource != null || r.adjTarget != null) {
17455                if (r.adjTarget instanceof  ComponentName) {
17456                    ComponentName cn = (ComponentName) r.adjTarget;
17457                    cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
17458                } else if (r.adjTarget != null) {
17459                    proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
17460                }
17461                if (r.adjSource instanceof ProcessRecord) {
17462                    ProcessRecord p = (ProcessRecord) r.adjSource;
17463                    p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
17464                } else if (r.adjSource != null) {
17465                    proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
17466                }
17467            }
17468            if (inclDetails) {
17469                long detailToken = proto.start(ProcessOomProto.DETAIL);
17470                proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
17471                proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
17472                proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
17473                proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
17474                proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
17475                proto.write(ProcessOomProto.Detail.CURRENT_STATE,
17476                        ProcessList.makeProcStateProtoEnum(r.curProcState));
17477                proto.write(ProcessOomProto.Detail.SET_STATE,
17478                        ProcessList.makeProcStateProtoEnum(r.setProcState));
17479                proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
17480                        r.lastPss*1024, new StringBuilder()));
17481                proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
17482                        r.lastSwapPss*1024, new StringBuilder()));
17483                proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
17484                        r.lastCachedPss*1024, new StringBuilder()));
17485                proto.write(ProcessOomProto.Detail.CACHED, r.cached);
17486                proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
17487                proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
17488
17489                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
17490                    if (r.lastCpuTime != 0) {
17491                        long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17492                        long timeUsed = r.curCpuTime - r.lastCpuTime;
17493                        long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
17494                        proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
17495                        proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
17496                        proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
17497                                (100.0*timeUsed)/uptimeSince);
17498                        proto.end(cpuTimeToken);
17499                    }
17500                }
17501                proto.end(detailToken);
17502            }
17503            proto.end(token);
17504        }
17505
17506        return true;
17507    }
17508
17509    private static final boolean dumpProcessOomList(PrintWriter pw,
17510            ActivityManagerService service, List<ProcessRecord> origList,
17511            String prefix, String normalLabel, String persistentLabel,
17512            boolean inclDetails, String dumpPackage) {
17513
17514        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17515        if (list.isEmpty()) return false;
17516
17517        final long curUptime = SystemClock.uptimeMillis();
17518        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17519
17520        for (int i=list.size()-1; i>=0; i--) {
17521            ProcessRecord r = list.get(i).first;
17522            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17523            char schedGroup;
17524            switch (r.setSchedGroup) {
17525                case ProcessList.SCHED_GROUP_BACKGROUND:
17526                    schedGroup = 'B';
17527                    break;
17528                case ProcessList.SCHED_GROUP_DEFAULT:
17529                    schedGroup = 'F';
17530                    break;
17531                case ProcessList.SCHED_GROUP_TOP_APP:
17532                    schedGroup = 'T';
17533                    break;
17534                default:
17535                    schedGroup = '?';
17536                    break;
17537            }
17538            char foreground;
17539            if (r.foregroundActivities) {
17540                foreground = 'A';
17541            } else if (r.foregroundServices) {
17542                foreground = 'S';
17543            } else {
17544                foreground = ' ';
17545            }
17546            String procState = ProcessList.makeProcStateString(r.curProcState);
17547            pw.print(prefix);
17548            pw.print(r.persistent ? persistentLabel : normalLabel);
17549            pw.print(" #");
17550            int num = (origList.size()-1)-list.get(i).second;
17551            if (num < 10) pw.print(' ');
17552            pw.print(num);
17553            pw.print(": ");
17554            pw.print(oomAdj);
17555            pw.print(' ');
17556            pw.print(schedGroup);
17557            pw.print('/');
17558            pw.print(foreground);
17559            pw.print('/');
17560            pw.print(procState);
17561            pw.print(" trm:");
17562            if (r.trimMemoryLevel < 10) pw.print(' ');
17563            pw.print(r.trimMemoryLevel);
17564            pw.print(' ');
17565            pw.print(r.toShortString());
17566            pw.print(" (");
17567            pw.print(r.adjType);
17568            pw.println(')');
17569            if (r.adjSource != null || r.adjTarget != null) {
17570                pw.print(prefix);
17571                pw.print("    ");
17572                if (r.adjTarget instanceof ComponentName) {
17573                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
17574                } else if (r.adjTarget != null) {
17575                    pw.print(r.adjTarget.toString());
17576                } else {
17577                    pw.print("{null}");
17578                }
17579                pw.print("<=");
17580                if (r.adjSource instanceof ProcessRecord) {
17581                    pw.print("Proc{");
17582                    pw.print(((ProcessRecord)r.adjSource).toShortString());
17583                    pw.println("}");
17584                } else if (r.adjSource != null) {
17585                    pw.println(r.adjSource.toString());
17586                } else {
17587                    pw.println("{null}");
17588                }
17589            }
17590            if (inclDetails) {
17591                pw.print(prefix);
17592                pw.print("    ");
17593                pw.print("oom: max="); pw.print(r.maxAdj);
17594                pw.print(" curRaw="); pw.print(r.curRawAdj);
17595                pw.print(" setRaw="); pw.print(r.setRawAdj);
17596                pw.print(" cur="); pw.print(r.curAdj);
17597                pw.print(" set="); pw.println(r.setAdj);
17598                pw.print(prefix);
17599                pw.print("    ");
17600                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
17601                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
17602                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
17603                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
17604                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
17605                pw.println();
17606                pw.print(prefix);
17607                pw.print("    ");
17608                pw.print("cached="); pw.print(r.cached);
17609                pw.print(" empty="); pw.print(r.empty);
17610                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
17611
17612                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
17613                    if (r.lastCpuTime != 0) {
17614                        long timeUsed = r.curCpuTime - r.lastCpuTime;
17615                        pw.print(prefix);
17616                        pw.print("    ");
17617                        pw.print("run cpu over ");
17618                        TimeUtils.formatDuration(uptimeSince, pw);
17619                        pw.print(" used ");
17620                        TimeUtils.formatDuration(timeUsed, pw);
17621                        pw.print(" (");
17622                        pw.print((timeUsed*100)/uptimeSince);
17623                        pw.println("%)");
17624                    }
17625                }
17626            }
17627        }
17628        return true;
17629    }
17630
17631    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
17632            String[] args) {
17633        ArrayList<ProcessRecord> procs;
17634        synchronized (this) {
17635            if (args != null && args.length > start
17636                    && args[start].charAt(0) != '-') {
17637                procs = new ArrayList<ProcessRecord>();
17638                int pid = -1;
17639                try {
17640                    pid = Integer.parseInt(args[start]);
17641                } catch (NumberFormatException e) {
17642                }
17643                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17644                    ProcessRecord proc = mLruProcesses.get(i);
17645                    if (proc.pid > 0 && proc.pid == pid) {
17646                        procs.add(proc);
17647                    } else if (allPkgs && proc.pkgList != null
17648                            && proc.pkgList.containsKey(args[start])) {
17649                        procs.add(proc);
17650                    } else if (proc.processName.equals(args[start])) {
17651                        procs.add(proc);
17652                    }
17653                }
17654                if (procs.size() <= 0) {
17655                    return null;
17656                }
17657            } else {
17658                procs = new ArrayList<ProcessRecord>(mLruProcesses);
17659            }
17660        }
17661        return procs;
17662    }
17663
17664    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
17665            PrintWriter pw, String[] args) {
17666        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
17667        if (procs == null) {
17668            pw.println("No process found for: " + args[0]);
17669            return;
17670        }
17671
17672        long uptime = SystemClock.uptimeMillis();
17673        long realtime = SystemClock.elapsedRealtime();
17674        pw.println("Applications Graphics Acceleration Info:");
17675        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17676
17677        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17678            ProcessRecord r = procs.get(i);
17679            if (r.thread != null) {
17680                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
17681                pw.flush();
17682                try {
17683                    TransferPipe tp = new TransferPipe();
17684                    try {
17685                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
17686                        tp.go(fd);
17687                    } finally {
17688                        tp.kill();
17689                    }
17690                } catch (IOException e) {
17691                    pw.println("Failure while dumping the app: " + r);
17692                    pw.flush();
17693                } catch (RemoteException e) {
17694                    pw.println("Got a RemoteException while dumping the app " + r);
17695                    pw.flush();
17696                }
17697            }
17698        }
17699    }
17700
17701    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
17702        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
17703        if (procs == null) {
17704            pw.println("No process found for: " + args[0]);
17705            return;
17706        }
17707
17708        pw.println("Applications Database Info:");
17709
17710        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17711            ProcessRecord r = procs.get(i);
17712            if (r.thread != null) {
17713                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
17714                pw.flush();
17715                try {
17716                    TransferPipe tp = new TransferPipe();
17717                    try {
17718                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
17719                        tp.go(fd);
17720                    } finally {
17721                        tp.kill();
17722                    }
17723                } catch (IOException e) {
17724                    pw.println("Failure while dumping the app: " + r);
17725                    pw.flush();
17726                } catch (RemoteException e) {
17727                    pw.println("Got a RemoteException while dumping the app " + r);
17728                    pw.flush();
17729                }
17730            }
17731        }
17732    }
17733
17734    final static class MemItem {
17735        final boolean isProc;
17736        final String label;
17737        final String shortLabel;
17738        final long pss;
17739        final long swapPss;
17740        final int id;
17741        final boolean hasActivities;
17742        ArrayList<MemItem> subitems;
17743
17744        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
17745                boolean _hasActivities) {
17746            isProc = true;
17747            label = _label;
17748            shortLabel = _shortLabel;
17749            pss = _pss;
17750            swapPss = _swapPss;
17751            id = _id;
17752            hasActivities = _hasActivities;
17753        }
17754
17755        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
17756            isProc = false;
17757            label = _label;
17758            shortLabel = _shortLabel;
17759            pss = _pss;
17760            swapPss = _swapPss;
17761            id = _id;
17762            hasActivities = false;
17763        }
17764    }
17765
17766    private static void sortMemItems(List<MemItem> items) {
17767        Collections.sort(items, new Comparator<MemItem>() {
17768            @Override
17769            public int compare(MemItem lhs, MemItem rhs) {
17770                if (lhs.pss < rhs.pss) {
17771                    return 1;
17772                } else if (lhs.pss > rhs.pss) {
17773                    return -1;
17774                }
17775                return 0;
17776            }
17777        });
17778    }
17779
17780    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
17781            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
17782        if (sort && !isCompact) {
17783            sortMemItems(items);
17784        }
17785
17786        for (int i=0; i<items.size(); i++) {
17787            MemItem mi = items.get(i);
17788            if (!isCompact) {
17789                if (dumpSwapPss) {
17790                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
17791                            mi.label, stringifyKBSize(mi.swapPss));
17792                } else {
17793                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
17794                }
17795            } else if (mi.isProc) {
17796                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
17797                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
17798                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
17799                pw.println(mi.hasActivities ? ",a" : ",e");
17800            } else {
17801                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
17802                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
17803            }
17804            if (mi.subitems != null) {
17805                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
17806                        true, isCompact, dumpSwapPss);
17807            }
17808        }
17809    }
17810
17811    static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
17812            ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
17813        if (sort) {
17814            sortMemItems(items);
17815        }
17816
17817        for (int i=0; i<items.size(); i++) {
17818            MemItem mi = items.get(i);
17819            final long token = proto.start(fieldId);
17820
17821            proto.write(MemInfoProto.MemItem.TAG, tag);
17822            proto.write(MemInfoProto.MemItem.LABEL, mi.shortLabel);
17823            proto.write(MemInfoProto.MemItem.IS_PROC, mi.isProc);
17824            proto.write(MemInfoProto.MemItem.ID, mi.id);
17825            proto.write(MemInfoProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
17826            proto.write(MemInfoProto.MemItem.PSS_KB, mi.pss);
17827            if (dumpSwapPss) {
17828                proto.write(MemInfoProto.MemItem.SWAP_PSS_KB, mi.swapPss);
17829            }
17830            if (mi.subitems != null) {
17831                dumpMemItems(proto, MemInfoProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
17832                        true, dumpSwapPss);
17833            }
17834            proto.end(token);
17835        }
17836    }
17837
17838    // These are in KB.
17839    static final long[] DUMP_MEM_BUCKETS = new long[] {
17840        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
17841        120*1024, 160*1024, 200*1024,
17842        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
17843        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
17844    };
17845
17846    static final void appendMemBucket(StringBuilder out, long memKB, String label,
17847            boolean stackLike) {
17848        int start = label.lastIndexOf('.');
17849        if (start >= 0) start++;
17850        else start = 0;
17851        int end = label.length();
17852        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
17853            if (DUMP_MEM_BUCKETS[i] >= memKB) {
17854                long bucket = DUMP_MEM_BUCKETS[i]/1024;
17855                out.append(bucket);
17856                out.append(stackLike ? "MB." : "MB ");
17857                out.append(label, start, end);
17858                return;
17859            }
17860        }
17861        out.append(memKB/1024);
17862        out.append(stackLike ? "MB." : "MB ");
17863        out.append(label, start, end);
17864    }
17865
17866    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17867            ProcessList.NATIVE_ADJ,
17868            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17869            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17870            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17871            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17872            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17873            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17874    };
17875    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17876            "Native",
17877            "System", "Persistent", "Persistent Service", "Foreground",
17878            "Visible", "Perceptible",
17879            "Heavy Weight", "Backup",
17880            "A Services", "Home",
17881            "Previous", "B Services", "Cached"
17882    };
17883    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17884            "native",
17885            "sys", "pers", "persvc", "fore",
17886            "vis", "percept",
17887            "heavy", "backup",
17888            "servicea", "home",
17889            "prev", "serviceb", "cached"
17890    };
17891
17892    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17893            long realtime, boolean isCheckinRequest, boolean isCompact) {
17894        if (isCompact) {
17895            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17896        }
17897        if (isCheckinRequest || isCompact) {
17898            // short checkin version
17899            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17900        } else {
17901            pw.println("Applications Memory Usage (in Kilobytes):");
17902            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17903        }
17904    }
17905
17906    private static final int KSM_SHARED = 0;
17907    private static final int KSM_SHARING = 1;
17908    private static final int KSM_UNSHARED = 2;
17909    private static final int KSM_VOLATILE = 3;
17910
17911    private final long[] getKsmInfo() {
17912        long[] longOut = new long[4];
17913        final int[] SINGLE_LONG_FORMAT = new int[] {
17914            PROC_SPACE_TERM| PROC_OUT_LONG
17915        };
17916        long[] longTmp = new long[1];
17917        readProcFile("/sys/kernel/mm/ksm/pages_shared",
17918                SINGLE_LONG_FORMAT, null, longTmp, null);
17919        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17920        longTmp[0] = 0;
17921        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17922                SINGLE_LONG_FORMAT, null, longTmp, null);
17923        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17924        longTmp[0] = 0;
17925        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17926                SINGLE_LONG_FORMAT, null, longTmp, null);
17927        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17928        longTmp[0] = 0;
17929        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17930                SINGLE_LONG_FORMAT, null, longTmp, null);
17931        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17932        return longOut;
17933    }
17934
17935    private static String stringifySize(long size, int order) {
17936        Locale locale = Locale.US;
17937        switch (order) {
17938            case 1:
17939                return String.format(locale, "%,13d", size);
17940            case 1024:
17941                return String.format(locale, "%,9dK", size / 1024);
17942            case 1024 * 1024:
17943                return String.format(locale, "%,5dM", size / 1024 / 1024);
17944            case 1024 * 1024 * 1024:
17945                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17946            default:
17947                throw new IllegalArgumentException("Invalid size order");
17948        }
17949    }
17950
17951    private static String stringifyKBSize(long size) {
17952        return stringifySize(size * 1024, 1024);
17953    }
17954
17955    // Update this version number if you change the 'compact' format.
17956    private static final int MEMINFO_COMPACT_VERSION = 1;
17957
17958    private static class MemoryUsageDumpOptions {
17959        boolean dumpDetails;
17960        boolean dumpFullDetails;
17961        boolean dumpDalvik;
17962        boolean dumpSummaryOnly;
17963        boolean dumpUnreachable;
17964        boolean oomOnly;
17965        boolean isCompact;
17966        boolean localOnly;
17967        boolean packages;
17968        boolean isCheckinRequest;
17969        boolean dumpSwapPss;
17970        boolean dumpProto;
17971    }
17972
17973    final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
17974            String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
17975        MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
17976        opts.dumpDetails = false;
17977        opts.dumpFullDetails = false;
17978        opts.dumpDalvik = false;
17979        opts.dumpSummaryOnly = false;
17980        opts.dumpUnreachable = false;
17981        opts.oomOnly = false;
17982        opts.isCompact = false;
17983        opts.localOnly = false;
17984        opts.packages = false;
17985        opts.isCheckinRequest = false;
17986        opts.dumpSwapPss = false;
17987        opts.dumpProto = asProto;
17988
17989        int opti = 0;
17990        while (opti < args.length) {
17991            String opt = args[opti];
17992            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17993                break;
17994            }
17995            opti++;
17996            if ("-a".equals(opt)) {
17997                opts.dumpDetails = true;
17998                opts.dumpFullDetails = true;
17999                opts.dumpDalvik = true;
18000                opts.dumpSwapPss = true;
18001            } else if ("-d".equals(opt)) {
18002                opts.dumpDalvik = true;
18003            } else if ("-c".equals(opt)) {
18004                opts.isCompact = true;
18005            } else if ("-s".equals(opt)) {
18006                opts.dumpDetails = true;
18007                opts.dumpSummaryOnly = true;
18008            } else if ("-S".equals(opt)) {
18009                opts.dumpSwapPss = true;
18010            } else if ("--unreachable".equals(opt)) {
18011                opts.dumpUnreachable = true;
18012            } else if ("--oom".equals(opt)) {
18013                opts.oomOnly = true;
18014            } else if ("--local".equals(opt)) {
18015                opts.localOnly = true;
18016            } else if ("--package".equals(opt)) {
18017                opts.packages = true;
18018            } else if ("--checkin".equals(opt)) {
18019                opts.isCheckinRequest = true;
18020            } else if ("--proto".equals(opt)) {
18021                opts.dumpProto = true;
18022
18023            } else if ("-h".equals(opt)) {
18024                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
18025                pw.println("  -a: include all available information for each process.");
18026                pw.println("  -d: include dalvik details.");
18027                pw.println("  -c: dump in a compact machine-parseable representation.");
18028                pw.println("  -s: dump only summary of application memory usage.");
18029                pw.println("  -S: dump also SwapPss.");
18030                pw.println("  --oom: only show processes organized by oom adj.");
18031                pw.println("  --local: only collect details locally, don't call process.");
18032                pw.println("  --package: interpret process arg as package, dumping all");
18033                pw.println("             processes that have loaded that package.");
18034                pw.println("  --checkin: dump data for a checkin");
18035                pw.println("  --proto: dump data to proto");
18036                pw.println("If [process] is specified it can be the name or ");
18037                pw.println("pid of a specific process to dump.");
18038                return;
18039            } else {
18040                pw.println("Unknown argument: " + opt + "; use -h for help");
18041            }
18042        }
18043
18044        String[] innerArgs = new String[args.length-opti];
18045        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18046
18047        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18048        if (opts.dumpProto) {
18049            dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18050        } else {
18051            dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
18052        }
18053    }
18054
18055    private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18056            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18057            ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
18058        long uptime = SystemClock.uptimeMillis();
18059        long realtime = SystemClock.elapsedRealtime();
18060        final long[] tmpLong = new long[1];
18061
18062        if (procs == null) {
18063            // No Java processes.  Maybe they want to print a native process.
18064            String proc = "N/A";
18065            if (innerArgs.length > 0) {
18066                proc = innerArgs[0];
18067                if (proc.charAt(0) != '-') {
18068                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18069                            = new ArrayList<ProcessCpuTracker.Stats>();
18070                    updateCpuStatsNow();
18071                    int findPid = -1;
18072                    try {
18073                        findPid = Integer.parseInt(innerArgs[0]);
18074                    } catch (NumberFormatException e) {
18075                    }
18076                    synchronized (mProcessCpuTracker) {
18077                        final int N = mProcessCpuTracker.countStats();
18078                        for (int i=0; i<N; i++) {
18079                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18080                            if (st.pid == findPid || (st.baseName != null
18081                                    && st.baseName.equals(innerArgs[0]))) {
18082                                nativeProcs.add(st);
18083                            }
18084                        }
18085                    }
18086                    if (nativeProcs.size() > 0) {
18087                        dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
18088                                opts.isCheckinRequest, opts.isCompact);
18089                        Debug.MemoryInfo mi = null;
18090                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18091                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18092                            final int pid = r.pid;
18093                            if (!opts.isCheckinRequest && opts.dumpDetails) {
18094                                pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
18095                            }
18096                            if (mi == null) {
18097                                mi = new Debug.MemoryInfo();
18098                            }
18099                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18100                                Debug.getMemoryInfo(pid, mi);
18101                            } else {
18102                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18103                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18104                            }
18105                            ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
18106                                    opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18107                                    pid, r.baseName, 0, 0, 0, 0, 0, 0);
18108                            if (opts.isCheckinRequest) {
18109                                pw.println();
18110                            }
18111                        }
18112                        return;
18113                    }
18114                }
18115            }
18116            pw.println("No process found for: " + proc);
18117            return;
18118        }
18119
18120        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18121            opts.dumpDetails = true;
18122        }
18123
18124        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
18125
18126        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18127        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18128        long nativePss = 0;
18129        long nativeSwapPss = 0;
18130        long dalvikPss = 0;
18131        long dalvikSwapPss = 0;
18132        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18133                EmptyArray.LONG;
18134        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18135                EmptyArray.LONG;
18136        long otherPss = 0;
18137        long otherSwapPss = 0;
18138        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18139        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18140
18141        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18142        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18143        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18144                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18145
18146        long totalPss = 0;
18147        long totalSwapPss = 0;
18148        long cachedPss = 0;
18149        long cachedSwapPss = 0;
18150        boolean hasSwapPss = false;
18151
18152        Debug.MemoryInfo mi = null;
18153        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18154            final ProcessRecord r = procs.get(i);
18155            final IApplicationThread thread;
18156            final int pid;
18157            final int oomAdj;
18158            final boolean hasActivities;
18159            synchronized (this) {
18160                thread = r.thread;
18161                pid = r.pid;
18162                oomAdj = r.getSetAdjWithServices();
18163                hasActivities = r.activities.size() > 0;
18164            }
18165            if (thread != null) {
18166                if (!opts.isCheckinRequest && opts.dumpDetails) {
18167                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
18168                }
18169                if (mi == null) {
18170                    mi = new Debug.MemoryInfo();
18171                }
18172                final int reportType;
18173                final long startTime;
18174                final long endTime;
18175                if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18176                    reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18177                    startTime = SystemClock.currentThreadTimeMillis();
18178                    Debug.getMemoryInfo(pid, mi);
18179                    endTime = SystemClock.currentThreadTimeMillis();
18180                    hasSwapPss = mi.hasSwappedOutPss;
18181                } else {
18182                    reportType = ProcessStats.ADD_PSS_EXTERNAL;
18183                    startTime = SystemClock.currentThreadTimeMillis();
18184                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18185                    endTime = SystemClock.currentThreadTimeMillis();
18186                    mi.dalvikPrivateDirty = (int)tmpLong[0];
18187                }
18188                if (opts.dumpDetails) {
18189                    if (opts.localOnly) {
18190                        ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
18191                                opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
18192                        if (opts.isCheckinRequest) {
18193                            pw.println();
18194                        }
18195                    } else {
18196                        pw.flush();
18197                        try {
18198                            TransferPipe tp = new TransferPipe();
18199                            try {
18200                                thread.dumpMemInfo(tp.getWriteFd(),
18201                                        mi, opts.isCheckinRequest, opts.dumpFullDetails,
18202                                        opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
18203                                tp.go(fd);
18204                            } finally {
18205                                tp.kill();
18206                            }
18207                        } catch (IOException e) {
18208                            if (!opts.isCheckinRequest) {
18209                                pw.println("Got IoException! " + e);
18210                                pw.flush();
18211                            }
18212                        } catch (RemoteException e) {
18213                            if (!opts.isCheckinRequest) {
18214                                pw.println("Got RemoteException! " + e);
18215                                pw.flush();
18216                            }
18217                        }
18218                    }
18219                }
18220
18221                final long myTotalPss = mi.getTotalPss();
18222                final long myTotalUss = mi.getTotalUss();
18223                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18224
18225                synchronized (this) {
18226                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18227                        // Record this for posterity if the process has been stable.
18228                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true,
18229                                reportType, endTime-startTime, r.pkgList);
18230                    }
18231                }
18232
18233                if (!opts.isCheckinRequest && mi != null) {
18234                    totalPss += myTotalPss;
18235                    totalSwapPss += myTotalSwapPss;
18236                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
18237                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
18238                            myTotalSwapPss, pid, hasActivities);
18239                    procMems.add(pssItem);
18240                    procMemsMap.put(pid, pssItem);
18241
18242                    nativePss += mi.nativePss;
18243                    nativeSwapPss += mi.nativeSwappedOutPss;
18244                    dalvikPss += mi.dalvikPss;
18245                    dalvikSwapPss += mi.dalvikSwappedOutPss;
18246                    for (int j=0; j<dalvikSubitemPss.length; j++) {
18247                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18248                        dalvikSubitemSwapPss[j] +=
18249                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18250                    }
18251                    otherPss += mi.otherPss;
18252                    otherSwapPss += mi.otherSwappedOutPss;
18253                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18254                        long mem = mi.getOtherPss(j);
18255                        miscPss[j] += mem;
18256                        otherPss -= mem;
18257                        mem = mi.getOtherSwappedOutPss(j);
18258                        miscSwapPss[j] += mem;
18259                        otherSwapPss -= mem;
18260                    }
18261
18262                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18263                        cachedPss += myTotalPss;
18264                        cachedSwapPss += myTotalSwapPss;
18265                    }
18266
18267                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
18268                        if (oomIndex == (oomPss.length - 1)
18269                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
18270                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
18271                            oomPss[oomIndex] += myTotalPss;
18272                            oomSwapPss[oomIndex] += myTotalSwapPss;
18273                            if (oomProcs[oomIndex] == null) {
18274                                oomProcs[oomIndex] = new ArrayList<MemItem>();
18275                            }
18276                            oomProcs[oomIndex].add(pssItem);
18277                            break;
18278                        }
18279                    }
18280                }
18281            }
18282        }
18283
18284        long nativeProcTotalPss = 0;
18285
18286        if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
18287            // If we are showing aggregations, also look for native processes to
18288            // include so that our aggregations are more accurate.
18289            updateCpuStatsNow();
18290            mi = null;
18291            synchronized (mProcessCpuTracker) {
18292                final int N = mProcessCpuTracker.countStats();
18293                for (int i=0; i<N; i++) {
18294                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18295                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
18296                        if (mi == null) {
18297                            mi = new Debug.MemoryInfo();
18298                        }
18299                        if (!brief && !opts.oomOnly) {
18300                            Debug.getMemoryInfo(st.pid, mi);
18301                        } else {
18302                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
18303                            mi.nativePrivateDirty = (int)tmpLong[0];
18304                        }
18305
18306                        final long myTotalPss = mi.getTotalPss();
18307                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18308                        totalPss += myTotalPss;
18309                        nativeProcTotalPss += myTotalPss;
18310
18311                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
18312                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
18313                        procMems.add(pssItem);
18314
18315                        nativePss += mi.nativePss;
18316                        nativeSwapPss += mi.nativeSwappedOutPss;
18317                        dalvikPss += mi.dalvikPss;
18318                        dalvikSwapPss += mi.dalvikSwappedOutPss;
18319                        for (int j=0; j<dalvikSubitemPss.length; j++) {
18320                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18321                            dalvikSubitemSwapPss[j] +=
18322                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18323                        }
18324                        otherPss += mi.otherPss;
18325                        otherSwapPss += mi.otherSwappedOutPss;
18326                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18327                            long mem = mi.getOtherPss(j);
18328                            miscPss[j] += mem;
18329                            otherPss -= mem;
18330                            mem = mi.getOtherSwappedOutPss(j);
18331                            miscSwapPss[j] += mem;
18332                            otherSwapPss -= mem;
18333                        }
18334                        oomPss[0] += myTotalPss;
18335                        oomSwapPss[0] += myTotalSwapPss;
18336                        if (oomProcs[0] == null) {
18337                            oomProcs[0] = new ArrayList<MemItem>();
18338                        }
18339                        oomProcs[0].add(pssItem);
18340                    }
18341                }
18342            }
18343
18344            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
18345
18346            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
18347            final int dalvikId = -2;
18348            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
18349            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
18350            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18351                String label = Debug.MemoryInfo.getOtherLabel(j);
18352                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
18353            }
18354            if (dalvikSubitemPss.length > 0) {
18355                // Add dalvik subitems.
18356                for (MemItem memItem : catMems) {
18357                    int memItemStart = 0, memItemEnd = 0;
18358                    if (memItem.id == dalvikId) {
18359                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
18360                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
18361                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
18362                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
18363                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
18364                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
18365                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
18366                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
18367                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
18368                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
18369                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
18370                    } else {
18371                        continue;  // No subitems, continue.
18372                    }
18373                    memItem.subitems = new ArrayList<MemItem>();
18374                    for (int j=memItemStart; j<=memItemEnd; j++) {
18375                        final String name = Debug.MemoryInfo.getOtherLabel(
18376                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
18377                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
18378                                dalvikSubitemSwapPss[j], j));
18379                    }
18380                }
18381            }
18382
18383            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
18384            for (int j=0; j<oomPss.length; j++) {
18385                if (oomPss[j] != 0) {
18386                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
18387                            : DUMP_MEM_OOM_LABEL[j];
18388                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
18389                            DUMP_MEM_OOM_ADJ[j]);
18390                    item.subitems = oomProcs[j];
18391                    oomMems.add(item);
18392                }
18393            }
18394
18395            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
18396            if (!brief && !opts.oomOnly && !opts.isCompact) {
18397                pw.println();
18398                pw.println("Total PSS by process:");
18399                dumpMemItems(pw, "  ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
18400                pw.println();
18401            }
18402            if (!opts.isCompact) {
18403                pw.println("Total PSS by OOM adjustment:");
18404            }
18405            dumpMemItems(pw, "  ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
18406            if (!brief && !opts.oomOnly) {
18407                PrintWriter out = categoryPw != null ? categoryPw : pw;
18408                if (!opts.isCompact) {
18409                    out.println();
18410                    out.println("Total PSS by category:");
18411                }
18412                dumpMemItems(out, "  ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
18413            }
18414            if (!opts.isCompact) {
18415                pw.println();
18416            }
18417            MemInfoReader memInfo = new MemInfoReader();
18418            memInfo.readMemInfo();
18419            if (nativeProcTotalPss > 0) {
18420                synchronized (this) {
18421                    final long cachedKb = memInfo.getCachedSizeKb();
18422                    final long freeKb = memInfo.getFreeSizeKb();
18423                    final long zramKb = memInfo.getZramTotalSizeKb();
18424                    final long kernelKb = memInfo.getKernelUsedSizeKb();
18425                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
18426                            kernelKb*1024, nativeProcTotalPss*1024);
18427                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
18428                            nativeProcTotalPss);
18429                }
18430            }
18431            if (!brief) {
18432                if (!opts.isCompact) {
18433                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
18434                    pw.print(" (status ");
18435                    switch (mLastMemoryLevel) {
18436                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
18437                            pw.println("normal)");
18438                            break;
18439                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
18440                            pw.println("moderate)");
18441                            break;
18442                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
18443                            pw.println("low)");
18444                            break;
18445                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18446                            pw.println("critical)");
18447                            break;
18448                        default:
18449                            pw.print(mLastMemoryLevel);
18450                            pw.println(")");
18451                            break;
18452                    }
18453                    pw.print(" Free RAM: ");
18454                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
18455                            + memInfo.getFreeSizeKb()));
18456                    pw.print(" (");
18457                    pw.print(stringifyKBSize(cachedPss));
18458                    pw.print(" cached pss + ");
18459                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
18460                    pw.print(" cached kernel + ");
18461                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
18462                    pw.println(" free)");
18463                } else {
18464                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
18465                    pw.print(cachedPss + memInfo.getCachedSizeKb()
18466                            + memInfo.getFreeSizeKb()); pw.print(",");
18467                    pw.println(totalPss - cachedPss);
18468                }
18469            }
18470            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
18471                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
18472                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
18473            if (!opts.isCompact) {
18474                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
18475                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
18476                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
18477                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
18478                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
18479            } else {
18480                pw.print("lostram,"); pw.println(lostRAM);
18481            }
18482            if (!brief) {
18483                if (memInfo.getZramTotalSizeKb() != 0) {
18484                    if (!opts.isCompact) {
18485                        pw.print("     ZRAM: ");
18486                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
18487                                pw.print(" physical used for ");
18488                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
18489                                        - memInfo.getSwapFreeSizeKb()));
18490                                pw.print(" in swap (");
18491                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
18492                                pw.println(" total swap)");
18493                    } else {
18494                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
18495                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
18496                                pw.println(memInfo.getSwapFreeSizeKb());
18497                    }
18498                }
18499                final long[] ksm = getKsmInfo();
18500                if (!opts.isCompact) {
18501                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
18502                            || ksm[KSM_VOLATILE] != 0) {
18503                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
18504                                pw.print(" saved from shared ");
18505                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
18506                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
18507                                pw.print(" unshared; ");
18508                                pw.print(stringifyKBSize(
18509                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
18510                    }
18511                    pw.print("   Tuning: ");
18512                    pw.print(ActivityManager.staticGetMemoryClass());
18513                    pw.print(" (large ");
18514                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18515                    pw.print("), oom ");
18516                    pw.print(stringifySize(
18517                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
18518                    pw.print(", restore limit ");
18519                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
18520                    if (ActivityManager.isLowRamDeviceStatic()) {
18521                        pw.print(" (low-ram)");
18522                    }
18523                    if (ActivityManager.isHighEndGfx()) {
18524                        pw.print(" (high-end-gfx)");
18525                    }
18526                    pw.println();
18527                } else {
18528                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
18529                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
18530                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
18531                    pw.print("tuning,");
18532                    pw.print(ActivityManager.staticGetMemoryClass());
18533                    pw.print(',');
18534                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18535                    pw.print(',');
18536                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
18537                    if (ActivityManager.isLowRamDeviceStatic()) {
18538                        pw.print(",low-ram");
18539                    }
18540                    if (ActivityManager.isHighEndGfx()) {
18541                        pw.print(",high-end-gfx");
18542                    }
18543                    pw.println();
18544                }
18545            }
18546        }
18547    }
18548
18549    private final void dumpApplicationMemoryUsage(FileDescriptor fd,
18550            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18551            ArrayList<ProcessRecord> procs) {
18552        final long uptimeMs = SystemClock.uptimeMillis();
18553        final long realtimeMs = SystemClock.elapsedRealtime();
18554        final long[] tmpLong = new long[1];
18555
18556        if (procs == null) {
18557            // No Java processes.  Maybe they want to print a native process.
18558            String proc = "N/A";
18559            if (innerArgs.length > 0) {
18560                proc = innerArgs[0];
18561                if (proc.charAt(0) != '-') {
18562                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18563                            = new ArrayList<ProcessCpuTracker.Stats>();
18564                    updateCpuStatsNow();
18565                    int findPid = -1;
18566                    try {
18567                        findPid = Integer.parseInt(innerArgs[0]);
18568                    } catch (NumberFormatException e) {
18569                    }
18570                    synchronized (mProcessCpuTracker) {
18571                        final int N = mProcessCpuTracker.countStats();
18572                        for (int i=0; i<N; i++) {
18573                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18574                            if (st.pid == findPid || (st.baseName != null
18575                                    && st.baseName.equals(innerArgs[0]))) {
18576                                nativeProcs.add(st);
18577                            }
18578                        }
18579                    }
18580                    if (nativeProcs.size() > 0) {
18581                        ProtoOutputStream proto = new ProtoOutputStream(fd);
18582
18583                        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
18584                        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
18585                        Debug.MemoryInfo mi = null;
18586                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18587                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18588                            final int pid = r.pid;
18589                            final long nToken = proto.start(MemInfoProto.NATIVE_PROCESSES);
18590
18591                            proto.write(MemInfoProto.ProcessMemory.PID, pid);
18592                            proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.baseName);
18593
18594                            if (mi == null) {
18595                                mi = new Debug.MemoryInfo();
18596                            }
18597                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18598                                Debug.getMemoryInfo(pid, mi);
18599                            } else {
18600                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18601                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18602                            }
18603                            ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
18604                                    opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
18605
18606                            proto.end(nToken);
18607                        }
18608
18609                        proto.flush();
18610                        return;
18611                    }
18612                }
18613            }
18614            Log.d(TAG, "No process found for: " + innerArgs[0]);
18615            return;
18616        }
18617
18618        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18619            opts.dumpDetails = true;
18620        }
18621
18622        ProtoOutputStream proto = new ProtoOutputStream(fd);
18623
18624        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
18625        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
18626
18627        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18628        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18629        long nativePss = 0;
18630        long nativeSwapPss = 0;
18631        long dalvikPss = 0;
18632        long dalvikSwapPss = 0;
18633        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18634                EmptyArray.LONG;
18635        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18636                EmptyArray.LONG;
18637        long otherPss = 0;
18638        long otherSwapPss = 0;
18639        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18640        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18641
18642        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18643        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18644        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18645                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18646
18647        long totalPss = 0;
18648        long totalSwapPss = 0;
18649        long cachedPss = 0;
18650        long cachedSwapPss = 0;
18651        boolean hasSwapPss = false;
18652
18653        Debug.MemoryInfo mi = null;
18654        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18655            final ProcessRecord r = procs.get(i);
18656            final IApplicationThread thread;
18657            final int pid;
18658            final int oomAdj;
18659            final boolean hasActivities;
18660            synchronized (this) {
18661                thread = r.thread;
18662                pid = r.pid;
18663                oomAdj = r.getSetAdjWithServices();
18664                hasActivities = r.activities.size() > 0;
18665            }
18666            if (thread == null) {
18667                continue;
18668            }
18669            if (mi == null) {
18670                mi = new Debug.MemoryInfo();
18671            }
18672            final int reportType;
18673            final long startTime;
18674            final long endTime;
18675            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18676                reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18677                startTime = SystemClock.currentThreadTimeMillis();
18678                Debug.getMemoryInfo(pid, mi);
18679                endTime = SystemClock.currentThreadTimeMillis();
18680                hasSwapPss = mi.hasSwappedOutPss;
18681            } else {
18682                reportType = ProcessStats.ADD_PSS_EXTERNAL;
18683                startTime = SystemClock.currentThreadTimeMillis();
18684                mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
18685                endTime = SystemClock.currentThreadTimeMillis();
18686                mi.dalvikPrivateDirty = (int) tmpLong[0];
18687            }
18688            if (opts.dumpDetails) {
18689                if (opts.localOnly) {
18690                    final long aToken = proto.start(MemInfoProto.APP_PROCESSES);
18691                    final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
18692                    proto.write(MemInfoProto.ProcessMemory.PID, pid);
18693                    proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.processName);
18694                    ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
18695                            opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
18696                    proto.end(mToken);
18697                    proto.end(aToken);
18698                } else {
18699                    try {
18700                        ByteTransferPipe tp = new ByteTransferPipe();
18701                        try {
18702                            thread.dumpMemInfoProto(tp.getWriteFd(),
18703                                mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18704                                opts.dumpUnreachable, innerArgs);
18705                            proto.write(MemInfoProto.APP_PROCESSES, tp.get());
18706                        } finally {
18707                            tp.kill();
18708                        }
18709                    } catch (IOException e) {
18710                        Log.e(TAG, "Got IOException!", e);
18711                    } catch (RemoteException e) {
18712                        Log.e(TAG, "Got RemoteException!", e);
18713                    }
18714                }
18715            }
18716
18717            final long myTotalPss = mi.getTotalPss();
18718            final long myTotalUss = mi.getTotalUss();
18719            final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18720
18721            synchronized (this) {
18722                if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18723                    // Record this for posterity if the process has been stable.
18724                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true,
18725                            reportType, endTime-startTime, r.pkgList);
18726                }
18727            }
18728
18729            if (!opts.isCheckinRequest && mi != null) {
18730                totalPss += myTotalPss;
18731                totalSwapPss += myTotalSwapPss;
18732                MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
18733                        (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
18734                        myTotalSwapPss, pid, hasActivities);
18735                procMems.add(pssItem);
18736                procMemsMap.put(pid, pssItem);
18737
18738                nativePss += mi.nativePss;
18739                nativeSwapPss += mi.nativeSwappedOutPss;
18740                dalvikPss += mi.dalvikPss;
18741                dalvikSwapPss += mi.dalvikSwappedOutPss;
18742                for (int j=0; j<dalvikSubitemPss.length; j++) {
18743                    dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18744                    dalvikSubitemSwapPss[j] +=
18745                            mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18746                }
18747                otherPss += mi.otherPss;
18748                otherSwapPss += mi.otherSwappedOutPss;
18749                for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18750                    long mem = mi.getOtherPss(j);
18751                    miscPss[j] += mem;
18752                    otherPss -= mem;
18753                    mem = mi.getOtherSwappedOutPss(j);
18754                    miscSwapPss[j] += mem;
18755                    otherSwapPss -= mem;
18756                }
18757
18758                if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18759                    cachedPss += myTotalPss;
18760                    cachedSwapPss += myTotalSwapPss;
18761                }
18762
18763                for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
18764                    if (oomIndex == (oomPss.length - 1)
18765                            || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
18766                                    && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
18767                        oomPss[oomIndex] += myTotalPss;
18768                        oomSwapPss[oomIndex] += myTotalSwapPss;
18769                        if (oomProcs[oomIndex] == null) {
18770                            oomProcs[oomIndex] = new ArrayList<MemItem>();
18771                        }
18772                        oomProcs[oomIndex].add(pssItem);
18773                        break;
18774                    }
18775                }
18776            }
18777        }
18778
18779        long nativeProcTotalPss = 0;
18780
18781        if (procs.size() > 1 && !opts.packages) {
18782            // If we are showing aggregations, also look for native processes to
18783            // include so that our aggregations are more accurate.
18784            updateCpuStatsNow();
18785            mi = null;
18786            synchronized (mProcessCpuTracker) {
18787                final int N = mProcessCpuTracker.countStats();
18788                for (int i=0; i<N; i++) {
18789                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18790                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
18791                        if (mi == null) {
18792                            mi = new Debug.MemoryInfo();
18793                        }
18794                        if (!brief && !opts.oomOnly) {
18795                            Debug.getMemoryInfo(st.pid, mi);
18796                        } else {
18797                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
18798                            mi.nativePrivateDirty = (int)tmpLong[0];
18799                        }
18800
18801                        final long myTotalPss = mi.getTotalPss();
18802                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18803                        totalPss += myTotalPss;
18804                        nativeProcTotalPss += myTotalPss;
18805
18806                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
18807                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
18808                        procMems.add(pssItem);
18809
18810                        nativePss += mi.nativePss;
18811                        nativeSwapPss += mi.nativeSwappedOutPss;
18812                        dalvikPss += mi.dalvikPss;
18813                        dalvikSwapPss += mi.dalvikSwappedOutPss;
18814                        for (int j=0; j<dalvikSubitemPss.length; j++) {
18815                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18816                            dalvikSubitemSwapPss[j] +=
18817                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18818                        }
18819                        otherPss += mi.otherPss;
18820                        otherSwapPss += mi.otherSwappedOutPss;
18821                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18822                            long mem = mi.getOtherPss(j);
18823                            miscPss[j] += mem;
18824                            otherPss -= mem;
18825                            mem = mi.getOtherSwappedOutPss(j);
18826                            miscSwapPss[j] += mem;
18827                            otherSwapPss -= mem;
18828                        }
18829                        oomPss[0] += myTotalPss;
18830                        oomSwapPss[0] += myTotalSwapPss;
18831                        if (oomProcs[0] == null) {
18832                            oomProcs[0] = new ArrayList<MemItem>();
18833                        }
18834                        oomProcs[0].add(pssItem);
18835                    }
18836                }
18837            }
18838
18839            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
18840
18841            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
18842            final int dalvikId = -2;
18843            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
18844            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
18845            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18846                String label = Debug.MemoryInfo.getOtherLabel(j);
18847                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
18848            }
18849            if (dalvikSubitemPss.length > 0) {
18850                // Add dalvik subitems.
18851                for (MemItem memItem : catMems) {
18852                    int memItemStart = 0, memItemEnd = 0;
18853                    if (memItem.id == dalvikId) {
18854                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
18855                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
18856                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
18857                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
18858                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
18859                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
18860                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
18861                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
18862                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
18863                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
18864                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
18865                    } else {
18866                        continue;  // No subitems, continue.
18867                    }
18868                    memItem.subitems = new ArrayList<MemItem>();
18869                    for (int j=memItemStart; j<=memItemEnd; j++) {
18870                        final String name = Debug.MemoryInfo.getOtherLabel(
18871                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
18872                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
18873                                dalvikSubitemSwapPss[j], j));
18874                    }
18875                }
18876            }
18877
18878            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
18879            for (int j=0; j<oomPss.length; j++) {
18880                if (oomPss[j] != 0) {
18881                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
18882                            : DUMP_MEM_OOM_LABEL[j];
18883                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
18884                            DUMP_MEM_OOM_ADJ[j]);
18885                    item.subitems = oomProcs[j];
18886                    oomMems.add(item);
18887                }
18888            }
18889
18890            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
18891            if (!opts.oomOnly) {
18892                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_PROCESS, "proc",
18893                        procMems, true, opts.dumpSwapPss);
18894            }
18895            dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
18896                    oomMems, false, opts.dumpSwapPss);
18897            if (!brief && !opts.oomOnly) {
18898                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_CATEGORY, "cat",
18899                        catMems, true, opts.dumpSwapPss);
18900            }
18901            MemInfoReader memInfo = new MemInfoReader();
18902            memInfo.readMemInfo();
18903            if (nativeProcTotalPss > 0) {
18904                synchronized (this) {
18905                    final long cachedKb = memInfo.getCachedSizeKb();
18906                    final long freeKb = memInfo.getFreeSizeKb();
18907                    final long zramKb = memInfo.getZramTotalSizeKb();
18908                    final long kernelKb = memInfo.getKernelUsedSizeKb();
18909                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
18910                            kernelKb*1024, nativeProcTotalPss*1024);
18911                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
18912                            nativeProcTotalPss);
18913                }
18914            }
18915            if (!brief) {
18916                proto.write(MemInfoProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
18917                proto.write(MemInfoProto.STATUS, mLastMemoryLevel);
18918                proto.write(MemInfoProto.CACHED_PSS_KB, cachedPss);
18919                proto.write(MemInfoProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
18920                proto.write(MemInfoProto.FREE_KB, memInfo.getFreeSizeKb());
18921            }
18922            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
18923                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
18924                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
18925            proto.write(MemInfoProto.USED_PSS_KB, totalPss - cachedPss);
18926            proto.write(MemInfoProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
18927            proto.write(MemInfoProto.LOST_RAM_KB, lostRAM);
18928            if (!brief) {
18929                if (memInfo.getZramTotalSizeKb() != 0) {
18930                    proto.write(MemInfoProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
18931                    proto.write(MemInfoProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
18932                            memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
18933                    proto.write(MemInfoProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
18934                }
18935                final long[] ksm = getKsmInfo();
18936                proto.write(MemInfoProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
18937                proto.write(MemInfoProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
18938                proto.write(MemInfoProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
18939                proto.write(MemInfoProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
18940
18941                proto.write(MemInfoProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
18942                proto.write(MemInfoProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
18943                proto.write(MemInfoProto.OOM_KB,
18944                        mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
18945                proto.write(MemInfoProto.RESTORE_LIMIT_KB,
18946                        mProcessList.getCachedRestoreThresholdKb());
18947
18948                proto.write(MemInfoProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
18949                proto.write(MemInfoProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
18950            }
18951        }
18952
18953        proto.flush();
18954    }
18955
18956    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
18957            long memtrack, String name) {
18958        sb.append("  ");
18959        sb.append(ProcessList.makeOomAdjString(oomAdj));
18960        sb.append(' ');
18961        sb.append(ProcessList.makeProcStateString(procState));
18962        sb.append(' ');
18963        ProcessList.appendRamKb(sb, pss);
18964        sb.append(": ");
18965        sb.append(name);
18966        if (memtrack > 0) {
18967            sb.append(" (");
18968            sb.append(stringifyKBSize(memtrack));
18969            sb.append(" memtrack)");
18970        }
18971    }
18972
18973    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
18974        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
18975        sb.append(" (pid ");
18976        sb.append(mi.pid);
18977        sb.append(") ");
18978        sb.append(mi.adjType);
18979        sb.append('\n');
18980        if (mi.adjReason != null) {
18981            sb.append("                      ");
18982            sb.append(mi.adjReason);
18983            sb.append('\n');
18984        }
18985    }
18986
18987    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
18988        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
18989        for (int i=0, N=memInfos.size(); i<N; i++) {
18990            ProcessMemInfo mi = memInfos.get(i);
18991            infoMap.put(mi.pid, mi);
18992        }
18993        updateCpuStatsNow();
18994        long[] memtrackTmp = new long[1];
18995        final List<ProcessCpuTracker.Stats> stats;
18996        // Get a list of Stats that have vsize > 0
18997        synchronized (mProcessCpuTracker) {
18998            stats = mProcessCpuTracker.getStats((st) -> {
18999                return st.vsize > 0;
19000            });
19001        }
19002        final int statsCount = stats.size();
19003        for (int i = 0; i < statsCount; i++) {
19004            ProcessCpuTracker.Stats st = stats.get(i);
19005            long pss = Debug.getPss(st.pid, null, memtrackTmp);
19006            if (pss > 0) {
19007                if (infoMap.indexOfKey(st.pid) < 0) {
19008                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19009                            ProcessList.NATIVE_ADJ, -1, "native", null);
19010                    mi.pss = pss;
19011                    mi.memtrack = memtrackTmp[0];
19012                    memInfos.add(mi);
19013                }
19014            }
19015        }
19016
19017        long totalPss = 0;
19018        long totalMemtrack = 0;
19019        for (int i=0, N=memInfos.size(); i<N; i++) {
19020            ProcessMemInfo mi = memInfos.get(i);
19021            if (mi.pss == 0) {
19022                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19023                mi.memtrack = memtrackTmp[0];
19024            }
19025            totalPss += mi.pss;
19026            totalMemtrack += mi.memtrack;
19027        }
19028        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
19029            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
19030                if (lhs.oomAdj != rhs.oomAdj) {
19031                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
19032                }
19033                if (lhs.pss != rhs.pss) {
19034                    return lhs.pss < rhs.pss ? 1 : -1;
19035                }
19036                return 0;
19037            }
19038        });
19039
19040        StringBuilder tag = new StringBuilder(128);
19041        StringBuilder stack = new StringBuilder(128);
19042        tag.append("Low on memory -- ");
19043        appendMemBucket(tag, totalPss, "total", false);
19044        appendMemBucket(stack, totalPss, "total", true);
19045
19046        StringBuilder fullNativeBuilder = new StringBuilder(1024);
19047        StringBuilder shortNativeBuilder = new StringBuilder(1024);
19048        StringBuilder fullJavaBuilder = new StringBuilder(1024);
19049
19050        boolean firstLine = true;
19051        int lastOomAdj = Integer.MIN_VALUE;
19052        long extraNativeRam = 0;
19053        long extraNativeMemtrack = 0;
19054        long cachedPss = 0;
19055        for (int i=0, N=memInfos.size(); i<N; i++) {
19056            ProcessMemInfo mi = memInfos.get(i);
19057
19058            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19059                cachedPss += mi.pss;
19060            }
19061
19062            if (mi.oomAdj != ProcessList.NATIVE_ADJ
19063                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
19064                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
19065                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
19066                if (lastOomAdj != mi.oomAdj) {
19067                    lastOomAdj = mi.oomAdj;
19068                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19069                        tag.append(" / ");
19070                    }
19071                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19072                        if (firstLine) {
19073                            stack.append(":");
19074                            firstLine = false;
19075                        }
19076                        stack.append("\n\t at ");
19077                    } else {
19078                        stack.append("$");
19079                    }
19080                } else {
19081                    tag.append(" ");
19082                    stack.append("$");
19083                }
19084                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19085                    appendMemBucket(tag, mi.pss, mi.name, false);
19086                }
19087                appendMemBucket(stack, mi.pss, mi.name, true);
19088                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
19089                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
19090                    stack.append("(");
19091                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
19092                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
19093                            stack.append(DUMP_MEM_OOM_LABEL[k]);
19094                            stack.append(":");
19095                            stack.append(DUMP_MEM_OOM_ADJ[k]);
19096                        }
19097                    }
19098                    stack.append(")");
19099                }
19100            }
19101
19102            appendMemInfo(fullNativeBuilder, mi);
19103            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
19104                // The short form only has native processes that are >= 512K.
19105                if (mi.pss >= 512) {
19106                    appendMemInfo(shortNativeBuilder, mi);
19107                } else {
19108                    extraNativeRam += mi.pss;
19109                    extraNativeMemtrack += mi.memtrack;
19110                }
19111            } else {
19112                // Short form has all other details, but if we have collected RAM
19113                // from smaller native processes let's dump a summary of that.
19114                if (extraNativeRam > 0) {
19115                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
19116                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
19117                    shortNativeBuilder.append('\n');
19118                    extraNativeRam = 0;
19119                }
19120                appendMemInfo(fullJavaBuilder, mi);
19121            }
19122        }
19123
19124        fullJavaBuilder.append("           ");
19125        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
19126        fullJavaBuilder.append(": TOTAL");
19127        if (totalMemtrack > 0) {
19128            fullJavaBuilder.append(" (");
19129            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
19130            fullJavaBuilder.append(" memtrack)");
19131        } else {
19132        }
19133        fullJavaBuilder.append("\n");
19134
19135        MemInfoReader memInfo = new MemInfoReader();
19136        memInfo.readMemInfo();
19137        final long[] infos = memInfo.getRawInfo();
19138
19139        StringBuilder memInfoBuilder = new StringBuilder(1024);
19140        Debug.getMemInfo(infos);
19141        memInfoBuilder.append("  MemInfo: ");
19142        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
19143        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
19144        memInfoBuilder.append(stringifyKBSize(
19145                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
19146        memInfoBuilder.append(stringifyKBSize(
19147                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
19148        memInfoBuilder.append(stringifyKBSize(
19149                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
19150        memInfoBuilder.append("           ");
19151        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
19152        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
19153        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
19154        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
19155        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
19156            memInfoBuilder.append("  ZRAM: ");
19157            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
19158            memInfoBuilder.append(" RAM, ");
19159            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
19160            memInfoBuilder.append(" swap total, ");
19161            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
19162            memInfoBuilder.append(" swap free\n");
19163        }
19164        final long[] ksm = getKsmInfo();
19165        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19166                || ksm[KSM_VOLATILE] != 0) {
19167            memInfoBuilder.append("  KSM: ");
19168            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
19169            memInfoBuilder.append(" saved from shared ");
19170            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
19171            memInfoBuilder.append("\n       ");
19172            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
19173            memInfoBuilder.append(" unshared; ");
19174            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
19175            memInfoBuilder.append(" volatile\n");
19176        }
19177        memInfoBuilder.append("  Free RAM: ");
19178        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19179                + memInfo.getFreeSizeKb()));
19180        memInfoBuilder.append("\n");
19181        memInfoBuilder.append("  Used RAM: ");
19182        memInfoBuilder.append(stringifyKBSize(
19183                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
19184        memInfoBuilder.append("\n");
19185        memInfoBuilder.append("  Lost RAM: ");
19186        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
19187                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19188                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
19189        memInfoBuilder.append("\n");
19190        Slog.i(TAG, "Low on memory:");
19191        Slog.i(TAG, shortNativeBuilder.toString());
19192        Slog.i(TAG, fullJavaBuilder.toString());
19193        Slog.i(TAG, memInfoBuilder.toString());
19194
19195        StringBuilder dropBuilder = new StringBuilder(1024);
19196        /*
19197        StringWriter oomSw = new StringWriter();
19198        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
19199        StringWriter catSw = new StringWriter();
19200        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19201        String[] emptyArgs = new String[] { };
19202        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
19203        oomPw.flush();
19204        String oomString = oomSw.toString();
19205        */
19206        dropBuilder.append("Low on memory:");
19207        dropBuilder.append(stack);
19208        dropBuilder.append('\n');
19209        dropBuilder.append(fullNativeBuilder);
19210        dropBuilder.append(fullJavaBuilder);
19211        dropBuilder.append('\n');
19212        dropBuilder.append(memInfoBuilder);
19213        dropBuilder.append('\n');
19214        /*
19215        dropBuilder.append(oomString);
19216        dropBuilder.append('\n');
19217        */
19218        StringWriter catSw = new StringWriter();
19219        synchronized (ActivityManagerService.this) {
19220            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19221            String[] emptyArgs = new String[] { };
19222            catPw.println();
19223            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
19224            catPw.println();
19225            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
19226                    false, null).dumpLocked();
19227            catPw.println();
19228            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
19229            catPw.flush();
19230        }
19231        dropBuilder.append(catSw.toString());
19232        addErrorToDropBox("lowmem", null, "system_server", null,
19233                null, tag.toString(), dropBuilder.toString(), null, null);
19234        //Slog.i(TAG, "Sent to dropbox:");
19235        //Slog.i(TAG, dropBuilder.toString());
19236        synchronized (ActivityManagerService.this) {
19237            long now = SystemClock.uptimeMillis();
19238            if (mLastMemUsageReportTime < now) {
19239                mLastMemUsageReportTime = now;
19240            }
19241        }
19242    }
19243
19244    /**
19245     * Searches array of arguments for the specified string
19246     * @param args array of argument strings
19247     * @param value value to search for
19248     * @return true if the value is contained in the array
19249     */
19250    private static boolean scanArgs(String[] args, String value) {
19251        if (args != null) {
19252            for (String arg : args) {
19253                if (value.equals(arg)) {
19254                    return true;
19255                }
19256            }
19257        }
19258        return false;
19259    }
19260
19261    private final boolean removeDyingProviderLocked(ProcessRecord proc,
19262            ContentProviderRecord cpr, boolean always) {
19263        final boolean inLaunching = mLaunchingProviders.contains(cpr);
19264
19265        if (!inLaunching || always) {
19266            synchronized (cpr) {
19267                cpr.launchingApp = null;
19268                cpr.notifyAll();
19269            }
19270            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
19271            String names[] = cpr.info.authority.split(";");
19272            for (int j = 0; j < names.length; j++) {
19273                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
19274            }
19275        }
19276
19277        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
19278            ContentProviderConnection conn = cpr.connections.get(i);
19279            if (conn.waiting) {
19280                // If this connection is waiting for the provider, then we don't
19281                // need to mess with its process unless we are always removing
19282                // or for some reason the provider is not currently launching.
19283                if (inLaunching && !always) {
19284                    continue;
19285                }
19286            }
19287            ProcessRecord capp = conn.client;
19288            conn.dead = true;
19289            if (conn.stableCount > 0) {
19290                if (!capp.persistent && capp.thread != null
19291                        && capp.pid != 0
19292                        && capp.pid != MY_PID) {
19293                    capp.kill("depends on provider "
19294                            + cpr.name.flattenToShortString()
19295                            + " in dying proc " + (proc != null ? proc.processName : "??")
19296                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
19297                }
19298            } else if (capp.thread != null && conn.provider.provider != null) {
19299                try {
19300                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
19301                } catch (RemoteException e) {
19302                }
19303                // In the protocol here, we don't expect the client to correctly
19304                // clean up this connection, we'll just remove it.
19305                cpr.connections.remove(i);
19306                if (conn.client.conProviders.remove(conn)) {
19307                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
19308                }
19309            }
19310        }
19311
19312        if (inLaunching && always) {
19313            mLaunchingProviders.remove(cpr);
19314        }
19315        return inLaunching;
19316    }
19317
19318    /**
19319     * Main code for cleaning up a process when it has gone away.  This is
19320     * called both as a result of the process dying, or directly when stopping
19321     * a process when running in single process mode.
19322     *
19323     * @return Returns true if the given process has been restarted, so the
19324     * app that was passed in must remain on the process lists.
19325     */
19326    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
19327            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
19328        if (index >= 0) {
19329            removeLruProcessLocked(app);
19330            ProcessList.remove(app.pid);
19331        }
19332
19333        mProcessesToGc.remove(app);
19334        mPendingPssProcesses.remove(app);
19335
19336        // Dismiss any open dialogs.
19337        if (app.crashDialog != null && !app.forceCrashReport) {
19338            app.crashDialog.dismiss();
19339            app.crashDialog = null;
19340        }
19341        if (app.anrDialog != null) {
19342            app.anrDialog.dismiss();
19343            app.anrDialog = null;
19344        }
19345        if (app.waitDialog != null) {
19346            app.waitDialog.dismiss();
19347            app.waitDialog = null;
19348        }
19349
19350        app.crashing = false;
19351        app.notResponding = false;
19352
19353        app.resetPackageList(mProcessStats);
19354        app.unlinkDeathRecipient();
19355        app.makeInactive(mProcessStats);
19356        app.waitingToKill = null;
19357        app.forcingToImportant = null;
19358        updateProcessForegroundLocked(app, false, false);
19359        app.foregroundActivities = false;
19360        app.hasShownUi = false;
19361        app.treatLikeActivity = false;
19362        app.hasAboveClient = false;
19363        app.hasClientActivities = false;
19364
19365        mServices.killServicesLocked(app, allowRestart);
19366
19367        boolean restart = false;
19368
19369        // Remove published content providers.
19370        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
19371            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
19372            final boolean always = app.bad || !allowRestart;
19373            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
19374            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
19375                // We left the provider in the launching list, need to
19376                // restart it.
19377                restart = true;
19378            }
19379
19380            cpr.provider = null;
19381            cpr.proc = null;
19382        }
19383        app.pubProviders.clear();
19384
19385        // Take care of any launching providers waiting for this process.
19386        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
19387            restart = true;
19388        }
19389
19390        // Unregister from connected content providers.
19391        if (!app.conProviders.isEmpty()) {
19392            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
19393                ContentProviderConnection conn = app.conProviders.get(i);
19394                conn.provider.connections.remove(conn);
19395                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
19396                        conn.provider.name);
19397            }
19398            app.conProviders.clear();
19399        }
19400
19401        // At this point there may be remaining entries in mLaunchingProviders
19402        // where we were the only one waiting, so they are no longer of use.
19403        // Look for these and clean up if found.
19404        // XXX Commented out for now.  Trying to figure out a way to reproduce
19405        // the actual situation to identify what is actually going on.
19406        if (false) {
19407            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19408                ContentProviderRecord cpr = mLaunchingProviders.get(i);
19409                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
19410                    synchronized (cpr) {
19411                        cpr.launchingApp = null;
19412                        cpr.notifyAll();
19413                    }
19414                }
19415            }
19416        }
19417
19418        skipCurrentReceiverLocked(app);
19419
19420        // Unregister any receivers.
19421        for (int i = app.receivers.size() - 1; i >= 0; i--) {
19422            removeReceiverLocked(app.receivers.valueAt(i));
19423        }
19424        app.receivers.clear();
19425
19426        // If the app is undergoing backup, tell the backup manager about it
19427        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
19428            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
19429                    + mBackupTarget.appInfo + " died during backup");
19430            mHandler.post(new Runnable() {
19431                @Override
19432                public void run(){
19433                    try {
19434                        IBackupManager bm = IBackupManager.Stub.asInterface(
19435                                ServiceManager.getService(Context.BACKUP_SERVICE));
19436                        bm.agentDisconnected(app.info.packageName);
19437                    } catch (RemoteException e) {
19438                        // can't happen; backup manager is local
19439                    }
19440                }
19441            });
19442        }
19443
19444        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
19445            ProcessChangeItem item = mPendingProcessChanges.get(i);
19446            if (app.pid > 0 && item.pid == app.pid) {
19447                mPendingProcessChanges.remove(i);
19448                mAvailProcessChanges.add(item);
19449            }
19450        }
19451        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
19452                null).sendToTarget();
19453
19454        // If the caller is restarting this app, then leave it in its
19455        // current lists and let the caller take care of it.
19456        if (restarting) {
19457            return false;
19458        }
19459
19460        if (!app.persistent || app.isolated) {
19461            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
19462                    "Removing non-persistent process during cleanup: " + app);
19463            if (!replacingPid) {
19464                removeProcessNameLocked(app.processName, app.uid, app);
19465            }
19466            if (mHeavyWeightProcess == app) {
19467                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
19468                        mHeavyWeightProcess.userId, 0));
19469                mHeavyWeightProcess = null;
19470            }
19471        } else if (!app.removed) {
19472            // This app is persistent, so we need to keep its record around.
19473            // If it is not already on the pending app list, add it there
19474            // and start a new process for it.
19475            if (mPersistentStartingProcesses.indexOf(app) < 0) {
19476                mPersistentStartingProcesses.add(app);
19477                restart = true;
19478            }
19479        }
19480        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
19481                TAG_CLEANUP, "Clean-up removing on hold: " + app);
19482        mProcessesOnHold.remove(app);
19483
19484        if (app == mHomeProcess) {
19485            mHomeProcess = null;
19486        }
19487        if (app == mPreviousProcess) {
19488            mPreviousProcess = null;
19489        }
19490
19491        if (restart && !app.isolated) {
19492            // We have components that still need to be running in the
19493            // process, so re-launch it.
19494            if (index < 0) {
19495                ProcessList.remove(app.pid);
19496            }
19497            addProcessNameLocked(app);
19498            app.pendingStart = false;
19499            startProcessLocked(app, "restart", app.processName);
19500            return true;
19501        } else if (app.pid > 0 && app.pid != MY_PID) {
19502            // Goodbye!
19503            boolean removed;
19504            synchronized (mPidsSelfLocked) {
19505                mPidsSelfLocked.remove(app.pid);
19506                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
19507            }
19508            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
19509            if (app.isolated) {
19510                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
19511            }
19512            app.setPid(0);
19513        }
19514        return false;
19515    }
19516
19517    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
19518        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19519            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19520            if (cpr.launchingApp == app) {
19521                return true;
19522            }
19523        }
19524        return false;
19525    }
19526
19527    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
19528        // Look through the content providers we are waiting to have launched,
19529        // and if any run in this process then either schedule a restart of
19530        // the process or kill the client waiting for it if this process has
19531        // gone bad.
19532        boolean restart = false;
19533        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19534            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19535            if (cpr.launchingApp == app) {
19536                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
19537                    restart = true;
19538                } else {
19539                    removeDyingProviderLocked(app, cpr, true);
19540                }
19541            }
19542        }
19543        return restart;
19544    }
19545
19546    // =========================================================
19547    // SERVICES
19548    // =========================================================
19549
19550    @Override
19551    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
19552        enforceNotIsolatedCaller("getServices");
19553
19554        final int callingUid = Binder.getCallingUid();
19555        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
19556            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
19557        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
19558            callingUid);
19559        synchronized (this) {
19560            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
19561                allowed, canInteractAcrossUsers);
19562        }
19563    }
19564
19565    @Override
19566    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
19567        enforceNotIsolatedCaller("getRunningServiceControlPanel");
19568        synchronized (this) {
19569            return mServices.getRunningServiceControlPanelLocked(name);
19570        }
19571    }
19572
19573    @Override
19574    public ComponentName startService(IApplicationThread caller, Intent service,
19575            String resolvedType, boolean requireForeground, String callingPackage, int userId)
19576            throws TransactionTooLargeException {
19577        enforceNotIsolatedCaller("startService");
19578        // Refuse possible leaked file descriptors
19579        if (service != null && service.hasFileDescriptors() == true) {
19580            throw new IllegalArgumentException("File descriptors passed in Intent");
19581        }
19582
19583        if (callingPackage == null) {
19584            throw new IllegalArgumentException("callingPackage cannot be null");
19585        }
19586
19587        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
19588                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
19589        synchronized(this) {
19590            final int callingPid = Binder.getCallingPid();
19591            final int callingUid = Binder.getCallingUid();
19592            final long origId = Binder.clearCallingIdentity();
19593            ComponentName res;
19594            try {
19595                res = mServices.startServiceLocked(caller, service,
19596                        resolvedType, callingPid, callingUid,
19597                        requireForeground, callingPackage, userId);
19598            } finally {
19599                Binder.restoreCallingIdentity(origId);
19600            }
19601            return res;
19602        }
19603    }
19604
19605    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
19606            boolean fgRequired, String callingPackage, int userId)
19607            throws TransactionTooLargeException {
19608        synchronized(this) {
19609            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
19610                    "startServiceInPackage: " + service + " type=" + resolvedType);
19611            final long origId = Binder.clearCallingIdentity();
19612            ComponentName res;
19613            try {
19614                res = mServices.startServiceLocked(null, service,
19615                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
19616            } finally {
19617                Binder.restoreCallingIdentity(origId);
19618            }
19619            return res;
19620        }
19621    }
19622
19623    @Override
19624    public int stopService(IApplicationThread caller, Intent service,
19625            String resolvedType, int userId) {
19626        enforceNotIsolatedCaller("stopService");
19627        // Refuse possible leaked file descriptors
19628        if (service != null && service.hasFileDescriptors() == true) {
19629            throw new IllegalArgumentException("File descriptors passed in Intent");
19630        }
19631
19632        synchronized(this) {
19633            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
19634        }
19635    }
19636
19637    @Override
19638    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
19639        enforceNotIsolatedCaller("peekService");
19640        // Refuse possible leaked file descriptors
19641        if (service != null && service.hasFileDescriptors() == true) {
19642            throw new IllegalArgumentException("File descriptors passed in Intent");
19643        }
19644
19645        if (callingPackage == null) {
19646            throw new IllegalArgumentException("callingPackage cannot be null");
19647        }
19648
19649        synchronized(this) {
19650            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
19651        }
19652    }
19653
19654    @Override
19655    public boolean stopServiceToken(ComponentName className, IBinder token,
19656            int startId) {
19657        synchronized(this) {
19658            return mServices.stopServiceTokenLocked(className, token, startId);
19659        }
19660    }
19661
19662    @Override
19663    public void setServiceForeground(ComponentName className, IBinder token,
19664            int id, Notification notification, int flags) {
19665        synchronized(this) {
19666            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
19667        }
19668    }
19669
19670    @Override
19671    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
19672            boolean requireFull, String name, String callerPackage) {
19673        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
19674                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
19675    }
19676
19677    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
19678            String className, int flags) {
19679        boolean result = false;
19680        // For apps that don't have pre-defined UIDs, check for permission
19681        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
19682            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
19683                if (ActivityManager.checkUidPermission(
19684                        INTERACT_ACROSS_USERS,
19685                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
19686                    ComponentName comp = new ComponentName(aInfo.packageName, className);
19687                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
19688                            + " requests FLAG_SINGLE_USER, but app does not hold "
19689                            + INTERACT_ACROSS_USERS;
19690                    Slog.w(TAG, msg);
19691                    throw new SecurityException(msg);
19692                }
19693                // Permission passed
19694                result = true;
19695            }
19696        } else if ("system".equals(componentProcessName)) {
19697            result = true;
19698        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
19699            // Phone app and persistent apps are allowed to export singleuser providers.
19700            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
19701                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
19702        }
19703        if (DEBUG_MU) Slog.v(TAG_MU,
19704                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
19705                + Integer.toHexString(flags) + ") = " + result);
19706        return result;
19707    }
19708
19709    /**
19710     * Checks to see if the caller is in the same app as the singleton
19711     * component, or the component is in a special app. It allows special apps
19712     * to export singleton components but prevents exporting singleton
19713     * components for regular apps.
19714     */
19715    boolean isValidSingletonCall(int callingUid, int componentUid) {
19716        int componentAppId = UserHandle.getAppId(componentUid);
19717        return UserHandle.isSameApp(callingUid, componentUid)
19718                || componentAppId == SYSTEM_UID
19719                || componentAppId == PHONE_UID
19720                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
19721                        == PackageManager.PERMISSION_GRANTED;
19722    }
19723
19724    public int bindService(IApplicationThread caller, IBinder token, Intent service,
19725            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
19726            int userId) throws TransactionTooLargeException {
19727        enforceNotIsolatedCaller("bindService");
19728
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        synchronized(this) {
19739            return mServices.bindServiceLocked(caller, token, service,
19740                    resolvedType, connection, flags, callingPackage, userId);
19741        }
19742    }
19743
19744    public boolean unbindService(IServiceConnection connection) {
19745        synchronized (this) {
19746            return mServices.unbindServiceLocked(connection);
19747        }
19748    }
19749
19750    public void publishService(IBinder token, Intent intent, IBinder service) {
19751        // Refuse possible leaked file descriptors
19752        if (intent != null && intent.hasFileDescriptors() == true) {
19753            throw new IllegalArgumentException("File descriptors passed in Intent");
19754        }
19755
19756        synchronized(this) {
19757            if (!(token instanceof ServiceRecord)) {
19758                throw new IllegalArgumentException("Invalid service token");
19759            }
19760            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
19761        }
19762    }
19763
19764    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
19765        // Refuse possible leaked file descriptors
19766        if (intent != null && intent.hasFileDescriptors() == true) {
19767            throw new IllegalArgumentException("File descriptors passed in Intent");
19768        }
19769
19770        synchronized(this) {
19771            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
19772        }
19773    }
19774
19775    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
19776        synchronized(this) {
19777            if (!(token instanceof ServiceRecord)) {
19778                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
19779                throw new IllegalArgumentException("Invalid service token");
19780            }
19781            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
19782        }
19783    }
19784
19785    // =========================================================
19786    // BACKUP AND RESTORE
19787    // =========================================================
19788
19789    // Cause the target app to be launched if necessary and its backup agent
19790    // instantiated.  The backup agent will invoke backupAgentCreated() on the
19791    // activity manager to announce its creation.
19792    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
19793        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
19794        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
19795
19796        IPackageManager pm = AppGlobals.getPackageManager();
19797        ApplicationInfo app = null;
19798        try {
19799            app = pm.getApplicationInfo(packageName, 0, userId);
19800        } catch (RemoteException e) {
19801            // can't happen; package manager is process-local
19802        }
19803        if (app == null) {
19804            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
19805            return false;
19806        }
19807
19808        int oldBackupUid;
19809        int newBackupUid;
19810
19811        synchronized(this) {
19812            // !!! TODO: currently no check here that we're already bound
19813            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
19814            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19815            synchronized (stats) {
19816                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
19817            }
19818
19819            // Backup agent is now in use, its package can't be stopped.
19820            try {
19821                AppGlobals.getPackageManager().setPackageStoppedState(
19822                        app.packageName, false, UserHandle.getUserId(app.uid));
19823            } catch (RemoteException e) {
19824            } catch (IllegalArgumentException e) {
19825                Slog.w(TAG, "Failed trying to unstop package "
19826                        + app.packageName + ": " + e);
19827            }
19828
19829            BackupRecord r = new BackupRecord(ss, app, backupMode);
19830            ComponentName hostingName =
19831                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
19832                            ? new ComponentName(app.packageName, app.backupAgentName)
19833                            : new ComponentName("android", "FullBackupAgent");
19834            // startProcessLocked() returns existing proc's record if it's already running
19835            ProcessRecord proc = startProcessLocked(app.processName, app,
19836                    false, 0, "backup", hostingName, false, false, false);
19837            if (proc == null) {
19838                Slog.e(TAG, "Unable to start backup agent process " + r);
19839                return false;
19840            }
19841
19842            // If the app is a regular app (uid >= 10000) and not the system server or phone
19843            // process, etc, then mark it as being in full backup so that certain calls to the
19844            // process can be blocked. This is not reset to false anywhere because we kill the
19845            // process after the full backup is done and the ProcessRecord will vaporize anyway.
19846            if (UserHandle.isApp(app.uid) &&
19847                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
19848                proc.inFullBackup = true;
19849            }
19850            r.app = proc;
19851            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
19852            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
19853            mBackupTarget = r;
19854            mBackupAppName = app.packageName;
19855
19856            // Try not to kill the process during backup
19857            updateOomAdjLocked(proc, true);
19858
19859            // If the process is already attached, schedule the creation of the backup agent now.
19860            // If it is not yet live, this will be done when it attaches to the framework.
19861            if (proc.thread != null) {
19862                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
19863                try {
19864                    proc.thread.scheduleCreateBackupAgent(app,
19865                            compatibilityInfoForPackageLocked(app), backupMode);
19866                } catch (RemoteException e) {
19867                    // Will time out on the backup manager side
19868                }
19869            } else {
19870                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
19871            }
19872            // Invariants: at this point, the target app process exists and the application
19873            // is either already running or in the process of coming up.  mBackupTarget and
19874            // mBackupAppName describe the app, so that when it binds back to the AM we
19875            // know that it's scheduled for a backup-agent operation.
19876        }
19877
19878        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
19879        if (oldBackupUid != -1) {
19880            js.removeBackingUpUid(oldBackupUid);
19881        }
19882        if (newBackupUid != -1) {
19883            js.addBackingUpUid(newBackupUid);
19884        }
19885
19886        return true;
19887    }
19888
19889    @Override
19890    public void clearPendingBackup() {
19891        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
19892        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
19893
19894        synchronized (this) {
19895            mBackupTarget = null;
19896            mBackupAppName = null;
19897        }
19898
19899        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
19900        js.clearAllBackingUpUids();
19901    }
19902
19903    // A backup agent has just come up
19904    public void backupAgentCreated(String agentPackageName, IBinder agent) {
19905        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
19906                + " = " + agent);
19907
19908        synchronized(this) {
19909            if (!agentPackageName.equals(mBackupAppName)) {
19910                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
19911                return;
19912            }
19913        }
19914
19915        long oldIdent = Binder.clearCallingIdentity();
19916        try {
19917            IBackupManager bm = IBackupManager.Stub.asInterface(
19918                    ServiceManager.getService(Context.BACKUP_SERVICE));
19919            bm.agentConnected(agentPackageName, agent);
19920        } catch (RemoteException e) {
19921            // can't happen; the backup manager service is local
19922        } catch (Exception e) {
19923            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
19924            e.printStackTrace();
19925        } finally {
19926            Binder.restoreCallingIdentity(oldIdent);
19927        }
19928    }
19929
19930    // done with this agent
19931    public void unbindBackupAgent(ApplicationInfo appInfo) {
19932        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
19933        if (appInfo == null) {
19934            Slog.w(TAG, "unbind backup agent for null app");
19935            return;
19936        }
19937
19938        int oldBackupUid;
19939
19940        synchronized(this) {
19941            try {
19942                if (mBackupAppName == null) {
19943                    Slog.w(TAG, "Unbinding backup agent with no active backup");
19944                    return;
19945                }
19946
19947                if (!mBackupAppName.equals(appInfo.packageName)) {
19948                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
19949                    return;
19950                }
19951
19952                // Not backing this app up any more; reset its OOM adjustment
19953                final ProcessRecord proc = mBackupTarget.app;
19954                updateOomAdjLocked(proc, true);
19955                proc.inFullBackup = false;
19956
19957                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
19958
19959                // If the app crashed during backup, 'thread' will be null here
19960                if (proc.thread != null) {
19961                    try {
19962                        proc.thread.scheduleDestroyBackupAgent(appInfo,
19963                                compatibilityInfoForPackageLocked(appInfo));
19964                    } catch (Exception e) {
19965                        Slog.e(TAG, "Exception when unbinding backup agent:");
19966                        e.printStackTrace();
19967                    }
19968                }
19969            } finally {
19970                mBackupTarget = null;
19971                mBackupAppName = null;
19972            }
19973        }
19974
19975        if (oldBackupUid != -1) {
19976            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
19977            js.removeBackingUpUid(oldBackupUid);
19978        }
19979    }
19980
19981    // =========================================================
19982    // BROADCASTS
19983    // =========================================================
19984
19985    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
19986        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
19987            return false;
19988        }
19989        // Easy case -- we have the app's ProcessRecord.
19990        if (record != null) {
19991            return record.info.isInstantApp();
19992        }
19993        // Otherwise check with PackageManager.
19994        if (callerPackage == null) {
19995            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
19996            throw new IllegalArgumentException("Calling application did not provide package name");
19997        }
19998        mAppOpsService.checkPackage(uid, callerPackage);
19999        try {
20000            IPackageManager pm = AppGlobals.getPackageManager();
20001            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
20002        } catch (RemoteException e) {
20003            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
20004            return true;
20005        }
20006    }
20007
20008    boolean isPendingBroadcastProcessLocked(int pid) {
20009        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20010                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
20011    }
20012
20013    void skipPendingBroadcastLocked(int pid) {
20014            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
20015            for (BroadcastQueue queue : mBroadcastQueues) {
20016                queue.skipPendingBroadcastLocked(pid);
20017            }
20018    }
20019
20020    // The app just attached; send any pending broadcasts that it should receive
20021    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
20022        boolean didSomething = false;
20023        for (BroadcastQueue queue : mBroadcastQueues) {
20024            didSomething |= queue.sendPendingBroadcastsLocked(app);
20025        }
20026        return didSomething;
20027    }
20028
20029    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20030            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
20031            int flags) {
20032        enforceNotIsolatedCaller("registerReceiver");
20033        ArrayList<Intent> stickyIntents = null;
20034        ProcessRecord callerApp = null;
20035        final boolean visibleToInstantApps
20036                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
20037        int callingUid;
20038        int callingPid;
20039        boolean instantApp;
20040        synchronized(this) {
20041            if (caller != null) {
20042                callerApp = getRecordForAppLocked(caller);
20043                if (callerApp == null) {
20044                    throw new SecurityException(
20045                            "Unable to find app for caller " + caller
20046                            + " (pid=" + Binder.getCallingPid()
20047                            + ") when registering receiver " + receiver);
20048                }
20049                if (callerApp.info.uid != SYSTEM_UID &&
20050                        !callerApp.pkgList.containsKey(callerPackage) &&
20051                        !"android".equals(callerPackage)) {
20052                    throw new SecurityException("Given caller package " + callerPackage
20053                            + " is not running in process " + callerApp);
20054                }
20055                callingUid = callerApp.info.uid;
20056                callingPid = callerApp.pid;
20057            } else {
20058                callerPackage = null;
20059                callingUid = Binder.getCallingUid();
20060                callingPid = Binder.getCallingPid();
20061            }
20062
20063            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20064            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20065                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
20066
20067            Iterator<String> actions = filter.actionsIterator();
20068            if (actions == null) {
20069                ArrayList<String> noAction = new ArrayList<String>(1);
20070                noAction.add(null);
20071                actions = noAction.iterator();
20072            }
20073
20074            // Collect stickies of users
20075            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
20076            while (actions.hasNext()) {
20077                String action = actions.next();
20078                for (int id : userIds) {
20079                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
20080                    if (stickies != null) {
20081                        ArrayList<Intent> intents = stickies.get(action);
20082                        if (intents != null) {
20083                            if (stickyIntents == null) {
20084                                stickyIntents = new ArrayList<Intent>();
20085                            }
20086                            stickyIntents.addAll(intents);
20087                        }
20088                    }
20089                }
20090            }
20091        }
20092
20093        ArrayList<Intent> allSticky = null;
20094        if (stickyIntents != null) {
20095            final ContentResolver resolver = mContext.getContentResolver();
20096            // Look for any matching sticky broadcasts...
20097            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
20098                Intent intent = stickyIntents.get(i);
20099                // Don't provided intents that aren't available to instant apps.
20100                if (instantApp &&
20101                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
20102                    continue;
20103                }
20104                // If intent has scheme "content", it will need to acccess
20105                // provider that needs to lock mProviderMap in ActivityThread
20106                // and also it may need to wait application response, so we
20107                // cannot lock ActivityManagerService here.
20108                if (filter.match(resolver, intent, true, TAG) >= 0) {
20109                    if (allSticky == null) {
20110                        allSticky = new ArrayList<Intent>();
20111                    }
20112                    allSticky.add(intent);
20113                }
20114            }
20115        }
20116
20117        // The first sticky in the list is returned directly back to the client.
20118        Intent sticky = allSticky != null ? allSticky.get(0) : null;
20119        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
20120        if (receiver == null) {
20121            return sticky;
20122        }
20123
20124        synchronized (this) {
20125            if (callerApp != null && (callerApp.thread == null
20126                    || callerApp.thread.asBinder() != caller.asBinder())) {
20127                // Original caller already died
20128                return null;
20129            }
20130            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20131            if (rl == null) {
20132                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
20133                        userId, receiver);
20134                if (rl.app != null) {
20135                    rl.app.receivers.add(rl);
20136                } else {
20137                    try {
20138                        receiver.asBinder().linkToDeath(rl, 0);
20139                    } catch (RemoteException e) {
20140                        return sticky;
20141                    }
20142                    rl.linkedToDeath = true;
20143                }
20144                mRegisteredReceivers.put(receiver.asBinder(), rl);
20145            } else if (rl.uid != callingUid) {
20146                throw new IllegalArgumentException(
20147                        "Receiver requested to register for uid " + callingUid
20148                        + " was previously registered for uid " + rl.uid
20149                        + " callerPackage is " + callerPackage);
20150            } else if (rl.pid != callingPid) {
20151                throw new IllegalArgumentException(
20152                        "Receiver requested to register for pid " + callingPid
20153                        + " was previously registered for pid " + rl.pid
20154                        + " callerPackage is " + callerPackage);
20155            } else if (rl.userId != userId) {
20156                throw new IllegalArgumentException(
20157                        "Receiver requested to register for user " + userId
20158                        + " was previously registered for user " + rl.userId
20159                        + " callerPackage is " + callerPackage);
20160            }
20161            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
20162                    permission, callingUid, userId, instantApp, visibleToInstantApps);
20163            rl.add(bf);
20164            if (!bf.debugCheck()) {
20165                Slog.w(TAG, "==> For Dynamic broadcast");
20166            }
20167            mReceiverResolver.addFilter(bf);
20168
20169            // Enqueue broadcasts for all existing stickies that match
20170            // this filter.
20171            if (allSticky != null) {
20172                ArrayList receivers = new ArrayList();
20173                receivers.add(bf);
20174
20175                final int stickyCount = allSticky.size();
20176                for (int i = 0; i < stickyCount; i++) {
20177                    Intent intent = allSticky.get(i);
20178                    BroadcastQueue queue = broadcastQueueForIntent(intent);
20179                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
20180                            null, -1, -1, false, null, null, OP_NONE, null, receivers,
20181                            null, 0, null, null, false, true, true, -1);
20182                    queue.enqueueParallelBroadcastLocked(r);
20183                    queue.scheduleBroadcastsLocked();
20184                }
20185            }
20186
20187            return sticky;
20188        }
20189    }
20190
20191    public void unregisterReceiver(IIntentReceiver receiver) {
20192        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
20193
20194        final long origId = Binder.clearCallingIdentity();
20195        try {
20196            boolean doTrim = false;
20197
20198            synchronized(this) {
20199                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20200                if (rl != null) {
20201                    final BroadcastRecord r = rl.curBroadcast;
20202                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
20203                        final boolean doNext = r.queue.finishReceiverLocked(
20204                                r, r.resultCode, r.resultData, r.resultExtras,
20205                                r.resultAbort, false);
20206                        if (doNext) {
20207                            doTrim = true;
20208                            r.queue.processNextBroadcast(false);
20209                        }
20210                    }
20211
20212                    if (rl.app != null) {
20213                        rl.app.receivers.remove(rl);
20214                    }
20215                    removeReceiverLocked(rl);
20216                    if (rl.linkedToDeath) {
20217                        rl.linkedToDeath = false;
20218                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
20219                    }
20220                }
20221            }
20222
20223            // If we actually concluded any broadcasts, we might now be able
20224            // to trim the recipients' apps from our working set
20225            if (doTrim) {
20226                trimApplications();
20227                return;
20228            }
20229
20230        } finally {
20231            Binder.restoreCallingIdentity(origId);
20232        }
20233    }
20234
20235    void removeReceiverLocked(ReceiverList rl) {
20236        mRegisteredReceivers.remove(rl.receiver.asBinder());
20237        for (int i = rl.size() - 1; i >= 0; i--) {
20238            mReceiverResolver.removeFilter(rl.get(i));
20239        }
20240    }
20241
20242    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
20243        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20244            ProcessRecord r = mLruProcesses.get(i);
20245            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
20246                try {
20247                    r.thread.dispatchPackageBroadcast(cmd, packages);
20248                } catch (RemoteException ex) {
20249                }
20250            }
20251        }
20252    }
20253
20254    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
20255            int callingUid, int[] users) {
20256        // TODO: come back and remove this assumption to triage all broadcasts
20257        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
20258
20259        List<ResolveInfo> receivers = null;
20260        try {
20261            HashSet<ComponentName> singleUserReceivers = null;
20262            boolean scannedFirstReceivers = false;
20263            for (int user : users) {
20264                // Skip users that have Shell restrictions, with exception of always permitted
20265                // Shell broadcasts
20266                if (callingUid == SHELL_UID
20267                        && mUserController.hasUserRestriction(
20268                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
20269                        && !isPermittedShellBroadcast(intent)) {
20270                    continue;
20271                }
20272                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
20273                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
20274                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
20275                    // If this is not the system user, we need to check for
20276                    // any receivers that should be filtered out.
20277                    for (int i=0; i<newReceivers.size(); i++) {
20278                        ResolveInfo ri = newReceivers.get(i);
20279                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
20280                            newReceivers.remove(i);
20281                            i--;
20282                        }
20283                    }
20284                }
20285                if (newReceivers != null && newReceivers.size() == 0) {
20286                    newReceivers = null;
20287                }
20288                if (receivers == null) {
20289                    receivers = newReceivers;
20290                } else if (newReceivers != null) {
20291                    // We need to concatenate the additional receivers
20292                    // found with what we have do far.  This would be easy,
20293                    // but we also need to de-dup any receivers that are
20294                    // singleUser.
20295                    if (!scannedFirstReceivers) {
20296                        // Collect any single user receivers we had already retrieved.
20297                        scannedFirstReceivers = true;
20298                        for (int i=0; i<receivers.size(); i++) {
20299                            ResolveInfo ri = receivers.get(i);
20300                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20301                                ComponentName cn = new ComponentName(
20302                                        ri.activityInfo.packageName, ri.activityInfo.name);
20303                                if (singleUserReceivers == null) {
20304                                    singleUserReceivers = new HashSet<ComponentName>();
20305                                }
20306                                singleUserReceivers.add(cn);
20307                            }
20308                        }
20309                    }
20310                    // Add the new results to the existing results, tracking
20311                    // and de-dupping single user receivers.
20312                    for (int i=0; i<newReceivers.size(); i++) {
20313                        ResolveInfo ri = newReceivers.get(i);
20314                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20315                            ComponentName cn = new ComponentName(
20316                                    ri.activityInfo.packageName, ri.activityInfo.name);
20317                            if (singleUserReceivers == null) {
20318                                singleUserReceivers = new HashSet<ComponentName>();
20319                            }
20320                            if (!singleUserReceivers.contains(cn)) {
20321                                singleUserReceivers.add(cn);
20322                                receivers.add(ri);
20323                            }
20324                        } else {
20325                            receivers.add(ri);
20326                        }
20327                    }
20328                }
20329            }
20330        } catch (RemoteException ex) {
20331            // pm is in same process, this will never happen.
20332        }
20333        return receivers;
20334    }
20335
20336    private boolean isPermittedShellBroadcast(Intent intent) {
20337        // remote bugreport should always be allowed to be taken
20338        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
20339    }
20340
20341    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
20342            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
20343        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
20344            // Don't yell about broadcasts sent via shell
20345            return;
20346        }
20347
20348        final String action = intent.getAction();
20349        if (isProtectedBroadcast
20350                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
20351                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
20352                || Intent.ACTION_MEDIA_BUTTON.equals(action)
20353                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
20354                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
20355                || Intent.ACTION_MASTER_CLEAR.equals(action)
20356                || Intent.ACTION_FACTORY_RESET.equals(action)
20357                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20358                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
20359                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
20360                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
20361                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
20362                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
20363                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
20364            // Broadcast is either protected, or it's a public action that
20365            // we've relaxed, so it's fine for system internals to send.
20366            return;
20367        }
20368
20369        // This broadcast may be a problem...  but there are often system components that
20370        // want to send an internal broadcast to themselves, which is annoying to have to
20371        // explicitly list each action as a protected broadcast, so we will check for that
20372        // one safe case and allow it: an explicit broadcast, only being received by something
20373        // that has protected itself.
20374        if (receivers != null && receivers.size() > 0
20375                && (intent.getPackage() != null || intent.getComponent() != null)) {
20376            boolean allProtected = true;
20377            for (int i = receivers.size()-1; i >= 0; i--) {
20378                Object target = receivers.get(i);
20379                if (target instanceof ResolveInfo) {
20380                    ResolveInfo ri = (ResolveInfo)target;
20381                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
20382                        allProtected = false;
20383                        break;
20384                    }
20385                } else {
20386                    BroadcastFilter bf = (BroadcastFilter)target;
20387                    if (bf.requiredPermission == null) {
20388                        allProtected = false;
20389                        break;
20390                    }
20391                }
20392            }
20393            if (allProtected) {
20394                // All safe!
20395                return;
20396            }
20397        }
20398
20399        // The vast majority of broadcasts sent from system internals
20400        // should be protected to avoid security holes, so yell loudly
20401        // to ensure we examine these cases.
20402        if (callerApp != null) {
20403            Log.wtf(TAG, "Sending non-protected broadcast " + action
20404                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
20405                    new Throwable());
20406        } else {
20407            Log.wtf(TAG, "Sending non-protected broadcast " + action
20408                            + " from system uid " + UserHandle.formatUid(callingUid)
20409                            + " pkg " + callerPackage,
20410                    new Throwable());
20411        }
20412    }
20413
20414    final int broadcastIntentLocked(ProcessRecord callerApp,
20415            String callerPackage, Intent intent, String resolvedType,
20416            IIntentReceiver resultTo, int resultCode, String resultData,
20417            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
20418            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
20419        intent = new Intent(intent);
20420
20421        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
20422        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
20423        if (callerInstantApp) {
20424            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20425        }
20426
20427        // By default broadcasts do not go to stopped apps.
20428        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
20429
20430        // If we have not finished booting, don't allow this to launch new processes.
20431        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
20432            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20433        }
20434
20435        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
20436                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
20437                + " ordered=" + ordered + " userid=" + userId);
20438        if ((resultTo != null) && !ordered) {
20439            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
20440        }
20441
20442        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20443                ALLOW_NON_FULL, "broadcast", callerPackage);
20444
20445        // Make sure that the user who is receiving this broadcast or its parent is running.
20446        // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
20447        if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
20448            if ((callingUid != SYSTEM_UID
20449                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
20450                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
20451                Slog.w(TAG, "Skipping broadcast of " + intent
20452                        + ": user " + userId + " and its parent (if any) are stopped");
20453                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
20454            }
20455        }
20456
20457        BroadcastOptions brOptions = null;
20458        if (bOptions != null) {
20459            brOptions = new BroadcastOptions(bOptions);
20460            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
20461                // See if the caller is allowed to do this.  Note we are checking against
20462                // the actual real caller (not whoever provided the operation as say a
20463                // PendingIntent), because that who is actually supplied the arguments.
20464                if (checkComponentPermission(
20465                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
20466                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
20467                        != PackageManager.PERMISSION_GRANTED) {
20468                    String msg = "Permission Denial: " + intent.getAction()
20469                            + " broadcast from " + callerPackage + " (pid=" + callingPid
20470                            + ", uid=" + callingUid + ")"
20471                            + " requires "
20472                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
20473                    Slog.w(TAG, msg);
20474                    throw new SecurityException(msg);
20475                }
20476            }
20477        }
20478
20479        // Verify that protected broadcasts are only being sent by system code,
20480        // and that system code is only sending protected broadcasts.
20481        final String action = intent.getAction();
20482        final boolean isProtectedBroadcast;
20483        try {
20484            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
20485        } catch (RemoteException e) {
20486            Slog.w(TAG, "Remote exception", e);
20487            return ActivityManager.BROADCAST_SUCCESS;
20488        }
20489
20490        final boolean isCallerSystem;
20491        switch (UserHandle.getAppId(callingUid)) {
20492            case ROOT_UID:
20493            case SYSTEM_UID:
20494            case PHONE_UID:
20495            case BLUETOOTH_UID:
20496            case NFC_UID:
20497                isCallerSystem = true;
20498                break;
20499            default:
20500                isCallerSystem = (callerApp != null) && callerApp.persistent;
20501                break;
20502        }
20503
20504        // First line security check before anything else: stop non-system apps from
20505        // sending protected broadcasts.
20506        if (!isCallerSystem) {
20507            if (isProtectedBroadcast) {
20508                String msg = "Permission Denial: not allowed to send broadcast "
20509                        + action + " from pid="
20510                        + callingPid + ", uid=" + callingUid;
20511                Slog.w(TAG, msg);
20512                throw new SecurityException(msg);
20513
20514            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20515                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
20516                // Special case for compatibility: we don't want apps to send this,
20517                // but historically it has not been protected and apps may be using it
20518                // to poke their own app widget.  So, instead of making it protected,
20519                // just limit it to the caller.
20520                if (callerPackage == null) {
20521                    String msg = "Permission Denial: not allowed to send broadcast "
20522                            + action + " from unknown caller.";
20523                    Slog.w(TAG, msg);
20524                    throw new SecurityException(msg);
20525                } else if (intent.getComponent() != null) {
20526                    // They are good enough to send to an explicit component...  verify
20527                    // it is being sent to the calling app.
20528                    if (!intent.getComponent().getPackageName().equals(
20529                            callerPackage)) {
20530                        String msg = "Permission Denial: not allowed to send broadcast "
20531                                + action + " to "
20532                                + intent.getComponent().getPackageName() + " from "
20533                                + callerPackage;
20534                        Slog.w(TAG, msg);
20535                        throw new SecurityException(msg);
20536                    }
20537                } else {
20538                    // Limit broadcast to their own package.
20539                    intent.setPackage(callerPackage);
20540                }
20541            }
20542        }
20543
20544        if (action != null) {
20545            if (getBackgroundLaunchBroadcasts().contains(action)) {
20546                if (DEBUG_BACKGROUND_CHECK) {
20547                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
20548                }
20549                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
20550            }
20551
20552            switch (action) {
20553                case Intent.ACTION_UID_REMOVED:
20554                case Intent.ACTION_PACKAGE_REMOVED:
20555                case Intent.ACTION_PACKAGE_CHANGED:
20556                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
20557                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
20558                case Intent.ACTION_PACKAGES_SUSPENDED:
20559                case Intent.ACTION_PACKAGES_UNSUSPENDED:
20560                    // Handle special intents: if this broadcast is from the package
20561                    // manager about a package being removed, we need to remove all of
20562                    // its activities from the history stack.
20563                    if (checkComponentPermission(
20564                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
20565                            callingPid, callingUid, -1, true)
20566                            != PackageManager.PERMISSION_GRANTED) {
20567                        String msg = "Permission Denial: " + intent.getAction()
20568                                + " broadcast from " + callerPackage + " (pid=" + callingPid
20569                                + ", uid=" + callingUid + ")"
20570                                + " requires "
20571                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
20572                        Slog.w(TAG, msg);
20573                        throw new SecurityException(msg);
20574                    }
20575                    switch (action) {
20576                        case Intent.ACTION_UID_REMOVED:
20577                            final int uid = getUidFromIntent(intent);
20578                            if (uid >= 0) {
20579                                mBatteryStatsService.removeUid(uid);
20580                                mAppOpsService.uidRemoved(uid);
20581                            }
20582                            break;
20583                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
20584                            // If resources are unavailable just force stop all those packages
20585                            // and flush the attribute cache as well.
20586                            String list[] =
20587                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
20588                            if (list != null && list.length > 0) {
20589                                for (int i = 0; i < list.length; i++) {
20590                                    forceStopPackageLocked(list[i], -1, false, true, true,
20591                                            false, false, userId, "storage unmount");
20592                                }
20593                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
20594                                sendPackageBroadcastLocked(
20595                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
20596                                        list, userId);
20597                            }
20598                            break;
20599                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
20600                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
20601                            break;
20602                        case Intent.ACTION_PACKAGE_REMOVED:
20603                        case Intent.ACTION_PACKAGE_CHANGED:
20604                            Uri data = intent.getData();
20605                            String ssp;
20606                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
20607                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
20608                                final boolean replacing =
20609                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
20610                                final boolean killProcess =
20611                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
20612                                final boolean fullUninstall = removed && !replacing;
20613                                if (removed) {
20614                                    if (killProcess) {
20615                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
20616                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
20617                                                false, true, true, false, fullUninstall, userId,
20618                                                removed ? "pkg removed" : "pkg changed");
20619                                    }
20620                                    final int cmd = killProcess
20621                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
20622                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
20623                                    sendPackageBroadcastLocked(cmd,
20624                                            new String[] {ssp}, userId);
20625                                    if (fullUninstall) {
20626                                        mAppOpsService.packageRemoved(
20627                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
20628
20629                                        // Remove all permissions granted from/to this package
20630                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
20631
20632                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
20633
20634                                        mServices.forceStopPackageLocked(ssp, userId);
20635                                        mAppWarnings.onPackageUninstalled(ssp);
20636                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
20637                                        mBatteryStatsService.notePackageUninstalled(ssp);
20638                                    }
20639                                } else {
20640                                    if (killProcess) {
20641                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
20642                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
20643                                                userId, ProcessList.INVALID_ADJ,
20644                                                false, true, true, false, "change " + ssp);
20645                                    }
20646                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
20647                                            intent.getStringArrayExtra(
20648                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
20649                                }
20650                            }
20651                            break;
20652                        case Intent.ACTION_PACKAGES_SUSPENDED:
20653                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
20654                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
20655                                    intent.getAction());
20656                            final String[] packageNames = intent.getStringArrayExtra(
20657                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
20658                            final int userHandle = intent.getIntExtra(
20659                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
20660
20661                            synchronized(ActivityManagerService.this) {
20662                                mRecentTasks.onPackagesSuspendedChanged(
20663                                        packageNames, suspended, userHandle);
20664                            }
20665                            break;
20666                    }
20667                    break;
20668                case Intent.ACTION_PACKAGE_REPLACED:
20669                {
20670                    final Uri data = intent.getData();
20671                    final String ssp;
20672                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20673                        ApplicationInfo aInfo = null;
20674                        try {
20675                            aInfo = AppGlobals.getPackageManager()
20676                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
20677                        } catch (RemoteException ignore) {}
20678                        if (aInfo == null) {
20679                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
20680                                    + " ssp=" + ssp + " data=" + data);
20681                            return ActivityManager.BROADCAST_SUCCESS;
20682                        }
20683                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
20684                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
20685                                new String[] {ssp}, userId);
20686                    }
20687                    break;
20688                }
20689                case Intent.ACTION_PACKAGE_ADDED:
20690                {
20691                    // Special case for adding a package: by default turn on compatibility mode.
20692                    Uri data = intent.getData();
20693                    String ssp;
20694                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20695                        final boolean replacing =
20696                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
20697                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
20698
20699                        try {
20700                            ApplicationInfo ai = AppGlobals.getPackageManager().
20701                                    getApplicationInfo(ssp, 0, 0);
20702                            mBatteryStatsService.notePackageInstalled(ssp,
20703                                    ai != null ? ai.versionCode : 0);
20704                        } catch (RemoteException e) {
20705                        }
20706                    }
20707                    break;
20708                }
20709                case Intent.ACTION_PACKAGE_DATA_CLEARED:
20710                {
20711                    Uri data = intent.getData();
20712                    String ssp;
20713                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20714                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
20715                        mAppWarnings.onPackageDataCleared(ssp);
20716                    }
20717                    break;
20718                }
20719                case Intent.ACTION_TIMEZONE_CHANGED:
20720                    // If this is the time zone changed action, queue up a message that will reset
20721                    // the timezone of all currently running processes. This message will get
20722                    // queued up before the broadcast happens.
20723                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
20724                    break;
20725                case Intent.ACTION_TIME_CHANGED:
20726                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
20727                    // the tri-state value it may contain and "unknown".
20728                    // For convenience we re-use the Intent extra values.
20729                    final int NO_EXTRA_VALUE_FOUND = -1;
20730                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
20731                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
20732                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
20733                    // Only send a message if the time preference is available.
20734                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
20735                        Message updateTimePreferenceMsg =
20736                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
20737                                        timeFormatPreferenceMsgValue, 0);
20738                        mHandler.sendMessage(updateTimePreferenceMsg);
20739                    }
20740                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20741                    synchronized (stats) {
20742                        stats.noteCurrentTimeChangedLocked();
20743                    }
20744                    break;
20745                case Intent.ACTION_CLEAR_DNS_CACHE:
20746                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
20747                    break;
20748                case Proxy.PROXY_CHANGE_ACTION:
20749                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
20750                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
20751                    break;
20752                case android.hardware.Camera.ACTION_NEW_PICTURE:
20753                case android.hardware.Camera.ACTION_NEW_VIDEO:
20754                    // In N we just turned these off; in O we are turing them back on partly,
20755                    // only for registered receivers.  This will still address the main problem
20756                    // (a spam of apps waking up when a picture is taken putting significant
20757                    // memory pressure on the system at a bad point), while still allowing apps
20758                    // that are already actively running to know about this happening.
20759                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20760                    break;
20761                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
20762                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
20763                    break;
20764                case "com.android.launcher.action.INSTALL_SHORTCUT":
20765                    // As of O, we no longer support this broadcasts, even for pre-O apps.
20766                    // Apps should now be using ShortcutManager.pinRequestShortcut().
20767                    Log.w(TAG, "Broadcast " + action
20768                            + " no longer supported. It will not be delivered.");
20769                    return ActivityManager.BROADCAST_SUCCESS;
20770            }
20771
20772            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
20773                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
20774                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
20775                final int uid = getUidFromIntent(intent);
20776                if (uid != -1) {
20777                    final UidRecord uidRec = mActiveUids.get(uid);
20778                    if (uidRec != null) {
20779                        uidRec.updateHasInternetPermission();
20780                    }
20781                }
20782            }
20783        }
20784
20785        // Add to the sticky list if requested.
20786        if (sticky) {
20787            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
20788                    callingPid, callingUid)
20789                    != PackageManager.PERMISSION_GRANTED) {
20790                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
20791                        + callingPid + ", uid=" + callingUid
20792                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
20793                Slog.w(TAG, msg);
20794                throw new SecurityException(msg);
20795            }
20796            if (requiredPermissions != null && requiredPermissions.length > 0) {
20797                Slog.w(TAG, "Can't broadcast sticky intent " + intent
20798                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
20799                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
20800            }
20801            if (intent.getComponent() != null) {
20802                throw new SecurityException(
20803                        "Sticky broadcasts can't target a specific component");
20804            }
20805            // We use userId directly here, since the "all" target is maintained
20806            // as a separate set of sticky broadcasts.
20807            if (userId != UserHandle.USER_ALL) {
20808                // But first, if this is not a broadcast to all users, then
20809                // make sure it doesn't conflict with an existing broadcast to
20810                // all users.
20811                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
20812                        UserHandle.USER_ALL);
20813                if (stickies != null) {
20814                    ArrayList<Intent> list = stickies.get(intent.getAction());
20815                    if (list != null) {
20816                        int N = list.size();
20817                        int i;
20818                        for (i=0; i<N; i++) {
20819                            if (intent.filterEquals(list.get(i))) {
20820                                throw new IllegalArgumentException(
20821                                        "Sticky broadcast " + intent + " for user "
20822                                        + userId + " conflicts with existing global broadcast");
20823                            }
20824                        }
20825                    }
20826                }
20827            }
20828            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
20829            if (stickies == null) {
20830                stickies = new ArrayMap<>();
20831                mStickyBroadcasts.put(userId, stickies);
20832            }
20833            ArrayList<Intent> list = stickies.get(intent.getAction());
20834            if (list == null) {
20835                list = new ArrayList<>();
20836                stickies.put(intent.getAction(), list);
20837            }
20838            final int stickiesCount = list.size();
20839            int i;
20840            for (i = 0; i < stickiesCount; i++) {
20841                if (intent.filterEquals(list.get(i))) {
20842                    // This sticky already exists, replace it.
20843                    list.set(i, new Intent(intent));
20844                    break;
20845                }
20846            }
20847            if (i >= stickiesCount) {
20848                list.add(new Intent(intent));
20849            }
20850        }
20851
20852        int[] users;
20853        if (userId == UserHandle.USER_ALL) {
20854            // Caller wants broadcast to go to all started users.
20855            users = mUserController.getStartedUserArray();
20856        } else {
20857            // Caller wants broadcast to go to one specific user.
20858            users = new int[] {userId};
20859        }
20860
20861        // Figure out who all will receive this broadcast.
20862        List receivers = null;
20863        List<BroadcastFilter> registeredReceivers = null;
20864        // Need to resolve the intent to interested receivers...
20865        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
20866                 == 0) {
20867            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
20868        }
20869        if (intent.getComponent() == null) {
20870            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
20871                // Query one target user at a time, excluding shell-restricted users
20872                for (int i = 0; i < users.length; i++) {
20873                    if (mUserController.hasUserRestriction(
20874                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
20875                        continue;
20876                    }
20877                    List<BroadcastFilter> registeredReceiversForUser =
20878                            mReceiverResolver.queryIntent(intent,
20879                                    resolvedType, false /*defaultOnly*/, users[i]);
20880                    if (registeredReceivers == null) {
20881                        registeredReceivers = registeredReceiversForUser;
20882                    } else if (registeredReceiversForUser != null) {
20883                        registeredReceivers.addAll(registeredReceiversForUser);
20884                    }
20885                }
20886            } else {
20887                registeredReceivers = mReceiverResolver.queryIntent(intent,
20888                        resolvedType, false /*defaultOnly*/, userId);
20889            }
20890        }
20891
20892        final boolean replacePending =
20893                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
20894
20895        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
20896                + " replacePending=" + replacePending);
20897
20898        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
20899        if (!ordered && NR > 0) {
20900            // If we are not serializing this broadcast, then send the
20901            // registered receivers separately so they don't wait for the
20902            // components to be launched.
20903            if (isCallerSystem) {
20904                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
20905                        isProtectedBroadcast, registeredReceivers);
20906            }
20907            final BroadcastQueue queue = broadcastQueueForIntent(intent);
20908            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
20909                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
20910                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
20911                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
20912            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
20913            final boolean replaced = replacePending
20914                    && (queue.replaceParallelBroadcastLocked(r) != null);
20915            // Note: We assume resultTo is null for non-ordered broadcasts.
20916            if (!replaced) {
20917                queue.enqueueParallelBroadcastLocked(r);
20918                queue.scheduleBroadcastsLocked();
20919            }
20920            registeredReceivers = null;
20921            NR = 0;
20922        }
20923
20924        // Merge into one list.
20925        int ir = 0;
20926        if (receivers != null) {
20927            // A special case for PACKAGE_ADDED: do not allow the package
20928            // being added to see this broadcast.  This prevents them from
20929            // using this as a back door to get run as soon as they are
20930            // installed.  Maybe in the future we want to have a special install
20931            // broadcast or such for apps, but we'd like to deliberately make
20932            // this decision.
20933            String skipPackages[] = null;
20934            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
20935                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
20936                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
20937                Uri data = intent.getData();
20938                if (data != null) {
20939                    String pkgName = data.getSchemeSpecificPart();
20940                    if (pkgName != null) {
20941                        skipPackages = new String[] { pkgName };
20942                    }
20943                }
20944            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
20945                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
20946            }
20947            if (skipPackages != null && (skipPackages.length > 0)) {
20948                for (String skipPackage : skipPackages) {
20949                    if (skipPackage != null) {
20950                        int NT = receivers.size();
20951                        for (int it=0; it<NT; it++) {
20952                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
20953                            if (curt.activityInfo.packageName.equals(skipPackage)) {
20954                                receivers.remove(it);
20955                                it--;
20956                                NT--;
20957                            }
20958                        }
20959                    }
20960                }
20961            }
20962
20963            int NT = receivers != null ? receivers.size() : 0;
20964            int it = 0;
20965            ResolveInfo curt = null;
20966            BroadcastFilter curr = null;
20967            while (it < NT && ir < NR) {
20968                if (curt == null) {
20969                    curt = (ResolveInfo)receivers.get(it);
20970                }
20971                if (curr == null) {
20972                    curr = registeredReceivers.get(ir);
20973                }
20974                if (curr.getPriority() >= curt.priority) {
20975                    // Insert this broadcast record into the final list.
20976                    receivers.add(it, curr);
20977                    ir++;
20978                    curr = null;
20979                    it++;
20980                    NT++;
20981                } else {
20982                    // Skip to the next ResolveInfo in the final list.
20983                    it++;
20984                    curt = null;
20985                }
20986            }
20987        }
20988        while (ir < NR) {
20989            if (receivers == null) {
20990                receivers = new ArrayList();
20991            }
20992            receivers.add(registeredReceivers.get(ir));
20993            ir++;
20994        }
20995
20996        if (isCallerSystem) {
20997            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
20998                    isProtectedBroadcast, receivers);
20999        }
21000
21001        if ((receivers != null && receivers.size() > 0)
21002                || resultTo != null) {
21003            BroadcastQueue queue = broadcastQueueForIntent(intent);
21004            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21005                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21006                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
21007                    resultData, resultExtras, ordered, sticky, false, userId);
21008
21009            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
21010                    + ": prev had " + queue.mOrderedBroadcasts.size());
21011            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
21012                    "Enqueueing broadcast " + r.intent.getAction());
21013
21014            final BroadcastRecord oldRecord =
21015                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
21016            if (oldRecord != null) {
21017                // Replaced, fire the result-to receiver.
21018                if (oldRecord.resultTo != null) {
21019                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
21020                    try {
21021                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
21022                                oldRecord.intent,
21023                                Activity.RESULT_CANCELED, null, null,
21024                                false, false, oldRecord.userId);
21025                    } catch (RemoteException e) {
21026                        Slog.w(TAG, "Failure ["
21027                                + queue.mQueueName + "] sending broadcast result of "
21028                                + intent, e);
21029
21030                    }
21031                }
21032            } else {
21033                queue.enqueueOrderedBroadcastLocked(r);
21034                queue.scheduleBroadcastsLocked();
21035            }
21036        } else {
21037            // There was nobody interested in the broadcast, but we still want to record
21038            // that it happened.
21039            if (intent.getComponent() == null && intent.getPackage() == null
21040                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21041                // This was an implicit broadcast... let's record it for posterity.
21042                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
21043            }
21044        }
21045
21046        return ActivityManager.BROADCAST_SUCCESS;
21047    }
21048
21049    /**
21050     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21051     */
21052    private int getUidFromIntent(Intent intent) {
21053        if (intent == null) {
21054            return -1;
21055        }
21056        final Bundle intentExtras = intent.getExtras();
21057        return intent.hasExtra(Intent.EXTRA_UID)
21058                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
21059    }
21060
21061    final void rotateBroadcastStatsIfNeededLocked() {
21062        final long now = SystemClock.elapsedRealtime();
21063        if (mCurBroadcastStats == null ||
21064                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
21065            mLastBroadcastStats = mCurBroadcastStats;
21066            if (mLastBroadcastStats != null) {
21067                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
21068                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
21069            }
21070            mCurBroadcastStats = new BroadcastStats();
21071        }
21072    }
21073
21074    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
21075            int skipCount, long dispatchTime) {
21076        rotateBroadcastStatsIfNeededLocked();
21077        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
21078    }
21079
21080    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21081        rotateBroadcastStatsIfNeededLocked();
21082        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
21083    }
21084
21085    final Intent verifyBroadcastLocked(Intent intent) {
21086        // Refuse possible leaked file descriptors
21087        if (intent != null && intent.hasFileDescriptors() == true) {
21088            throw new IllegalArgumentException("File descriptors passed in Intent");
21089        }
21090
21091        int flags = intent.getFlags();
21092
21093        if (!mProcessesReady) {
21094            // if the caller really truly claims to know what they're doing, go
21095            // ahead and allow the broadcast without launching any receivers
21096            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
21097                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
21098            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21099                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
21100                        + " before boot completion");
21101                throw new IllegalStateException("Cannot broadcast before boot completed");
21102            }
21103        }
21104
21105        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
21106            throw new IllegalArgumentException(
21107                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
21108        }
21109
21110        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21111            switch (Binder.getCallingUid()) {
21112                case ROOT_UID:
21113                case SHELL_UID:
21114                    break;
21115                default:
21116                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
21117                            + Binder.getCallingUid());
21118                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
21119                    break;
21120            }
21121        }
21122
21123        return intent;
21124    }
21125
21126    public final int broadcastIntent(IApplicationThread caller,
21127            Intent intent, String resolvedType, IIntentReceiver resultTo,
21128            int resultCode, String resultData, Bundle resultExtras,
21129            String[] requiredPermissions, int appOp, Bundle bOptions,
21130            boolean serialized, boolean sticky, int userId) {
21131        enforceNotIsolatedCaller("broadcastIntent");
21132        synchronized(this) {
21133            intent = verifyBroadcastLocked(intent);
21134
21135            final ProcessRecord callerApp = getRecordForAppLocked(caller);
21136            final int callingPid = Binder.getCallingPid();
21137            final int callingUid = Binder.getCallingUid();
21138            final long origId = Binder.clearCallingIdentity();
21139            int res = broadcastIntentLocked(callerApp,
21140                    callerApp != null ? callerApp.info.packageName : null,
21141                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
21142                    requiredPermissions, appOp, bOptions, serialized, sticky,
21143                    callingPid, callingUid, userId);
21144            Binder.restoreCallingIdentity(origId);
21145            return res;
21146        }
21147    }
21148
21149
21150    int broadcastIntentInPackage(String packageName, int uid,
21151            Intent intent, String resolvedType, IIntentReceiver resultTo,
21152            int resultCode, String resultData, Bundle resultExtras,
21153            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
21154            int userId) {
21155        synchronized(this) {
21156            intent = verifyBroadcastLocked(intent);
21157
21158            final long origId = Binder.clearCallingIdentity();
21159            String[] requiredPermissions = requiredPermission == null ? null
21160                    : new String[] {requiredPermission};
21161            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
21162                    resultTo, resultCode, resultData, resultExtras,
21163                    requiredPermissions, OP_NONE, bOptions, serialized,
21164                    sticky, -1, uid, userId);
21165            Binder.restoreCallingIdentity(origId);
21166            return res;
21167        }
21168    }
21169
21170    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
21171        // Refuse possible leaked file descriptors
21172        if (intent != null && intent.hasFileDescriptors() == true) {
21173            throw new IllegalArgumentException("File descriptors passed in Intent");
21174        }
21175
21176        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21177                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
21178
21179        synchronized(this) {
21180            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
21181                    != PackageManager.PERMISSION_GRANTED) {
21182                String msg = "Permission Denial: unbroadcastIntent() from pid="
21183                        + Binder.getCallingPid()
21184                        + ", uid=" + Binder.getCallingUid()
21185                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21186                Slog.w(TAG, msg);
21187                throw new SecurityException(msg);
21188            }
21189            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21190            if (stickies != null) {
21191                ArrayList<Intent> list = stickies.get(intent.getAction());
21192                if (list != null) {
21193                    int N = list.size();
21194                    int i;
21195                    for (i=0; i<N; i++) {
21196                        if (intent.filterEquals(list.get(i))) {
21197                            list.remove(i);
21198                            break;
21199                        }
21200                    }
21201                    if (list.size() <= 0) {
21202                        stickies.remove(intent.getAction());
21203                    }
21204                }
21205                if (stickies.size() <= 0) {
21206                    mStickyBroadcasts.remove(userId);
21207                }
21208            }
21209        }
21210    }
21211
21212    void backgroundServicesFinishedLocked(int userId) {
21213        for (BroadcastQueue queue : mBroadcastQueues) {
21214            queue.backgroundServicesFinishedLocked(userId);
21215        }
21216    }
21217
21218    public void finishReceiver(IBinder who, int resultCode, String resultData,
21219            Bundle resultExtras, boolean resultAbort, int flags) {
21220        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
21221
21222        // Refuse possible leaked file descriptors
21223        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
21224            throw new IllegalArgumentException("File descriptors passed in Bundle");
21225        }
21226
21227        final long origId = Binder.clearCallingIdentity();
21228        try {
21229            boolean doNext = false;
21230            BroadcastRecord r;
21231
21232            synchronized(this) {
21233                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
21234                        ? mFgBroadcastQueue : mBgBroadcastQueue;
21235                r = queue.getMatchingOrderedReceiver(who);
21236                if (r != null) {
21237                    doNext = r.queue.finishReceiverLocked(r, resultCode,
21238                        resultData, resultExtras, resultAbort, true);
21239                }
21240            }
21241
21242            if (doNext) {
21243                r.queue.processNextBroadcast(false);
21244            }
21245            trimApplications();
21246        } finally {
21247            Binder.restoreCallingIdentity(origId);
21248        }
21249    }
21250
21251    // =========================================================
21252    // INSTRUMENTATION
21253    // =========================================================
21254
21255    public boolean startInstrumentation(ComponentName className,
21256            String profileFile, int flags, Bundle arguments,
21257            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
21258            int userId, String abiOverride) {
21259        enforceNotIsolatedCaller("startInstrumentation");
21260        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21261                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
21262        // Refuse possible leaked file descriptors
21263        if (arguments != null && arguments.hasFileDescriptors()) {
21264            throw new IllegalArgumentException("File descriptors passed in Bundle");
21265        }
21266
21267        synchronized(this) {
21268            InstrumentationInfo ii = null;
21269            ApplicationInfo ai = null;
21270            try {
21271                ii = mContext.getPackageManager().getInstrumentationInfo(
21272                    className, STOCK_PM_FLAGS);
21273                ai = AppGlobals.getPackageManager().getApplicationInfo(
21274                        ii.targetPackage, STOCK_PM_FLAGS, userId);
21275            } catch (PackageManager.NameNotFoundException e) {
21276            } catch (RemoteException e) {
21277            }
21278            if (ii == null) {
21279                reportStartInstrumentationFailureLocked(watcher, className,
21280                        "Unable to find instrumentation info for: " + className);
21281                return false;
21282            }
21283            if (ai == null) {
21284                reportStartInstrumentationFailureLocked(watcher, className,
21285                        "Unable to find instrumentation target package: " + ii.targetPackage);
21286                return false;
21287            }
21288            if (!ai.hasCode()) {
21289                reportStartInstrumentationFailureLocked(watcher, className,
21290                        "Instrumentation target has no code: " + ii.targetPackage);
21291                return false;
21292            }
21293
21294            int match = mContext.getPackageManager().checkSignatures(
21295                    ii.targetPackage, ii.packageName);
21296            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
21297                String msg = "Permission Denial: starting instrumentation "
21298                        + className + " from pid="
21299                        + Binder.getCallingPid()
21300                        + ", uid=" + Binder.getCallingPid()
21301                        + " not allowed because package " + ii.packageName
21302                        + " does not have a signature matching the target "
21303                        + ii.targetPackage;
21304                reportStartInstrumentationFailureLocked(watcher, className, msg);
21305                throw new SecurityException(msg);
21306            }
21307
21308            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
21309            activeInstr.mClass = className;
21310            String defProcess = ai.processName;;
21311            if (ii.targetProcesses == null) {
21312                activeInstr.mTargetProcesses = new String[]{ai.processName};
21313            } else if (ii.targetProcesses.equals("*")) {
21314                activeInstr.mTargetProcesses = new String[0];
21315            } else {
21316                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
21317                defProcess = activeInstr.mTargetProcesses[0];
21318            }
21319            activeInstr.mTargetInfo = ai;
21320            activeInstr.mProfileFile = profileFile;
21321            activeInstr.mArguments = arguments;
21322            activeInstr.mWatcher = watcher;
21323            activeInstr.mUiAutomationConnection = uiAutomationConnection;
21324            activeInstr.mResultClass = className;
21325
21326            final long origId = Binder.clearCallingIdentity();
21327            // Instrumentation can kill and relaunch even persistent processes
21328            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
21329                    "start instr");
21330            // Inform usage stats to make the target package active
21331            if (mUsageStatsService != null) {
21332                mUsageStatsService.reportEvent(ii.targetPackage, userId,
21333                        UsageEvents.Event.SYSTEM_INTERACTION);
21334            }
21335            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
21336            app.instr = activeInstr;
21337            activeInstr.mFinished = false;
21338            activeInstr.mRunningProcesses.add(app);
21339            if (!mActiveInstrumentation.contains(activeInstr)) {
21340                mActiveInstrumentation.add(activeInstr);
21341            }
21342            Binder.restoreCallingIdentity(origId);
21343        }
21344
21345        return true;
21346    }
21347
21348    /**
21349     * Report errors that occur while attempting to start Instrumentation.  Always writes the
21350     * error to the logs, but if somebody is watching, send the report there too.  This enables
21351     * the "am" command to report errors with more information.
21352     *
21353     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
21354     * @param cn The component name of the instrumentation.
21355     * @param report The error report.
21356     */
21357    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
21358            ComponentName cn, String report) {
21359        Slog.w(TAG, report);
21360        if (watcher != null) {
21361            Bundle results = new Bundle();
21362            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
21363            results.putString("Error", report);
21364            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
21365        }
21366    }
21367
21368    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
21369        if (app.instr == null) {
21370            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21371            return;
21372        }
21373
21374        if (!app.instr.mFinished && results != null) {
21375            if (app.instr.mCurResults == null) {
21376                app.instr.mCurResults = new Bundle(results);
21377            } else {
21378                app.instr.mCurResults.putAll(results);
21379            }
21380        }
21381    }
21382
21383    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
21384        int userId = UserHandle.getCallingUserId();
21385        // Refuse possible leaked file descriptors
21386        if (results != null && results.hasFileDescriptors()) {
21387            throw new IllegalArgumentException("File descriptors passed in Intent");
21388        }
21389
21390        synchronized(this) {
21391            ProcessRecord app = getRecordForAppLocked(target);
21392            if (app == null) {
21393                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
21394                return;
21395            }
21396            final long origId = Binder.clearCallingIdentity();
21397            addInstrumentationResultsLocked(app, results);
21398            Binder.restoreCallingIdentity(origId);
21399        }
21400    }
21401
21402    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
21403        if (app.instr == null) {
21404            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21405            return;
21406        }
21407
21408        if (!app.instr.mFinished) {
21409            if (app.instr.mWatcher != null) {
21410                Bundle finalResults = app.instr.mCurResults;
21411                if (finalResults != null) {
21412                    if (app.instr.mCurResults != null && results != null) {
21413                        finalResults.putAll(results);
21414                    }
21415                } else {
21416                    finalResults = results;
21417                }
21418                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
21419                        app.instr.mClass, resultCode, finalResults);
21420            }
21421
21422            // Can't call out of the system process with a lock held, so post a message.
21423            if (app.instr.mUiAutomationConnection != null) {
21424                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
21425                        app.instr.mUiAutomationConnection).sendToTarget();
21426            }
21427            app.instr.mFinished = true;
21428        }
21429
21430        app.instr.removeProcess(app);
21431        app.instr = null;
21432
21433        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
21434                "finished inst");
21435    }
21436
21437    public void finishInstrumentation(IApplicationThread target,
21438            int resultCode, Bundle results) {
21439        int userId = UserHandle.getCallingUserId();
21440        // Refuse possible leaked file descriptors
21441        if (results != null && results.hasFileDescriptors()) {
21442            throw new IllegalArgumentException("File descriptors passed in Intent");
21443        }
21444
21445        synchronized(this) {
21446            ProcessRecord app = getRecordForAppLocked(target);
21447            if (app == null) {
21448                Slog.w(TAG, "finishInstrumentation: no app for " + target);
21449                return;
21450            }
21451            final long origId = Binder.clearCallingIdentity();
21452            finishInstrumentationLocked(app, resultCode, results);
21453            Binder.restoreCallingIdentity(origId);
21454        }
21455    }
21456
21457    // =========================================================
21458    // CONFIGURATION
21459    // =========================================================
21460
21461    public ConfigurationInfo getDeviceConfigurationInfo() {
21462        ConfigurationInfo config = new ConfigurationInfo();
21463        synchronized (this) {
21464            final Configuration globalConfig = getGlobalConfiguration();
21465            config.reqTouchScreen = globalConfig.touchscreen;
21466            config.reqKeyboardType = globalConfig.keyboard;
21467            config.reqNavigation = globalConfig.navigation;
21468            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
21469                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
21470                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
21471            }
21472            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
21473                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
21474                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
21475            }
21476            config.reqGlEsVersion = GL_ES_VERSION;
21477        }
21478        return config;
21479    }
21480
21481    ActivityStack getFocusedStack() {
21482        return mStackSupervisor.getFocusedStack();
21483    }
21484
21485    @Override
21486    public StackInfo getFocusedStackInfo() throws RemoteException {
21487        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
21488        long ident = Binder.clearCallingIdentity();
21489        try {
21490            synchronized (this) {
21491                ActivityStack focusedStack = getFocusedStack();
21492                if (focusedStack != null) {
21493                    return mStackSupervisor.getStackInfo(focusedStack.mStackId);
21494                }
21495                return null;
21496            }
21497        } finally {
21498            Binder.restoreCallingIdentity(ident);
21499        }
21500    }
21501
21502    public Configuration getConfiguration() {
21503        Configuration ci;
21504        synchronized(this) {
21505            ci = new Configuration(getGlobalConfiguration());
21506            ci.userSetLocale = false;
21507        }
21508        return ci;
21509    }
21510
21511    @Override
21512    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
21513        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
21514        synchronized (this) {
21515            mSuppressResizeConfigChanges = suppress;
21516        }
21517    }
21518
21519    /**
21520     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
21521     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
21522     *       activity and clearing the task at the same time.
21523     */
21524    @Override
21525    // TODO: API should just be about changing windowing modes...
21526    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
21527        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
21528                "moveTasksToFullscreenStack()");
21529        synchronized (this) {
21530            final long origId = Binder.clearCallingIdentity();
21531            try {
21532                final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
21533                if (stack != null){
21534                    if (!stack.isActivityTypeStandardOrUndefined()) {
21535                        throw new IllegalArgumentException(
21536                                "You can't move tasks from non-standard stacks.");
21537                    }
21538                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
21539                }
21540            } finally {
21541                Binder.restoreCallingIdentity(origId);
21542            }
21543        }
21544    }
21545
21546    @Override
21547    public void updatePersistentConfiguration(Configuration values) {
21548        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
21549        enforceWriteSettingsPermission("updatePersistentConfiguration()");
21550        if (values == null) {
21551            throw new NullPointerException("Configuration must not be null");
21552        }
21553
21554        int userId = UserHandle.getCallingUserId();
21555
21556        synchronized(this) {
21557            updatePersistentConfigurationLocked(values, userId);
21558        }
21559    }
21560
21561    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
21562        final long origId = Binder.clearCallingIdentity();
21563        try {
21564            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
21565        } finally {
21566            Binder.restoreCallingIdentity(origId);
21567        }
21568    }
21569
21570    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
21571        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
21572                FONT_SCALE, 1.0f, userId);
21573
21574        synchronized (this) {
21575            if (getGlobalConfiguration().fontScale == scaleFactor) {
21576                return;
21577            }
21578
21579            final Configuration configuration
21580                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
21581            configuration.fontScale = scaleFactor;
21582            updatePersistentConfigurationLocked(configuration, userId);
21583        }
21584    }
21585
21586    private void enforceWriteSettingsPermission(String func) {
21587        int uid = Binder.getCallingUid();
21588        if (uid == ROOT_UID) {
21589            return;
21590        }
21591
21592        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
21593                Settings.getPackageNameForUid(mContext, uid), false)) {
21594            return;
21595        }
21596
21597        String msg = "Permission Denial: " + func + " from pid="
21598                + Binder.getCallingPid()
21599                + ", uid=" + uid
21600                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
21601        Slog.w(TAG, msg);
21602        throw new SecurityException(msg);
21603    }
21604
21605    @Override
21606    public boolean updateConfiguration(Configuration values) {
21607        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
21608
21609        synchronized(this) {
21610            if (values == null && mWindowManager != null) {
21611                // sentinel: fetch the current configuration from the window manager
21612                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
21613            }
21614
21615            if (mWindowManager != null) {
21616                // Update OOM levels based on display size.
21617                mProcessList.applyDisplaySize(mWindowManager);
21618            }
21619
21620            final long origId = Binder.clearCallingIdentity();
21621            try {
21622                if (values != null) {
21623                    Settings.System.clearConfiguration(values);
21624                }
21625                updateConfigurationLocked(values, null, false, false /* persistent */,
21626                        UserHandle.USER_NULL, false /* deferResume */,
21627                        mTmpUpdateConfigurationResult);
21628                return mTmpUpdateConfigurationResult.changes != 0;
21629            } finally {
21630                Binder.restoreCallingIdentity(origId);
21631            }
21632        }
21633    }
21634
21635    void updateUserConfigurationLocked() {
21636        final Configuration configuration = new Configuration(getGlobalConfiguration());
21637        final int currentUserId = mUserController.getCurrentUserId();
21638        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
21639                currentUserId, Settings.System.canWrite(mContext));
21640        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
21641                false /* persistent */, currentUserId, false /* deferResume */);
21642    }
21643
21644    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21645            boolean initLocale) {
21646        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
21647    }
21648
21649    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21650            boolean initLocale, boolean deferResume) {
21651        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
21652        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
21653                UserHandle.USER_NULL, deferResume);
21654    }
21655
21656    // To cache the list of supported system locales
21657    private String[] mSupportedSystemLocales = null;
21658
21659    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21660            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
21661        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
21662                deferResume, null /* result */);
21663    }
21664
21665    /**
21666     * Do either or both things: (1) change the current configuration, and (2)
21667     * make sure the given activity is running with the (now) current
21668     * configuration.  Returns true if the activity has been left running, or
21669     * false if <var>starting</var> is being destroyed to match the new
21670     * configuration.
21671     *
21672     * @param userId is only used when persistent parameter is set to true to persist configuration
21673     *               for that particular user
21674     */
21675    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21676            boolean initLocale, boolean persistent, int userId, boolean deferResume,
21677            UpdateConfigurationResult result) {
21678        int changes = 0;
21679        boolean kept = true;
21680
21681        if (mWindowManager != null) {
21682            mWindowManager.deferSurfaceLayout();
21683        }
21684        try {
21685            if (values != null) {
21686                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
21687                        deferResume);
21688            }
21689
21690            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
21691        } finally {
21692            if (mWindowManager != null) {
21693                mWindowManager.continueSurfaceLayout();
21694            }
21695        }
21696
21697        if (result != null) {
21698            result.changes = changes;
21699            result.activityRelaunched = !kept;
21700        }
21701        return kept;
21702    }
21703
21704    /** Update default (global) configuration and notify listeners about changes. */
21705    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
21706            boolean persistent, int userId, boolean deferResume) {
21707        mTempConfig.setTo(getGlobalConfiguration());
21708        final int changes = mTempConfig.updateFrom(values);
21709        if (changes == 0) {
21710            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
21711            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
21712            // performDisplayOverrideConfigUpdate in order to send the new display configuration
21713            // (even if there are no actual changes) to unfreeze the window.
21714            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
21715            return 0;
21716        }
21717
21718        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
21719                "Updating global configuration to: " + values);
21720
21721        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
21722
21723        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
21724            final LocaleList locales = values.getLocales();
21725            int bestLocaleIndex = 0;
21726            if (locales.size() > 1) {
21727                if (mSupportedSystemLocales == null) {
21728                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
21729                }
21730                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
21731            }
21732            SystemProperties.set("persist.sys.locale",
21733                    locales.get(bestLocaleIndex).toLanguageTag());
21734            LocaleList.setDefault(locales, bestLocaleIndex);
21735            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
21736                    locales.get(bestLocaleIndex)));
21737        }
21738
21739        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
21740        mTempConfig.seq = mConfigurationSeq;
21741
21742        // Update stored global config and notify everyone about the change.
21743        mStackSupervisor.onConfigurationChanged(mTempConfig);
21744
21745        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
21746        // TODO(multi-display): Update UsageEvents#Event to include displayId.
21747        mUsageStatsService.reportConfigurationChange(mTempConfig,
21748                mUserController.getCurrentUserId());
21749
21750        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
21751        mShowDialogs = shouldShowDialogs(mTempConfig);
21752
21753        AttributeCache ac = AttributeCache.instance();
21754        if (ac != null) {
21755            ac.updateConfiguration(mTempConfig);
21756        }
21757
21758        // Make sure all resources in our process are updated right now, so that anyone who is going
21759        // to retrieve resource values after we return will be sure to get the new ones. This is
21760        // especially important during boot, where the first config change needs to guarantee all
21761        // resources have that config before following boot code is executed.
21762        mSystemThread.applyConfigurationToResources(mTempConfig);
21763
21764        // We need another copy of global config because we're scheduling some calls instead of
21765        // running them in place. We need to be sure that object we send will be handled unchanged.
21766        final Configuration configCopy = new Configuration(mTempConfig);
21767        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
21768            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
21769            msg.obj = configCopy;
21770            msg.arg1 = userId;
21771            mHandler.sendMessage(msg);
21772        }
21773
21774        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21775            ProcessRecord app = mLruProcesses.get(i);
21776            try {
21777                if (app.thread != null) {
21778                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
21779                            + app.processName + " new config " + configCopy);
21780                    mLifecycleManager.scheduleTransaction(app.thread,
21781                            ConfigurationChangeItem.obtain(configCopy));
21782                }
21783            } catch (Exception e) {
21784                Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
21785            }
21786        }
21787
21788        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
21789        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
21790                | Intent.FLAG_RECEIVER_FOREGROUND
21791                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21792        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
21793                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
21794                UserHandle.USER_ALL);
21795        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
21796            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
21797            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
21798                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
21799                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21800            if (initLocale || !mProcessesReady) {
21801                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21802            }
21803            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
21804                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
21805                    UserHandle.USER_ALL);
21806        }
21807
21808        // Override configuration of the default display duplicates global config, so we need to
21809        // update it also. This will also notify WindowManager about changes.
21810        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
21811                DEFAULT_DISPLAY);
21812
21813        return changes;
21814    }
21815
21816    @Override
21817    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
21818        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
21819
21820        synchronized (this) {
21821            // Check if display is initialized in AM.
21822            if (!mStackSupervisor.isDisplayAdded(displayId)) {
21823                // Call might come when display is not yet added or has already been removed.
21824                if (DEBUG_CONFIGURATION) {
21825                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
21826                            + displayId);
21827                }
21828                return false;
21829            }
21830
21831            if (values == null && mWindowManager != null) {
21832                // sentinel: fetch the current configuration from the window manager
21833                values = mWindowManager.computeNewConfiguration(displayId);
21834            }
21835
21836            if (mWindowManager != null) {
21837                // Update OOM levels based on display size.
21838                mProcessList.applyDisplaySize(mWindowManager);
21839            }
21840
21841            final long origId = Binder.clearCallingIdentity();
21842            try {
21843                if (values != null) {
21844                    Settings.System.clearConfiguration(values);
21845                }
21846                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
21847                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
21848                return mTmpUpdateConfigurationResult.changes != 0;
21849            } finally {
21850                Binder.restoreCallingIdentity(origId);
21851            }
21852        }
21853    }
21854
21855    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
21856            boolean deferResume, int displayId) {
21857        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
21858                displayId, null /* result */);
21859    }
21860
21861    /**
21862     * Updates override configuration specific for the selected display. If no config is provided,
21863     * new one will be computed in WM based on current display info.
21864     */
21865    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
21866            ActivityRecord starting, boolean deferResume, int displayId,
21867            UpdateConfigurationResult result) {
21868        int changes = 0;
21869        boolean kept = true;
21870
21871        if (mWindowManager != null) {
21872            mWindowManager.deferSurfaceLayout();
21873        }
21874        try {
21875            if (values != null) {
21876                if (displayId == DEFAULT_DISPLAY) {
21877                    // Override configuration of the default display duplicates global config, so
21878                    // we're calling global config update instead for default display. It will also
21879                    // apply the correct override config.
21880                    changes = updateGlobalConfiguration(values, false /* initLocale */,
21881                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
21882                } else {
21883                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
21884                }
21885            }
21886
21887            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
21888        } finally {
21889            if (mWindowManager != null) {
21890                mWindowManager.continueSurfaceLayout();
21891            }
21892        }
21893
21894        if (result != null) {
21895            result.changes = changes;
21896            result.activityRelaunched = !kept;
21897        }
21898        return kept;
21899    }
21900
21901    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
21902            int displayId) {
21903        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
21904        final int changes = mTempConfig.updateFrom(values);
21905        if (changes != 0) {
21906            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
21907                    + mTempConfig + " for displayId=" + displayId);
21908            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
21909
21910            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
21911            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
21912                mAppWarnings.onDensityChanged();
21913
21914                killAllBackgroundProcessesExcept(N,
21915                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
21916            }
21917        }
21918
21919        // Update the configuration with WM first and check if any of the stacks need to be resized
21920        // due to the configuration change. If so, resize the stacks now and do any relaunches if
21921        // necessary. This way we don't need to relaunch again afterwards in
21922        // ensureActivityConfigurationLocked().
21923        if (mWindowManager != null) {
21924            final int[] resizedStacks =
21925                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
21926            if (resizedStacks != null) {
21927                for (int stackId : resizedStacks) {
21928                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
21929                }
21930            }
21931        }
21932
21933        return changes;
21934    }
21935
21936    /** Applies latest configuration and/or visibility updates if needed. */
21937    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
21938        boolean kept = true;
21939        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
21940        // mainStack is null during startup.
21941        if (mainStack != null) {
21942            if (changes != 0 && starting == null) {
21943                // If the configuration changed, and the caller is not already
21944                // in the process of starting an activity, then find the top
21945                // activity to check if its configuration needs to change.
21946                starting = mainStack.topRunningActivityLocked();
21947            }
21948
21949            if (starting != null) {
21950                kept = starting.ensureActivityConfigurationLocked(changes,
21951                        false /* preserveWindow */);
21952                // And we need to make sure at this point that all other activities
21953                // are made visible with the correct configuration.
21954                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
21955                        !PRESERVE_WINDOWS);
21956            }
21957        }
21958
21959        return kept;
21960    }
21961
21962    /** Helper method that requests bounds from WM and applies them to stack. */
21963    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
21964        final Rect newStackBounds = new Rect();
21965        final ActivityStack stack = mStackSupervisor.getStack(stackId);
21966
21967        // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
21968        if (stack == null) {
21969            final StringWriter writer = new StringWriter();
21970            final PrintWriter printWriter = new PrintWriter(writer);
21971            mStackSupervisor.dumpDisplays(printWriter);
21972            printWriter.flush();
21973
21974            Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
21975        }
21976
21977        stack.getBoundsForNewConfiguration(newStackBounds);
21978        mStackSupervisor.resizeStackLocked(
21979                stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
21980                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
21981                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
21982    }
21983
21984    /**
21985     * Decide based on the configuration whether we should show the ANR,
21986     * crash, etc dialogs.  The idea is that if there is no affordance to
21987     * press the on-screen buttons, or the user experience would be more
21988     * greatly impacted than the crash itself, we shouldn't show the dialog.
21989     *
21990     * A thought: SystemUI might also want to get told about this, the Power
21991     * dialog / global actions also might want different behaviors.
21992     */
21993    private static boolean shouldShowDialogs(Configuration config) {
21994        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
21995                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
21996                                   && config.navigation == Configuration.NAVIGATION_NONAV);
21997        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
21998        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
21999                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
22000                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
22001                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
22002        return inputMethodExists && uiModeSupportsDialogs;
22003    }
22004
22005    @Override
22006    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
22007        synchronized (this) {
22008            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
22009            if (srec != null) {
22010                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
22011            }
22012        }
22013        return false;
22014    }
22015
22016    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22017            Intent resultData) {
22018
22019        synchronized (this) {
22020            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22021            if (r != null) {
22022                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22023            }
22024            return false;
22025        }
22026    }
22027
22028    public int getLaunchedFromUid(IBinder activityToken) {
22029        ActivityRecord srec;
22030        synchronized (this) {
22031            srec = ActivityRecord.forTokenLocked(activityToken);
22032        }
22033        if (srec == null) {
22034            return -1;
22035        }
22036        return srec.launchedFromUid;
22037    }
22038
22039    public String getLaunchedFromPackage(IBinder activityToken) {
22040        ActivityRecord srec;
22041        synchronized (this) {
22042            srec = ActivityRecord.forTokenLocked(activityToken);
22043        }
22044        if (srec == null) {
22045            return null;
22046        }
22047        return srec.launchedFromPackage;
22048    }
22049
22050    // =========================================================
22051    // LIFETIME MANAGEMENT
22052    // =========================================================
22053
22054    // Returns whether the app is receiving broadcast.
22055    // If receiving, fetch all broadcast queues which the app is
22056    // the current [or imminent] receiver on.
22057    private boolean isReceivingBroadcastLocked(ProcessRecord app,
22058            ArraySet<BroadcastQueue> receivingQueues) {
22059        final int N = app.curReceivers.size();
22060        if (N > 0) {
22061            for (int i = 0; i < N; i++) {
22062                receivingQueues.add(app.curReceivers.valueAt(i).queue);
22063            }
22064            return true;
22065        }
22066
22067        // It's not the current receiver, but it might be starting up to become one
22068        for (BroadcastQueue queue : mBroadcastQueues) {
22069            final BroadcastRecord r = queue.mPendingBroadcast;
22070            if (r != null && r.curApp == app) {
22071                // found it; report which queue it's in
22072                receivingQueues.add(queue);
22073            }
22074        }
22075
22076        return !receivingQueues.isEmpty();
22077    }
22078
22079    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
22080            int targetUid, ComponentName targetComponent, String targetProcess) {
22081        if (!mTrackingAssociations) {
22082            return null;
22083        }
22084        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22085                = mAssociations.get(targetUid);
22086        if (components == null) {
22087            components = new ArrayMap<>();
22088            mAssociations.put(targetUid, components);
22089        }
22090        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22091        if (sourceUids == null) {
22092            sourceUids = new SparseArray<>();
22093            components.put(targetComponent, sourceUids);
22094        }
22095        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22096        if (sourceProcesses == null) {
22097            sourceProcesses = new ArrayMap<>();
22098            sourceUids.put(sourceUid, sourceProcesses);
22099        }
22100        Association ass = sourceProcesses.get(sourceProcess);
22101        if (ass == null) {
22102            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
22103                    targetProcess);
22104            sourceProcesses.put(sourceProcess, ass);
22105        }
22106        ass.mCount++;
22107        ass.mNesting++;
22108        if (ass.mNesting == 1) {
22109            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
22110            ass.mLastState = sourceState;
22111        }
22112        return ass;
22113    }
22114
22115    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
22116            ComponentName targetComponent) {
22117        if (!mTrackingAssociations) {
22118            return;
22119        }
22120        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22121                = mAssociations.get(targetUid);
22122        if (components == null) {
22123            return;
22124        }
22125        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22126        if (sourceUids == null) {
22127            return;
22128        }
22129        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22130        if (sourceProcesses == null) {
22131            return;
22132        }
22133        Association ass = sourceProcesses.get(sourceProcess);
22134        if (ass == null || ass.mNesting <= 0) {
22135            return;
22136        }
22137        ass.mNesting--;
22138        if (ass.mNesting == 0) {
22139            long uptime = SystemClock.uptimeMillis();
22140            ass.mTime += uptime - ass.mStartTime;
22141            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22142                    += uptime - ass.mLastStateUptime;
22143            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
22144        }
22145    }
22146
22147    private void noteUidProcessState(final int uid, final int state) {
22148        mBatteryStatsService.noteUidProcessState(uid, state);
22149        if (mTrackingAssociations) {
22150            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
22151                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
22152                        = mAssociations.valueAt(i1);
22153                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
22154                    SparseArray<ArrayMap<String, Association>> sourceUids
22155                            = targetComponents.valueAt(i2);
22156                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
22157                    if (sourceProcesses != null) {
22158                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
22159                            Association ass = sourceProcesses.valueAt(i4);
22160                            if (ass.mNesting >= 1) {
22161                                // currently associated
22162                                long uptime = SystemClock.uptimeMillis();
22163                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22164                                        += uptime - ass.mLastStateUptime;
22165                                ass.mLastState = state;
22166                                ass.mLastStateUptime = uptime;
22167                            }
22168                        }
22169                    }
22170                }
22171            }
22172        }
22173    }
22174
22175    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
22176            boolean doingAll, long now) {
22177        if (mAdjSeq == app.adjSeq) {
22178            // This adjustment has already been computed.
22179            return app.curRawAdj;
22180        }
22181
22182        if (app.thread == null) {
22183            app.adjSeq = mAdjSeq;
22184            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22185            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22186            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
22187        }
22188
22189        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
22190        app.adjSource = null;
22191        app.adjTarget = null;
22192        app.empty = false;
22193        app.cached = false;
22194
22195        final int activitiesSize = app.activities.size();
22196
22197        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
22198            // The max adjustment doesn't allow this app to be anything
22199            // below foreground, so it is not worth doing work for it.
22200            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
22201            app.adjType = "fixed";
22202            app.adjSeq = mAdjSeq;
22203            app.curRawAdj = app.maxAdj;
22204            app.foregroundActivities = false;
22205            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22206            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
22207            // System processes can do UI, and when they do we want to have
22208            // them trim their memory after the user leaves the UI.  To
22209            // facilitate this, here we need to determine whether or not it
22210            // is currently showing UI.
22211            app.systemNoUi = true;
22212            if (app == TOP_APP) {
22213                app.systemNoUi = false;
22214                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22215                app.adjType = "pers-top-activity";
22216            } else if (app.hasTopUi) {
22217                app.systemNoUi = false;
22218                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22219                app.adjType = "pers-top-ui";
22220            } else if (activitiesSize > 0) {
22221                for (int j = 0; j < activitiesSize; j++) {
22222                    final ActivityRecord r = app.activities.get(j);
22223                    if (r.visible) {
22224                        app.systemNoUi = false;
22225                    }
22226                }
22227            }
22228            if (!app.systemNoUi) {
22229                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
22230            }
22231            return (app.curAdj=app.maxAdj);
22232        }
22233
22234        app.systemNoUi = false;
22235
22236        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
22237
22238        // Determine the importance of the process, starting with most
22239        // important to least, and assign an appropriate OOM adjustment.
22240        int adj;
22241        int schedGroup;
22242        int procState;
22243        boolean foregroundActivities = false;
22244        mTmpBroadcastQueue.clear();
22245        if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
22246            // The last app on the list is the foreground app.
22247            adj = ProcessList.FOREGROUND_APP_ADJ;
22248            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22249            app.adjType = "top-activity";
22250            foregroundActivities = true;
22251            procState = PROCESS_STATE_CUR_TOP;
22252            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22253        } else if (app.instr != null) {
22254            // Don't want to kill running instrumentation.
22255            adj = ProcessList.FOREGROUND_APP_ADJ;
22256            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22257            app.adjType = "instrumentation";
22258            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22259            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
22260        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
22261            // An app that is currently receiving a broadcast also
22262            // counts as being in the foreground for OOM killer purposes.
22263            // It's placed in a sched group based on the nature of the
22264            // broadcast as reflected by which queue it's active in.
22265            adj = ProcessList.FOREGROUND_APP_ADJ;
22266            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
22267                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22268            app.adjType = "broadcast";
22269            procState = ActivityManager.PROCESS_STATE_RECEIVER;
22270            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
22271        } else if (app.executingServices.size() > 0) {
22272            // An app that is currently executing a service callback also
22273            // counts as being in the foreground.
22274            adj = ProcessList.FOREGROUND_APP_ADJ;
22275            schedGroup = app.execServicesFg ?
22276                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22277            app.adjType = "exec-service";
22278            procState = ActivityManager.PROCESS_STATE_SERVICE;
22279            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
22280            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
22281        } else if (app == TOP_APP) {
22282            adj = ProcessList.FOREGROUND_APP_ADJ;
22283            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22284            app.adjType = "top-sleeping";
22285            foregroundActivities = true;
22286            procState = PROCESS_STATE_CUR_TOP;
22287            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22288        } else {
22289            // As far as we know the process is empty.  We may change our mind later.
22290            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22291            // At this point we don't actually know the adjustment.  Use the cached adj
22292            // value that the caller wants us to.
22293            adj = cachedAdj;
22294            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22295            app.cached = true;
22296            app.empty = true;
22297            app.adjType = "cch-empty";
22298            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
22299        }
22300
22301        // Examine all activities if not already foreground.
22302        if (!foregroundActivities && activitiesSize > 0) {
22303            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
22304            for (int j = 0; j < activitiesSize; j++) {
22305                final ActivityRecord r = app.activities.get(j);
22306                if (r.app != app) {
22307                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
22308                            + " instead of expected " + app);
22309                    if (r.app == null || (r.app.uid == app.uid)) {
22310                        // Only fix things up when they look sane
22311                        r.setProcess(app);
22312                    } else {
22313                        continue;
22314                    }
22315                }
22316                if (r.visible) {
22317                    // App has a visible activity; only upgrade adjustment.
22318                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
22319                        adj = ProcessList.VISIBLE_APP_ADJ;
22320                        app.adjType = "vis-activity";
22321                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22322                    }
22323                    if (procState > PROCESS_STATE_CUR_TOP) {
22324                        procState = PROCESS_STATE_CUR_TOP;
22325                        app.adjType = "vis-activity";
22326                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22327                    }
22328                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22329                    app.cached = false;
22330                    app.empty = false;
22331                    foregroundActivities = true;
22332                    final TaskRecord task = r.getTask();
22333                    if (task != null && minLayer > 0) {
22334                        final int layer = task.mLayerRank;
22335                        if (layer >= 0 && minLayer > layer) {
22336                            minLayer = layer;
22337                        }
22338                    }
22339                    break;
22340                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
22341                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22342                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22343                        app.adjType = "pause-activity";
22344                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22345                    }
22346                    if (procState > PROCESS_STATE_CUR_TOP) {
22347                        procState = PROCESS_STATE_CUR_TOP;
22348                        app.adjType = "pause-activity";
22349                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22350                    }
22351                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22352                    app.cached = false;
22353                    app.empty = false;
22354                    foregroundActivities = true;
22355                } else if (r.state == ActivityState.STOPPING) {
22356                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22357                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22358                        app.adjType = "stop-activity";
22359                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22360                    }
22361                    // For the process state, we will at this point consider the
22362                    // process to be cached.  It will be cached either as an activity
22363                    // or empty depending on whether the activity is finishing.  We do
22364                    // this so that we can treat the process as cached for purposes of
22365                    // memory trimming (determing current memory level, trim command to
22366                    // send to process) since there can be an arbitrary number of stopping
22367                    // processes and they should soon all go into the cached state.
22368                    if (!r.finishing) {
22369                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22370                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22371                            app.adjType = "stop-activity";
22372                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22373                        }
22374                    }
22375                    app.cached = false;
22376                    app.empty = false;
22377                    foregroundActivities = true;
22378                } else {
22379                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22380                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
22381                        app.adjType = "cch-act";
22382                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
22383                    }
22384                }
22385            }
22386            if (adj == ProcessList.VISIBLE_APP_ADJ) {
22387                adj += minLayer;
22388            }
22389        }
22390        if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
22391            procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
22392            app.adjType = "cch-rec";
22393            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached recent: " + app);
22394        }
22395
22396        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22397                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
22398            if (app.foregroundServices) {
22399                // The user is aware of this app, so make it visible.
22400                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22401                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22402                app.cached = false;
22403                app.adjType = "fg-service";
22404                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22405                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
22406            } else if (app.hasOverlayUi) {
22407                // The process is display an overlay UI.
22408                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22409                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22410                app.cached = false;
22411                app.adjType = "has-overlay-ui";
22412                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22413                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
22414            }
22415        }
22416
22417        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22418                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22419            if (app.forcingToImportant != null) {
22420                // This is currently used for toasts...  they are not interactive, and
22421                // we don't want them to cause the app to become fully foreground (and
22422                // thus out of background check), so we yes the best background level we can.
22423                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22424                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22425                app.cached = false;
22426                app.adjType = "force-imp";
22427                app.adjSource = app.forcingToImportant;
22428                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22429                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
22430            }
22431        }
22432
22433        if (app == mHeavyWeightProcess) {
22434            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
22435                // We don't want to kill the current heavy-weight process.
22436                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
22437                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22438                app.cached = false;
22439                app.adjType = "heavy";
22440                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22441            }
22442            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22443                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
22444                app.adjType = "heavy";
22445                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22446            }
22447        }
22448
22449        if (app == mHomeProcess) {
22450            if (adj > ProcessList.HOME_APP_ADJ) {
22451                // This process is hosting what we currently consider to be the
22452                // home app, so we don't want to let it go into the background.
22453                adj = ProcessList.HOME_APP_ADJ;
22454                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22455                app.cached = false;
22456                app.adjType = "home";
22457                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22458            }
22459            if (procState > ActivityManager.PROCESS_STATE_HOME) {
22460                procState = ActivityManager.PROCESS_STATE_HOME;
22461                app.adjType = "home";
22462                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22463            }
22464        }
22465
22466        if (app == mPreviousProcess && app.activities.size() > 0) {
22467            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
22468                // This was the previous process that showed UI to the user.
22469                // We want to try to keep it around more aggressively, to give
22470                // a good experience around switching between two apps.
22471                adj = ProcessList.PREVIOUS_APP_ADJ;
22472                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22473                app.cached = false;
22474                app.adjType = "previous";
22475                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
22476            }
22477            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22478                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22479                app.adjType = "previous";
22480                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
22481            }
22482        }
22483
22484        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
22485                + " reason=" + app.adjType);
22486
22487        // By default, we use the computed adjustment.  It may be changed if
22488        // there are applications dependent on our services or providers, but
22489        // this gives us a baseline and makes sure we don't get into an
22490        // infinite recursion.
22491        app.adjSeq = mAdjSeq;
22492        app.curRawAdj = adj;
22493        app.hasStartedServices = false;
22494
22495        if (mBackupTarget != null && app == mBackupTarget.app) {
22496            // If possible we want to avoid killing apps while they're being backed up
22497            if (adj > ProcessList.BACKUP_APP_ADJ) {
22498                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
22499                adj = ProcessList.BACKUP_APP_ADJ;
22500                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22501                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22502                }
22503                app.adjType = "backup";
22504                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22505                app.cached = false;
22506            }
22507            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
22508                procState = ActivityManager.PROCESS_STATE_BACKUP;
22509                app.adjType = "backup";
22510                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22511            }
22512        }
22513
22514        boolean mayBeTop = false;
22515        String mayBeTopType = null;
22516        Object mayBeTopSource = null;
22517        Object mayBeTopTarget = null;
22518
22519        for (int is = app.services.size()-1;
22520                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22521                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22522                        || procState > ActivityManager.PROCESS_STATE_TOP);
22523                is--) {
22524            ServiceRecord s = app.services.valueAt(is);
22525            if (s.startRequested) {
22526                app.hasStartedServices = true;
22527                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
22528                    procState = ActivityManager.PROCESS_STATE_SERVICE;
22529                    app.adjType = "started-services";
22530                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
22531                }
22532                if (app.hasShownUi && app != mHomeProcess) {
22533                    // If this process has shown some UI, let it immediately
22534                    // go to the LRU list because it may be pretty heavy with
22535                    // UI stuff.  We'll tag it with a label just to help
22536                    // debug and understand what is going on.
22537                    if (adj > ProcessList.SERVICE_ADJ) {
22538                        app.adjType = "cch-started-ui-services";
22539                    }
22540                } else {
22541                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
22542                        // This service has seen some activity within
22543                        // recent memory, so we will keep its process ahead
22544                        // of the background processes.
22545                        if (adj > ProcessList.SERVICE_ADJ) {
22546                            adj = ProcessList.SERVICE_ADJ;
22547                            app.adjType = "started-services";
22548                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
22549                            app.cached = false;
22550                        }
22551                    }
22552                    // If we have let the service slide into the background
22553                    // state, still have some text describing what it is doing
22554                    // even though the service no longer has an impact.
22555                    if (adj > ProcessList.SERVICE_ADJ) {
22556                        app.adjType = "cch-started-services";
22557                    }
22558                }
22559            }
22560
22561            for (int conni = s.connections.size()-1;
22562                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22563                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22564                            || procState > ActivityManager.PROCESS_STATE_TOP);
22565                    conni--) {
22566                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
22567                for (int i = 0;
22568                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
22569                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22570                                || procState > ActivityManager.PROCESS_STATE_TOP);
22571                        i++) {
22572                    // XXX should compute this based on the max of
22573                    // all connected clients.
22574                    ConnectionRecord cr = clist.get(i);
22575                    if (cr.binding.client == app) {
22576                        // Binding to ourself is not interesting.
22577                        continue;
22578                    }
22579
22580                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
22581                        ProcessRecord client = cr.binding.client;
22582                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
22583                                TOP_APP, doingAll, now);
22584                        int clientProcState = client.curProcState;
22585                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22586                            // If the other app is cached for any reason, for purposes here
22587                            // we are going to consider it empty.  The specific cached state
22588                            // doesn't propagate except under certain conditions.
22589                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22590                        }
22591                        String adjType = null;
22592                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
22593                            // Not doing bind OOM management, so treat
22594                            // this guy more like a started service.
22595                            if (app.hasShownUi && app != mHomeProcess) {
22596                                // If this process has shown some UI, let it immediately
22597                                // go to the LRU list because it may be pretty heavy with
22598                                // UI stuff.  We'll tag it with a label just to help
22599                                // debug and understand what is going on.
22600                                if (adj > clientAdj) {
22601                                    adjType = "cch-bound-ui-services";
22602                                }
22603                                app.cached = false;
22604                                clientAdj = adj;
22605                                clientProcState = procState;
22606                            } else {
22607                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
22608                                    // This service has not seen activity within
22609                                    // recent memory, so allow it to drop to the
22610                                    // LRU list if there is no other reason to keep
22611                                    // it around.  We'll also tag it with a label just
22612                                    // to help debug and undertand what is going on.
22613                                    if (adj > clientAdj) {
22614                                        adjType = "cch-bound-services";
22615                                    }
22616                                    clientAdj = adj;
22617                                }
22618                            }
22619                        }
22620                        if (adj > clientAdj) {
22621                            // If this process has recently shown UI, and
22622                            // the process that is binding to it is less
22623                            // important than being visible, then we don't
22624                            // care about the binding as much as we care
22625                            // about letting this process get into the LRU
22626                            // list to be killed and restarted if needed for
22627                            // memory.
22628                            if (app.hasShownUi && app != mHomeProcess
22629                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22630                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
22631                                    adjType = "cch-bound-ui-services";
22632                                }
22633                            } else {
22634                                int newAdj;
22635                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
22636                                        |Context.BIND_IMPORTANT)) != 0) {
22637                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
22638                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
22639                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
22640                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
22641                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22642                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
22643                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
22644                                    newAdj = clientAdj;
22645                                } else {
22646                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
22647                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
22648                                    } else {
22649                                        newAdj = adj;
22650                                    }
22651                                }
22652                                if (!client.cached) {
22653                                    app.cached = false;
22654                                }
22655                                if (adj >  newAdj) {
22656                                    adj = newAdj;
22657                                    adjType = "service";
22658                                }
22659                            }
22660                        }
22661                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
22662                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
22663                            // This will treat important bound services identically to
22664                            // the top app, which may behave differently than generic
22665                            // foreground work.
22666                            if (client.curSchedGroup > schedGroup) {
22667                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
22668                                    schedGroup = client.curSchedGroup;
22669                                } else {
22670                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22671                                }
22672                            }
22673                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
22674                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
22675                                    // Special handling of clients who are in the top state.
22676                                    // We *may* want to consider this process to be in the
22677                                    // top state as well, but only if there is not another
22678                                    // reason for it to be running.  Being on the top is a
22679                                    // special state, meaning you are specifically running
22680                                    // for the current top app.  If the process is already
22681                                    // running in the background for some other reason, it
22682                                    // is more important to continue considering it to be
22683                                    // in the background state.
22684                                    mayBeTop = true;
22685                                    mayBeTopType = "service";
22686                                    mayBeTopSource = cr.binding.client;
22687                                    mayBeTopTarget = s.name;
22688                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22689                                } else {
22690                                    // Special handling for above-top states (persistent
22691                                    // processes).  These should not bring the current process
22692                                    // into the top state, since they are not on top.  Instead
22693                                    // give them the best state after that.
22694                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
22695                                        clientProcState =
22696                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22697                                    } else if (mWakefulness
22698                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
22699                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
22700                                                    != 0) {
22701                                        clientProcState =
22702                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22703                                    } else {
22704                                        clientProcState =
22705                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22706                                    }
22707                                }
22708                            }
22709                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
22710                            if (clientProcState <
22711                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22712                                clientProcState =
22713                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22714                            }
22715                        } else {
22716                            if (clientProcState <
22717                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
22718                                clientProcState =
22719                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
22720                            }
22721                        }
22722                        if (procState > clientProcState) {
22723                            procState = clientProcState;
22724                            if (adjType == null) {
22725                                adjType = "service";
22726                            }
22727                        }
22728                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22729                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
22730                            app.pendingUiClean = true;
22731                        }
22732                        if (adjType != null) {
22733                            app.adjType = adjType;
22734                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
22735                                    .REASON_SERVICE_IN_USE;
22736                            app.adjSource = cr.binding.client;
22737                            app.adjSourceProcState = clientProcState;
22738                            app.adjTarget = s.name;
22739                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
22740                                    + ": " + app + ", due to " + cr.binding.client
22741                                    + " adj=" + adj + " procState=" + procState);
22742                        }
22743                    }
22744                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
22745                        app.treatLikeActivity = true;
22746                    }
22747                    final ActivityRecord a = cr.activity;
22748                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
22749                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
22750                            (a.visible || a.state == ActivityState.RESUMED ||
22751                             a.state == ActivityState.PAUSING)) {
22752                            adj = ProcessList.FOREGROUND_APP_ADJ;
22753                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
22754                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
22755                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
22756                                } else {
22757                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22758                                }
22759                            }
22760                            app.cached = false;
22761                            app.adjType = "service";
22762                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
22763                                    .REASON_SERVICE_IN_USE;
22764                            app.adjSource = a;
22765                            app.adjSourceProcState = procState;
22766                            app.adjTarget = s.name;
22767                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
22768                                    + app);
22769                        }
22770                    }
22771                }
22772            }
22773        }
22774
22775        for (int provi = app.pubProviders.size()-1;
22776                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22777                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22778                        || procState > ActivityManager.PROCESS_STATE_TOP);
22779                provi--) {
22780            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
22781            for (int i = cpr.connections.size()-1;
22782                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22783                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22784                            || procState > ActivityManager.PROCESS_STATE_TOP);
22785                    i--) {
22786                ContentProviderConnection conn = cpr.connections.get(i);
22787                ProcessRecord client = conn.client;
22788                if (client == app) {
22789                    // Being our own client is not interesting.
22790                    continue;
22791                }
22792                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
22793                int clientProcState = client.curProcState;
22794                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22795                    // If the other app is cached for any reason, for purposes here
22796                    // we are going to consider it empty.
22797                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22798                }
22799                String adjType = null;
22800                if (adj > clientAdj) {
22801                    if (app.hasShownUi && app != mHomeProcess
22802                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22803                        adjType = "cch-ui-provider";
22804                    } else {
22805                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
22806                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
22807                        adjType = "provider";
22808                    }
22809                    app.cached &= client.cached;
22810                }
22811                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
22812                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
22813                        // Special handling of clients who are in the top state.
22814                        // We *may* want to consider this process to be in the
22815                        // top state as well, but only if there is not another
22816                        // reason for it to be running.  Being on the top is a
22817                        // special state, meaning you are specifically running
22818                        // for the current top app.  If the process is already
22819                        // running in the background for some other reason, it
22820                        // is more important to continue considering it to be
22821                        // in the background state.
22822                        mayBeTop = true;
22823                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22824                        mayBeTopType = adjType = "provider-top";
22825                        mayBeTopSource = client;
22826                        mayBeTopTarget = cpr.name;
22827                    } else {
22828                        // Special handling for above-top states (persistent
22829                        // processes).  These should not bring the current process
22830                        // into the top state, since they are not on top.  Instead
22831                        // give them the best state after that.
22832                        clientProcState =
22833                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22834                        if (adjType == null) {
22835                            adjType = "provider";
22836                        }
22837                    }
22838                }
22839                if (procState > clientProcState) {
22840                    procState = clientProcState;
22841                }
22842                if (client.curSchedGroup > schedGroup) {
22843                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22844                }
22845                if (adjType != null) {
22846                    app.adjType = adjType;
22847                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
22848                            .REASON_PROVIDER_IN_USE;
22849                    app.adjSource = client;
22850                    app.adjSourceProcState = clientProcState;
22851                    app.adjTarget = cpr.name;
22852                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
22853                            + ": " + app + ", due to " + client
22854                            + " adj=" + adj + " procState=" + procState);
22855                }
22856            }
22857            // If the provider has external (non-framework) process
22858            // dependencies, ensure that its adjustment is at least
22859            // FOREGROUND_APP_ADJ.
22860            if (cpr.hasExternalProcessHandles()) {
22861                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
22862                    adj = ProcessList.FOREGROUND_APP_ADJ;
22863                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22864                    app.cached = false;
22865                    app.adjType = "ext-provider";
22866                    app.adjTarget = cpr.name;
22867                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
22868                }
22869                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22870                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22871                }
22872            }
22873        }
22874
22875        if (app.lastProviderTime > 0 &&
22876                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
22877            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
22878                adj = ProcessList.PREVIOUS_APP_ADJ;
22879                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22880                app.cached = false;
22881                app.adjType = "recent-provider";
22882                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
22883            }
22884            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22885                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22886                app.adjType = "recent-provider";
22887                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
22888            }
22889        }
22890
22891        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
22892            // A client of one of our services or providers is in the top state.  We
22893            // *may* want to be in the top state, but not if we are already running in
22894            // the background for some other reason.  For the decision here, we are going
22895            // to pick out a few specific states that we want to remain in when a client
22896            // is top (states that tend to be longer-term) and otherwise allow it to go
22897            // to the top state.
22898            switch (procState) {
22899                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
22900                case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
22901                    // Something else is keeping it at this level, just leave it.
22902                    break;
22903                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
22904                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
22905                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
22906                case ActivityManager.PROCESS_STATE_SERVICE:
22907                    // These all are longer-term states, so pull them up to the top
22908                    // of the background states, but not all the way to the top state.
22909                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22910                    app.adjType = mayBeTopType;
22911                    app.adjSource = mayBeTopSource;
22912                    app.adjTarget = mayBeTopTarget;
22913                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
22914                            + ": " + app + ", due to " + mayBeTopSource
22915                            + " adj=" + adj + " procState=" + procState);
22916                    break;
22917                default:
22918                    // Otherwise, top is a better choice, so take it.
22919                    procState = ActivityManager.PROCESS_STATE_TOP;
22920                    app.adjType = mayBeTopType;
22921                    app.adjSource = mayBeTopSource;
22922                    app.adjTarget = mayBeTopTarget;
22923                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
22924                            + ": " + app + ", due to " + mayBeTopSource
22925                            + " adj=" + adj + " procState=" + procState);
22926                    break;
22927            }
22928        }
22929
22930        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
22931            if (app.hasClientActivities) {
22932                // This is a cached process, but with client activities.  Mark it so.
22933                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
22934                app.adjType = "cch-client-act";
22935            } else if (app.treatLikeActivity) {
22936                // This is a cached process, but somebody wants us to treat it like it has
22937                // an activity, okay!
22938                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
22939                app.adjType = "cch-as-act";
22940            }
22941        }
22942
22943        if (adj == ProcessList.SERVICE_ADJ) {
22944            if (doingAll) {
22945                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
22946                mNewNumServiceProcs++;
22947                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
22948                if (!app.serviceb) {
22949                    // This service isn't far enough down on the LRU list to
22950                    // normally be a B service, but if we are low on RAM and it
22951                    // is large we want to force it down since we would prefer to
22952                    // keep launcher over it.
22953                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
22954                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
22955                        app.serviceHighRam = true;
22956                        app.serviceb = true;
22957                        //Slog.i(TAG, "ADJ " + app + " high ram!");
22958                    } else {
22959                        mNewNumAServiceProcs++;
22960                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
22961                    }
22962                } else {
22963                    app.serviceHighRam = false;
22964                }
22965            }
22966            if (app.serviceb) {
22967                adj = ProcessList.SERVICE_B_ADJ;
22968            }
22969        }
22970
22971        app.curRawAdj = adj;
22972
22973        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
22974        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
22975        if (adj > app.maxAdj) {
22976            adj = app.maxAdj;
22977            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
22978                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22979            }
22980        }
22981
22982        // Do final modification to adj.  Everything we do between here and applying
22983        // the final setAdj must be done in this function, because we will also use
22984        // it when computing the final cached adj later.  Note that we don't need to
22985        // worry about this for max adj above, since max adj will always be used to
22986        // keep it out of the cached vaues.
22987        app.curAdj = app.modifyRawOomAdj(adj);
22988        app.curSchedGroup = schedGroup;
22989        app.curProcState = procState;
22990        app.foregroundActivities = foregroundActivities;
22991
22992        return app.curRawAdj;
22993    }
22994
22995    /**
22996     * Record new PSS sample for a process.
22997     */
22998    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
22999            long pssDuration, long now) {
23000        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
23001                swapPss * 1024);
23002        proc.lastPssTime = now;
23003        proc.baseProcessTracker.addPss(pss, uss, true, ProcessStats.ADD_PSS_INTERNAL,
23004                pssDuration, proc.pkgList);
23005        if (DEBUG_PSS) Slog.d(TAG_PSS,
23006                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
23007                + " state=" + ProcessList.makeProcStateString(procState));
23008        if (proc.initialIdlePss == 0) {
23009            proc.initialIdlePss = pss;
23010        }
23011        proc.lastPss = pss;
23012        proc.lastSwapPss = swapPss;
23013        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
23014            proc.lastCachedPss = pss;
23015            proc.lastCachedSwapPss = swapPss;
23016        }
23017
23018        final SparseArray<Pair<Long, String>> watchUids
23019                = mMemWatchProcesses.getMap().get(proc.processName);
23020        Long check = null;
23021        if (watchUids != null) {
23022            Pair<Long, String> val = watchUids.get(proc.uid);
23023            if (val == null) {
23024                val = watchUids.get(0);
23025            }
23026            if (val != null) {
23027                check = val.first;
23028            }
23029        }
23030        if (check != null) {
23031            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
23032                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23033                if (!isDebuggable) {
23034                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
23035                        isDebuggable = true;
23036                    }
23037                }
23038                if (isDebuggable) {
23039                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
23040                    final ProcessRecord myProc = proc;
23041                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
23042                    mMemWatchDumpProcName = proc.processName;
23043                    mMemWatchDumpFile = heapdumpFile.toString();
23044                    mMemWatchDumpPid = proc.pid;
23045                    mMemWatchDumpUid = proc.uid;
23046                    BackgroundThread.getHandler().post(new Runnable() {
23047                        @Override
23048                        public void run() {
23049                            revokeUriPermission(ActivityThread.currentActivityThread()
23050                                            .getApplicationThread(),
23051                                    null, DumpHeapActivity.JAVA_URI,
23052                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
23053                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
23054                                    UserHandle.myUserId());
23055                            ParcelFileDescriptor fd = null;
23056                            try {
23057                                heapdumpFile.delete();
23058                                fd = ParcelFileDescriptor.open(heapdumpFile,
23059                                        ParcelFileDescriptor.MODE_CREATE |
23060                                                ParcelFileDescriptor.MODE_TRUNCATE |
23061                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
23062                                                ParcelFileDescriptor.MODE_APPEND);
23063                                IApplicationThread thread = myProc.thread;
23064                                if (thread != null) {
23065                                    try {
23066                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
23067                                                "Requesting dump heap from "
23068                                                + myProc + " to " + heapdumpFile);
23069                                        thread.dumpHeap(/* managed= */ true,
23070                                                /* mallocInfo= */ false, /* runGc= */ false,
23071                                                heapdumpFile.toString(), fd);
23072                                    } catch (RemoteException e) {
23073                                    }
23074                                }
23075                            } catch (FileNotFoundException e) {
23076                                e.printStackTrace();
23077                            } finally {
23078                                if (fd != null) {
23079                                    try {
23080                                        fd.close();
23081                                    } catch (IOException e) {
23082                                    }
23083                                }
23084                            }
23085                        }
23086                    });
23087                } else {
23088                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
23089                            + ", but debugging not enabled");
23090                }
23091            }
23092        }
23093    }
23094
23095    /**
23096     * Schedule PSS collection of a process.
23097     */
23098    void requestPssLocked(ProcessRecord proc, int procState) {
23099        if (mPendingPssProcesses.contains(proc)) {
23100            return;
23101        }
23102        if (mPendingPssProcesses.size() == 0) {
23103            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23104        }
23105        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
23106        proc.pssProcState = procState;
23107        mPendingPssProcesses.add(proc);
23108    }
23109
23110    /**
23111     * Schedule PSS collection of all processes.
23112     */
23113    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
23114        if (!always) {
23115            if (now < (mLastFullPssTime +
23116                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
23117                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
23118                return;
23119            }
23120        }
23121        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
23122        mLastFullPssTime = now;
23123        mFullPssPending = true;
23124        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
23125        mPendingPssProcesses.clear();
23126        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23127            ProcessRecord app = mLruProcesses.get(i);
23128            if (app.thread == null
23129                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
23130                continue;
23131            }
23132            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
23133                app.pssProcState = app.setProcState;
23134                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
23135                        mTestPssMode, isSleepingLocked(), now);
23136                mPendingPssProcesses.add(app);
23137            }
23138        }
23139        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23140    }
23141
23142    public void setTestPssMode(boolean enabled) {
23143        synchronized (this) {
23144            mTestPssMode = enabled;
23145            if (enabled) {
23146                // Whenever we enable the mode, we want to take a snapshot all of current
23147                // process mem use.
23148                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
23149            }
23150        }
23151    }
23152
23153    /**
23154     * Ask a given process to GC right now.
23155     */
23156    final void performAppGcLocked(ProcessRecord app) {
23157        try {
23158            app.lastRequestedGc = SystemClock.uptimeMillis();
23159            if (app.thread != null) {
23160                if (app.reportLowMemory) {
23161                    app.reportLowMemory = false;
23162                    app.thread.scheduleLowMemory();
23163                } else {
23164                    app.thread.processInBackground();
23165                }
23166            }
23167        } catch (Exception e) {
23168            // whatever.
23169        }
23170    }
23171
23172    /**
23173     * Returns true if things are idle enough to perform GCs.
23174     */
23175    private final boolean canGcNowLocked() {
23176        boolean processingBroadcasts = false;
23177        for (BroadcastQueue q : mBroadcastQueues) {
23178            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
23179                processingBroadcasts = true;
23180            }
23181        }
23182        return !processingBroadcasts
23183                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
23184    }
23185
23186    /**
23187     * Perform GCs on all processes that are waiting for it, but only
23188     * if things are idle.
23189     */
23190    final void performAppGcsLocked() {
23191        final int N = mProcessesToGc.size();
23192        if (N <= 0) {
23193            return;
23194        }
23195        if (canGcNowLocked()) {
23196            while (mProcessesToGc.size() > 0) {
23197                ProcessRecord proc = mProcessesToGc.remove(0);
23198                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
23199                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
23200                            <= SystemClock.uptimeMillis()) {
23201                        // To avoid spamming the system, we will GC processes one
23202                        // at a time, waiting a few seconds between each.
23203                        performAppGcLocked(proc);
23204                        scheduleAppGcsLocked();
23205                        return;
23206                    } else {
23207                        // It hasn't been long enough since we last GCed this
23208                        // process...  put it in the list to wait for its time.
23209                        addProcessToGcListLocked(proc);
23210                        break;
23211                    }
23212                }
23213            }
23214
23215            scheduleAppGcsLocked();
23216        }
23217    }
23218
23219    /**
23220     * If all looks good, perform GCs on all processes waiting for them.
23221     */
23222    final void performAppGcsIfAppropriateLocked() {
23223        if (canGcNowLocked()) {
23224            performAppGcsLocked();
23225            return;
23226        }
23227        // Still not idle, wait some more.
23228        scheduleAppGcsLocked();
23229    }
23230
23231    /**
23232     * Schedule the execution of all pending app GCs.
23233     */
23234    final void scheduleAppGcsLocked() {
23235        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
23236
23237        if (mProcessesToGc.size() > 0) {
23238            // Schedule a GC for the time to the next process.
23239            ProcessRecord proc = mProcessesToGc.get(0);
23240            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
23241
23242            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
23243            long now = SystemClock.uptimeMillis();
23244            if (when < (now+mConstants.GC_TIMEOUT)) {
23245                when = now + mConstants.GC_TIMEOUT;
23246            }
23247            mHandler.sendMessageAtTime(msg, when);
23248        }
23249    }
23250
23251    /**
23252     * Add a process to the array of processes waiting to be GCed.  Keeps the
23253     * list in sorted order by the last GC time.  The process can't already be
23254     * on the list.
23255     */
23256    final void addProcessToGcListLocked(ProcessRecord proc) {
23257        boolean added = false;
23258        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
23259            if (mProcessesToGc.get(i).lastRequestedGc <
23260                    proc.lastRequestedGc) {
23261                added = true;
23262                mProcessesToGc.add(i+1, proc);
23263                break;
23264            }
23265        }
23266        if (!added) {
23267            mProcessesToGc.add(0, proc);
23268        }
23269    }
23270
23271    /**
23272     * Set up to ask a process to GC itself.  This will either do it
23273     * immediately, or put it on the list of processes to gc the next
23274     * time things are idle.
23275     */
23276    final void scheduleAppGcLocked(ProcessRecord app) {
23277        long now = SystemClock.uptimeMillis();
23278        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
23279            return;
23280        }
23281        if (!mProcessesToGc.contains(app)) {
23282            addProcessToGcListLocked(app);
23283            scheduleAppGcsLocked();
23284        }
23285    }
23286
23287    final void checkExcessivePowerUsageLocked() {
23288        updateCpuStatsNow();
23289
23290        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
23291        boolean doCpuKills = true;
23292        if (mLastPowerCheckUptime == 0) {
23293            doCpuKills = false;
23294        }
23295        final long curUptime = SystemClock.uptimeMillis();
23296        final long uptimeSince = curUptime - mLastPowerCheckUptime;
23297        mLastPowerCheckUptime = curUptime;
23298        int i = mLruProcesses.size();
23299        while (i > 0) {
23300            i--;
23301            ProcessRecord app = mLruProcesses.get(i);
23302            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
23303                if (app.lastCpuTime <= 0) {
23304                    continue;
23305                }
23306                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
23307                if (DEBUG_POWER) {
23308                    StringBuilder sb = new StringBuilder(128);
23309                    sb.append("CPU for ");
23310                    app.toShortString(sb);
23311                    sb.append(": over ");
23312                    TimeUtils.formatDuration(uptimeSince, sb);
23313                    sb.append(" used ");
23314                    TimeUtils.formatDuration(cputimeUsed, sb);
23315                    sb.append(" (");
23316                    sb.append((cputimeUsed*100)/uptimeSince);
23317                    sb.append("%)");
23318                    Slog.i(TAG_POWER, sb.toString());
23319                }
23320                // If the process has used too much CPU over the last duration, the
23321                // user probably doesn't want this, so kill!
23322                if (doCpuKills && uptimeSince > 0) {
23323                    // What is the limit for this process?
23324                    int cpuLimit;
23325                    long checkDur = curUptime - app.whenUnimportant;
23326                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
23327                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
23328                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
23329                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
23330                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
23331                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
23332                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
23333                    } else {
23334                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
23335                    }
23336                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
23337                        synchronized (stats) {
23338                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
23339                                    uptimeSince, cputimeUsed);
23340                        }
23341                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
23342                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
23343                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
23344                    }
23345                }
23346                app.lastCpuTime = app.curCpuTime;
23347            }
23348        }
23349    }
23350
23351    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
23352            long nowElapsed) {
23353        boolean success = true;
23354
23355        if (app.curRawAdj != app.setRawAdj) {
23356            app.setRawAdj = app.curRawAdj;
23357        }
23358
23359        int changes = 0;
23360
23361        if (app.curAdj != app.setAdj) {
23362            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
23363            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
23364                String msg = "Set " + app.pid + " " + app.processName + " adj "
23365                        + app.curAdj + ": " + app.adjType;
23366                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23367            }
23368            app.setAdj = app.curAdj;
23369            app.verifiedAdj = ProcessList.INVALID_ADJ;
23370        }
23371
23372        if (app.setSchedGroup != app.curSchedGroup) {
23373            int oldSchedGroup = app.setSchedGroup;
23374            app.setSchedGroup = app.curSchedGroup;
23375            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
23376                String msg = "Setting sched group of " + app.processName
23377                        + " to " + app.curSchedGroup;
23378                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23379            }
23380            if (app.waitingToKill != null && app.curReceivers.isEmpty()
23381                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
23382                app.kill(app.waitingToKill, true);
23383                success = false;
23384            } else {
23385                int processGroup;
23386                switch (app.curSchedGroup) {
23387                    case ProcessList.SCHED_GROUP_BACKGROUND:
23388                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
23389                        break;
23390                    case ProcessList.SCHED_GROUP_TOP_APP:
23391                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
23392                        processGroup = THREAD_GROUP_TOP_APP;
23393                        break;
23394                    default:
23395                        processGroup = THREAD_GROUP_DEFAULT;
23396                        break;
23397                }
23398                long oldId = Binder.clearCallingIdentity();
23399                try {
23400                    setProcessGroup(app.pid, processGroup);
23401                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
23402                        // do nothing if we already switched to RT
23403                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23404                            mVrController.onTopProcChangedLocked(app);
23405                            if (mUseFifoUiScheduling) {
23406                                // Switch UI pipeline for app to SCHED_FIFO
23407                                app.savedPriority = Process.getThreadPriority(app.pid);
23408                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
23409                                if (app.renderThreadTid != 0) {
23410                                    scheduleAsFifoPriority(app.renderThreadTid,
23411                                        /* suppressLogs */true);
23412                                    if (DEBUG_OOM_ADJ) {
23413                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
23414                                            app.renderThreadTid + ") to FIFO");
23415                                    }
23416                                } else {
23417                                    if (DEBUG_OOM_ADJ) {
23418                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
23419                                    }
23420                                }
23421                            } else {
23422                                // Boost priority for top app UI and render threads
23423                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
23424                                if (app.renderThreadTid != 0) {
23425                                    try {
23426                                        setThreadPriority(app.renderThreadTid,
23427                                                TOP_APP_PRIORITY_BOOST);
23428                                    } catch (IllegalArgumentException e) {
23429                                        // thread died, ignore
23430                                    }
23431                                }
23432                            }
23433                        }
23434                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
23435                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23436                        mVrController.onTopProcChangedLocked(app);
23437                        if (mUseFifoUiScheduling) {
23438                            try {
23439                                // Reset UI pipeline to SCHED_OTHER
23440                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
23441                                setThreadPriority(app.pid, app.savedPriority);
23442                                if (app.renderThreadTid != 0) {
23443                                    setThreadScheduler(app.renderThreadTid,
23444                                        SCHED_OTHER, 0);
23445                                    setThreadPriority(app.renderThreadTid, -4);
23446                                }
23447                            } catch (IllegalArgumentException e) {
23448                                Slog.w(TAG,
23449                                        "Failed to set scheduling policy, thread does not exist:\n"
23450                                                + e);
23451                            } catch (SecurityException e) {
23452                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
23453                            }
23454                        } else {
23455                            // Reset priority for top app UI and render threads
23456                            setThreadPriority(app.pid, 0);
23457                            if (app.renderThreadTid != 0) {
23458                                setThreadPriority(app.renderThreadTid, 0);
23459                            }
23460                        }
23461                    }
23462                } catch (Exception e) {
23463                    if (false) {
23464                        Slog.w(TAG, "Failed setting process group of " + app.pid
23465                                + " to " + app.curSchedGroup);
23466                        Slog.w(TAG, "at location", e);
23467                    }
23468                } finally {
23469                    Binder.restoreCallingIdentity(oldId);
23470                }
23471            }
23472        }
23473        if (app.repForegroundActivities != app.foregroundActivities) {
23474            app.repForegroundActivities = app.foregroundActivities;
23475            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
23476        }
23477        if (app.repProcState != app.curProcState) {
23478            app.repProcState = app.curProcState;
23479            if (app.thread != null) {
23480                try {
23481                    if (false) {
23482                        //RuntimeException h = new RuntimeException("here");
23483                        Slog.i(TAG, "Sending new process state " + app.repProcState
23484                                + " to " + app /*, h*/);
23485                    }
23486                    app.thread.setProcessState(app.repProcState);
23487                } catch (RemoteException e) {
23488                }
23489            }
23490        }
23491        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
23492                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
23493            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
23494                // Experimental code to more aggressively collect pss while
23495                // running test...  the problem is that this tends to collect
23496                // the data right when a process is transitioning between process
23497                // states, which well tend to give noisy data.
23498                long start = SystemClock.uptimeMillis();
23499                long startTime = SystemClock.currentThreadTimeMillis();
23500                long pss = Debug.getPss(app.pid, mTmpLong, null);
23501                long endTime = SystemClock.currentThreadTimeMillis();
23502                recordPssSampleLocked(app, app.curProcState, pss, endTime-startTime,
23503                        mTmpLong[0], mTmpLong[1], now);
23504                mPendingPssProcesses.remove(app);
23505                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
23506                        + " to " + app.curProcState + ": "
23507                        + (SystemClock.uptimeMillis()-start) + "ms");
23508            }
23509            app.lastStateTime = now;
23510            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
23511                    mTestPssMode, isSleepingLocked(), now);
23512            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
23513                    + ProcessList.makeProcStateString(app.setProcState) + " to "
23514                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
23515                    + (app.nextPssTime-now) + ": " + app);
23516        } else {
23517            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
23518                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
23519                    mTestPssMode)))) {
23520                requestPssLocked(app, app.setProcState);
23521                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
23522                        mTestPssMode, isSleepingLocked(), now);
23523            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
23524                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
23525        }
23526        if (app.setProcState != app.curProcState) {
23527            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
23528                String msg = "Proc state change of " + app.processName
23529                        + " to " + app.curProcState;
23530                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23531            }
23532            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
23533            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
23534            if (setImportant && !curImportant) {
23535                // This app is no longer something we consider important enough to allow to
23536                // use arbitrary amounts of battery power.  Note
23537                // its current CPU time to later know to kill it if
23538                // it is not behaving well.
23539                app.whenUnimportant = now;
23540                app.lastCpuTime = 0;
23541            }
23542            // Inform UsageStats of important process state change
23543            // Must be called before updating setProcState
23544            maybeUpdateUsageStatsLocked(app, nowElapsed);
23545
23546            app.setProcState = app.curProcState;
23547            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
23548                app.notCachedSinceIdle = false;
23549            }
23550            if (!doingAll) {
23551                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
23552            } else {
23553                app.procStateChanged = true;
23554            }
23555        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
23556                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
23557            // For apps that sit around for a long time in the interactive state, we need
23558            // to report this at least once a day so they don't go idle.
23559            maybeUpdateUsageStatsLocked(app, nowElapsed);
23560        }
23561
23562        if (changes != 0) {
23563            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23564                    "Changes in " + app + ": " + changes);
23565            int i = mPendingProcessChanges.size()-1;
23566            ProcessChangeItem item = null;
23567            while (i >= 0) {
23568                item = mPendingProcessChanges.get(i);
23569                if (item.pid == app.pid) {
23570                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23571                            "Re-using existing item: " + item);
23572                    break;
23573                }
23574                i--;
23575            }
23576            if (i < 0) {
23577                // No existing item in pending changes; need a new one.
23578                final int NA = mAvailProcessChanges.size();
23579                if (NA > 0) {
23580                    item = mAvailProcessChanges.remove(NA-1);
23581                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23582                            "Retrieving available item: " + item);
23583                } else {
23584                    item = new ProcessChangeItem();
23585                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23586                            "Allocating new item: " + item);
23587                }
23588                item.changes = 0;
23589                item.pid = app.pid;
23590                item.uid = app.info.uid;
23591                if (mPendingProcessChanges.size() == 0) {
23592                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23593                            "*** Enqueueing dispatch processes changed!");
23594                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
23595                }
23596                mPendingProcessChanges.add(item);
23597            }
23598            item.changes |= changes;
23599            item.foregroundActivities = app.repForegroundActivities;
23600            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23601                    "Item " + Integer.toHexString(System.identityHashCode(item))
23602                    + " " + app.toShortString() + ": changes=" + item.changes
23603                    + " foreground=" + item.foregroundActivities
23604                    + " type=" + app.adjType + " source=" + app.adjSource
23605                    + " target=" + app.adjTarget);
23606        }
23607
23608        return success;
23609    }
23610
23611    private boolean isEphemeralLocked(int uid) {
23612        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
23613        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
23614            return false;
23615        }
23616        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
23617                packages[0]);
23618    }
23619
23620    @VisibleForTesting
23621    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
23622        final UidRecord.ChangeItem pendingChange;
23623        if (uidRec == null || uidRec.pendingChange == null) {
23624            if (mPendingUidChanges.size() == 0) {
23625                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23626                        "*** Enqueueing dispatch uid changed!");
23627                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
23628            }
23629            final int NA = mAvailUidChanges.size();
23630            if (NA > 0) {
23631                pendingChange = mAvailUidChanges.remove(NA-1);
23632                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23633                        "Retrieving available item: " + pendingChange);
23634            } else {
23635                pendingChange = new UidRecord.ChangeItem();
23636                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23637                        "Allocating new item: " + pendingChange);
23638            }
23639            if (uidRec != null) {
23640                uidRec.pendingChange = pendingChange;
23641                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
23642                    // If this uid is going away, and we haven't yet reported it is gone,
23643                    // then do so now.
23644                    change |= UidRecord.CHANGE_IDLE;
23645                }
23646            } else if (uid < 0) {
23647                throw new IllegalArgumentException("No UidRecord or uid");
23648            }
23649            pendingChange.uidRecord = uidRec;
23650            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
23651            mPendingUidChanges.add(pendingChange);
23652        } else {
23653            pendingChange = uidRec.pendingChange;
23654            // If there is no change in idle or active state, then keep whatever was pending.
23655            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
23656                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
23657                        | UidRecord.CHANGE_ACTIVE));
23658            }
23659            // If there is no change in cached or uncached state, then keep whatever was pending.
23660            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
23661                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
23662                        | UidRecord.CHANGE_UNCACHED));
23663            }
23664            // If this is a report of the UID being gone, then we shouldn't keep any previous
23665            // report of it being active or cached.  (That is, a gone uid is never active,
23666            // and never cached.)
23667            if ((change & UidRecord.CHANGE_GONE) != 0) {
23668                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
23669                if (!uidRec.idle) {
23670                    // If this uid is going away, and we haven't yet reported it is gone,
23671                    // then do so now.
23672                    change |= UidRecord.CHANGE_IDLE;
23673                }
23674            }
23675        }
23676        pendingChange.change = change;
23677        pendingChange.processState = uidRec != null
23678                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
23679        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
23680        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
23681        if (uidRec != null) {
23682            uidRec.lastReportedChange = change;
23683            uidRec.updateLastDispatchedProcStateSeq(change);
23684        }
23685
23686        // Directly update the power manager, since we sit on top of it and it is critical
23687        // it be kept in sync (so wake locks will be held as soon as appropriate).
23688        if (mLocalPowerManager != null) {
23689            // TO DO: dispatch cached/uncached changes here, so we don't need to report
23690            // all proc state changes.
23691            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
23692                mLocalPowerManager.uidActive(pendingChange.uid);
23693            }
23694            if ((change & UidRecord.CHANGE_IDLE) != 0) {
23695                mLocalPowerManager.uidIdle(pendingChange.uid);
23696            }
23697            if ((change & UidRecord.CHANGE_GONE) != 0) {
23698                mLocalPowerManager.uidGone(pendingChange.uid);
23699            } else {
23700                mLocalPowerManager.updateUidProcState(pendingChange.uid,
23701                        pendingChange.processState);
23702            }
23703        }
23704    }
23705
23706    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
23707            String authority) {
23708        if (app == null) return;
23709        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23710            UserState userState = mUserController.getStartedUserState(app.userId);
23711            if (userState == null) return;
23712            final long now = SystemClock.elapsedRealtime();
23713            Long lastReported = userState.mProviderLastReportedFg.get(authority);
23714            if (lastReported == null || lastReported < now - 60 * 1000L) {
23715                if (mSystemReady) {
23716                    // Cannot touch the user stats if not system ready
23717                    mUsageStatsService.reportContentProviderUsage(
23718                            authority, providerPkgName, app.userId);
23719                }
23720                userState.mProviderLastReportedFg.put(authority, now);
23721            }
23722        }
23723    }
23724
23725    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
23726        if (DEBUG_USAGE_STATS) {
23727            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
23728                    + "] state changes: old = " + app.setProcState + ", new = "
23729                    + app.curProcState);
23730        }
23731        if (mUsageStatsService == null) {
23732            return;
23733        }
23734        boolean isInteraction;
23735        // To avoid some abuse patterns, we are going to be careful about what we consider
23736        // to be an app interaction.  Being the top activity doesn't count while the display
23737        // is sleeping, nor do short foreground services.
23738        if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
23739            isInteraction = true;
23740            app.fgInteractionTime = 0;
23741        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
23742            if (app.fgInteractionTime == 0) {
23743                app.fgInteractionTime = nowElapsed;
23744                isInteraction = false;
23745            } else {
23746                isInteraction = nowElapsed > app.fgInteractionTime
23747                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
23748            }
23749        } else {
23750            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23751            app.fgInteractionTime = 0;
23752        }
23753        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
23754                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
23755            app.interactionEventTime = nowElapsed;
23756            String[] packages = app.getPackageList();
23757            if (packages != null) {
23758                for (int i = 0; i < packages.length; i++) {
23759                    mUsageStatsService.reportEvent(packages[i], app.userId,
23760                            UsageEvents.Event.SYSTEM_INTERACTION);
23761                }
23762            }
23763        }
23764        app.reportedInteraction = isInteraction;
23765        if (!isInteraction) {
23766            app.interactionEventTime = 0;
23767        }
23768    }
23769
23770    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
23771        if (proc.thread != null) {
23772            if (proc.baseProcessTracker != null) {
23773                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
23774            }
23775        }
23776    }
23777
23778    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
23779            ProcessRecord TOP_APP, boolean doingAll, long now) {
23780        if (app.thread == null) {
23781            return false;
23782        }
23783
23784        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
23785
23786        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
23787    }
23788
23789    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
23790            boolean oomAdj) {
23791        if (isForeground != proc.foregroundServices) {
23792            proc.foregroundServices = isForeground;
23793            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
23794                    proc.info.uid);
23795            if (isForeground) {
23796                if (curProcs == null) {
23797                    curProcs = new ArrayList<ProcessRecord>();
23798                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
23799                }
23800                if (!curProcs.contains(proc)) {
23801                    curProcs.add(proc);
23802                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
23803                            proc.info.packageName, proc.info.uid);
23804                }
23805            } else {
23806                if (curProcs != null) {
23807                    if (curProcs.remove(proc)) {
23808                        mBatteryStatsService.noteEvent(
23809                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
23810                                proc.info.packageName, proc.info.uid);
23811                        if (curProcs.size() <= 0) {
23812                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
23813                        }
23814                    }
23815                }
23816            }
23817            if (oomAdj) {
23818                updateOomAdjLocked();
23819            }
23820        }
23821    }
23822
23823    private final ActivityRecord resumedAppLocked() {
23824        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
23825        String pkg;
23826        int uid;
23827        if (act != null) {
23828            pkg = act.packageName;
23829            uid = act.info.applicationInfo.uid;
23830        } else {
23831            pkg = null;
23832            uid = -1;
23833        }
23834        // Has the UID or resumed package name changed?
23835        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
23836                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
23837            if (mCurResumedPackage != null) {
23838                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
23839                        mCurResumedPackage, mCurResumedUid);
23840            }
23841            mCurResumedPackage = pkg;
23842            mCurResumedUid = uid;
23843            if (mCurResumedPackage != null) {
23844                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
23845                        mCurResumedPackage, mCurResumedUid);
23846            }
23847        }
23848        return act;
23849    }
23850
23851    /**
23852     * Update OomAdj for a specific process.
23853     * @param app The process to update
23854     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
23855     *                  if necessary, or skip.
23856     * @return whether updateOomAdjLocked(app) was successful.
23857     */
23858    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
23859        final ActivityRecord TOP_ACT = resumedAppLocked();
23860        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
23861        final boolean wasCached = app.cached;
23862
23863        mAdjSeq++;
23864
23865        // This is the desired cached adjusment we want to tell it to use.
23866        // If our app is currently cached, we know it, and that is it.  Otherwise,
23867        // we don't know it yet, and it needs to now be cached we will then
23868        // need to do a complete oom adj.
23869        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
23870                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
23871        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
23872                SystemClock.uptimeMillis());
23873        if (oomAdjAll
23874                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
23875            // Changed to/from cached state, so apps after it in the LRU
23876            // list may also be changed.
23877            updateOomAdjLocked();
23878        }
23879        return success;
23880    }
23881
23882    final void updateOomAdjLocked() {
23883        final ActivityRecord TOP_ACT = resumedAppLocked();
23884        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
23885        final long now = SystemClock.uptimeMillis();
23886        final long nowElapsed = SystemClock.elapsedRealtime();
23887        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
23888        final int N = mLruProcesses.size();
23889
23890        if (false) {
23891            RuntimeException e = new RuntimeException();
23892            e.fillInStackTrace();
23893            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
23894        }
23895
23896        // Reset state in all uid records.
23897        for (int i=mActiveUids.size()-1; i>=0; i--) {
23898            final UidRecord uidRec = mActiveUids.valueAt(i);
23899            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23900                    "Starting update of " + uidRec);
23901            uidRec.reset();
23902        }
23903
23904        mStackSupervisor.rankTaskLayersIfNeeded();
23905
23906        mAdjSeq++;
23907        mNewNumServiceProcs = 0;
23908        mNewNumAServiceProcs = 0;
23909
23910        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
23911        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
23912
23913        // Let's determine how many processes we have running vs.
23914        // how many slots we have for background processes; we may want
23915        // to put multiple processes in a slot of there are enough of
23916        // them.
23917        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
23918                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
23919        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
23920        if (numEmptyProcs > cachedProcessLimit) {
23921            // If there are more empty processes than our limit on cached
23922            // processes, then use the cached process limit for the factor.
23923            // This ensures that the really old empty processes get pushed
23924            // down to the bottom, so if we are running low on memory we will
23925            // have a better chance at keeping around more cached processes
23926            // instead of a gazillion empty processes.
23927            numEmptyProcs = cachedProcessLimit;
23928        }
23929        int emptyFactor = numEmptyProcs/numSlots;
23930        if (emptyFactor < 1) emptyFactor = 1;
23931        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
23932        if (cachedFactor < 1) cachedFactor = 1;
23933        int stepCached = 0;
23934        int stepEmpty = 0;
23935        int numCached = 0;
23936        int numEmpty = 0;
23937        int numTrimming = 0;
23938
23939        mNumNonCachedProcs = 0;
23940        mNumCachedHiddenProcs = 0;
23941
23942        // First update the OOM adjustment for each of the
23943        // application processes based on their current state.
23944        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
23945        int nextCachedAdj = curCachedAdj+1;
23946        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
23947        int nextEmptyAdj = curEmptyAdj+2;
23948        for (int i=N-1; i>=0; i--) {
23949            ProcessRecord app = mLruProcesses.get(i);
23950            if (!app.killedByAm && app.thread != null) {
23951                app.procStateChanged = false;
23952                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
23953
23954                // If we haven't yet assigned the final cached adj
23955                // to the process, do that now.
23956                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
23957                    switch (app.curProcState) {
23958                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
23959                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
23960                        case ActivityManager.PROCESS_STATE_CACHED_RECENT:
23961                            // This process is a cached process holding activities...
23962                            // assign it the next cached value for that type, and then
23963                            // step that cached level.
23964                            app.curRawAdj = curCachedAdj;
23965                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
23966                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
23967                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
23968                                    + ")");
23969                            if (curCachedAdj != nextCachedAdj) {
23970                                stepCached++;
23971                                if (stepCached >= cachedFactor) {
23972                                    stepCached = 0;
23973                                    curCachedAdj = nextCachedAdj;
23974                                    nextCachedAdj += 2;
23975                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
23976                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
23977                                    }
23978                                }
23979                            }
23980                            break;
23981                        default:
23982                            // For everything else, assign next empty cached process
23983                            // level and bump that up.  Note that this means that
23984                            // long-running services that have dropped down to the
23985                            // cached level will be treated as empty (since their process
23986                            // state is still as a service), which is what we want.
23987                            app.curRawAdj = curEmptyAdj;
23988                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
23989                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
23990                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
23991                                    + ")");
23992                            if (curEmptyAdj != nextEmptyAdj) {
23993                                stepEmpty++;
23994                                if (stepEmpty >= emptyFactor) {
23995                                    stepEmpty = 0;
23996                                    curEmptyAdj = nextEmptyAdj;
23997                                    nextEmptyAdj += 2;
23998                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
23999                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
24000                                    }
24001                                }
24002                            }
24003                            break;
24004                    }
24005                }
24006
24007                applyOomAdjLocked(app, true, now, nowElapsed);
24008
24009                // Count the number of process types.
24010                switch (app.curProcState) {
24011                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24012                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24013                        mNumCachedHiddenProcs++;
24014                        numCached++;
24015                        if (numCached > cachedProcessLimit) {
24016                            app.kill("cached #" + numCached, true);
24017                        }
24018                        break;
24019                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
24020                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
24021                                && app.lastActivityTime < oldTime) {
24022                            app.kill("empty for "
24023                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
24024                                    / 1000) + "s", true);
24025                        } else {
24026                            numEmpty++;
24027                            if (numEmpty > emptyProcessLimit) {
24028                                app.kill("empty #" + numEmpty, true);
24029                            }
24030                        }
24031                        break;
24032                    default:
24033                        mNumNonCachedProcs++;
24034                        break;
24035                }
24036
24037                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
24038                    // If this is an isolated process, there are no services
24039                    // running in it, and it's not a special process with a
24040                    // custom entry point, then the process is no longer
24041                    // needed.  We agressively kill these because we can by
24042                    // definition not re-use the same process again, and it is
24043                    // good to avoid having whatever code was running in them
24044                    // left sitting around after no longer needed.
24045                    app.kill("isolated not needed", true);
24046                } else {
24047                    // Keeping this process, update its uid.
24048                    final UidRecord uidRec = app.uidRecord;
24049                    if (uidRec != null) {
24050                        uidRec.ephemeral = app.info.isInstantApp();
24051                        if (uidRec.curProcState > app.curProcState) {
24052                            uidRec.curProcState = app.curProcState;
24053                        }
24054                        if (app.foregroundServices) {
24055                            uidRec.foregroundServices = true;
24056                        }
24057                    }
24058                }
24059
24060                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24061                        && !app.killedByAm) {
24062                    numTrimming++;
24063                }
24064            }
24065        }
24066
24067        incrementProcStateSeqAndNotifyAppsLocked();
24068
24069        mNumServiceProcs = mNewNumServiceProcs;
24070
24071        // Now determine the memory trimming level of background processes.
24072        // Unfortunately we need to start at the back of the list to do this
24073        // properly.  We only do this if the number of background apps we
24074        // are managing to keep around is less than half the maximum we desire;
24075        // if we are keeping a good number around, we'll let them use whatever
24076        // memory they want.
24077        final int numCachedAndEmpty = numCached + numEmpty;
24078        int memFactor;
24079        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
24080                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
24081            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
24082                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
24083            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
24084                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
24085            } else {
24086                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
24087            }
24088        } else {
24089            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
24090        }
24091        // We always allow the memory level to go up (better).  We only allow it to go
24092        // down if we are in a state where that is allowed, *and* the total number of processes
24093        // has gone down since last time.
24094        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
24095                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
24096                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
24097        if (memFactor > mLastMemoryLevel) {
24098            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
24099                memFactor = mLastMemoryLevel;
24100                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
24101            }
24102        }
24103        if (memFactor != mLastMemoryLevel) {
24104            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
24105        }
24106        mLastMemoryLevel = memFactor;
24107        mLastNumProcesses = mLruProcesses.size();
24108        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
24109        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
24110        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
24111            if (mLowRamStartTime == 0) {
24112                mLowRamStartTime = now;
24113            }
24114            int step = 0;
24115            int fgTrimLevel;
24116            switch (memFactor) {
24117                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
24118                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
24119                    break;
24120                case ProcessStats.ADJ_MEM_FACTOR_LOW:
24121                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
24122                    break;
24123                default:
24124                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
24125                    break;
24126            }
24127            int factor = numTrimming/3;
24128            int minFactor = 2;
24129            if (mHomeProcess != null) minFactor++;
24130            if (mPreviousProcess != null) minFactor++;
24131            if (factor < minFactor) factor = minFactor;
24132            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
24133            for (int i=N-1; i>=0; i--) {
24134                ProcessRecord app = mLruProcesses.get(i);
24135                if (allChanged || app.procStateChanged) {
24136                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24137                    app.procStateChanged = false;
24138                }
24139                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24140                        && !app.killedByAm) {
24141                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
24142                        try {
24143                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24144                                    "Trimming memory of " + app.processName + " to " + curLevel);
24145                            app.thread.scheduleTrimMemory(curLevel);
24146                        } catch (RemoteException e) {
24147                        }
24148                        if (false) {
24149                            // For now we won't do this; our memory trimming seems
24150                            // to be good enough at this point that destroying
24151                            // activities causes more harm than good.
24152                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
24153                                    && app != mHomeProcess && app != mPreviousProcess) {
24154                                // Need to do this on its own message because the stack may not
24155                                // be in a consistent state at this point.
24156                                // For these apps we will also finish their activities
24157                                // to help them free memory.
24158                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
24159                            }
24160                        }
24161                    }
24162                    app.trimMemoryLevel = curLevel;
24163                    step++;
24164                    if (step >= factor) {
24165                        step = 0;
24166                        switch (curLevel) {
24167                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
24168                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
24169                                break;
24170                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
24171                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24172                                break;
24173                        }
24174                    }
24175                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
24176                        && !app.killedByAm) {
24177                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
24178                            && app.thread != null) {
24179                        try {
24180                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24181                                    "Trimming memory of heavy-weight " + app.processName
24182                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24183                            app.thread.scheduleTrimMemory(
24184                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24185                        } catch (RemoteException e) {
24186                        }
24187                    }
24188                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24189                } else {
24190                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24191                            || app.systemNoUi) && app.pendingUiClean) {
24192                        // If this application is now in the background and it
24193                        // had done UI, then give it the special trim level to
24194                        // have it free UI resources.
24195                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
24196                        if (app.trimMemoryLevel < level && app.thread != null) {
24197                            try {
24198                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24199                                        "Trimming memory of bg-ui " + app.processName
24200                                        + " to " + level);
24201                                app.thread.scheduleTrimMemory(level);
24202                            } catch (RemoteException e) {
24203                            }
24204                        }
24205                        app.pendingUiClean = false;
24206                    }
24207                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
24208                        try {
24209                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24210                                    "Trimming memory of fg " + app.processName
24211                                    + " to " + fgTrimLevel);
24212                            app.thread.scheduleTrimMemory(fgTrimLevel);
24213                        } catch (RemoteException e) {
24214                        }
24215                    }
24216                    app.trimMemoryLevel = fgTrimLevel;
24217                }
24218            }
24219        } else {
24220            if (mLowRamStartTime != 0) {
24221                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
24222                mLowRamStartTime = 0;
24223            }
24224            for (int i=N-1; i>=0; i--) {
24225                ProcessRecord app = mLruProcesses.get(i);
24226                if (allChanged || app.procStateChanged) {
24227                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24228                    app.procStateChanged = false;
24229                }
24230                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24231                        || app.systemNoUi) && app.pendingUiClean) {
24232                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
24233                            && app.thread != null) {
24234                        try {
24235                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24236                                    "Trimming memory of ui hidden " + app.processName
24237                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24238                            app.thread.scheduleTrimMemory(
24239                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24240                        } catch (RemoteException e) {
24241                        }
24242                    }
24243                    app.pendingUiClean = false;
24244                }
24245                app.trimMemoryLevel = 0;
24246            }
24247        }
24248
24249        if (mAlwaysFinishActivities) {
24250            // Need to do this on its own message because the stack may not
24251            // be in a consistent state at this point.
24252            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
24253        }
24254
24255        if (allChanged) {
24256            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
24257        }
24258
24259        ArrayList<UidRecord> becameIdle = null;
24260
24261        // Update from any uid changes.
24262        if (mLocalPowerManager != null) {
24263            mLocalPowerManager.startUidChanges();
24264        }
24265        for (int i=mActiveUids.size()-1; i>=0; i--) {
24266            final UidRecord uidRec = mActiveUids.valueAt(i);
24267            int uidChange = UidRecord.CHANGE_PROCSTATE;
24268            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
24269                    && (uidRec.setProcState != uidRec.curProcState
24270                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
24271                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24272                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
24273                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
24274                        + " to " + uidRec.curWhitelist);
24275                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
24276                        && !uidRec.curWhitelist) {
24277                    // UID is now in the background (and not on the temp whitelist).  Was it
24278                    // previously in the foreground (or on the temp whitelist)?
24279                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
24280                            || uidRec.setWhitelist) {
24281                        uidRec.lastBackgroundTime = nowElapsed;
24282                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
24283                            // Note: the background settle time is in elapsed realtime, while
24284                            // the handler time base is uptime.  All this means is that we may
24285                            // stop background uids later than we had intended, but that only
24286                            // happens because the device was sleeping so we are okay anyway.
24287                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24288                                    mConstants.BACKGROUND_SETTLE_TIME);
24289                        }
24290                    }
24291                    if (uidRec.idle && !uidRec.setIdle) {
24292                        uidChange = UidRecord.CHANGE_IDLE;
24293                        if (becameIdle == null) {
24294                            becameIdle = new ArrayList<>();
24295                        }
24296                        becameIdle.add(uidRec);
24297                    }
24298                } else {
24299                    if (uidRec.idle) {
24300                        uidChange = UidRecord.CHANGE_ACTIVE;
24301                        EventLogTags.writeAmUidActive(uidRec.uid);
24302                        uidRec.idle = false;
24303                    }
24304                    uidRec.lastBackgroundTime = 0;
24305                }
24306                final boolean wasCached = uidRec.setProcState
24307                        > ActivityManager.PROCESS_STATE_RECEIVER;
24308                final boolean isCached = uidRec.curProcState
24309                        > ActivityManager.PROCESS_STATE_RECEIVER;
24310                if (wasCached != isCached ||
24311                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
24312                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
24313                }
24314                uidRec.setProcState = uidRec.curProcState;
24315                uidRec.setWhitelist = uidRec.curWhitelist;
24316                uidRec.setIdle = uidRec.idle;
24317                enqueueUidChangeLocked(uidRec, -1, uidChange);
24318                noteUidProcessState(uidRec.uid, uidRec.curProcState);
24319                if (uidRec.foregroundServices) {
24320                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
24321                }
24322            }
24323        }
24324        if (mLocalPowerManager != null) {
24325            mLocalPowerManager.finishUidChanges();
24326        }
24327
24328        if (becameIdle != null) {
24329            // If we have any new uids that became idle this time, we need to make sure
24330            // they aren't left with running services.
24331            for (int i = becameIdle.size() - 1; i >= 0; i--) {
24332                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
24333            }
24334        }
24335
24336        if (mProcessStats.shouldWriteNowLocked(now)) {
24337            mHandler.post(new Runnable() {
24338                @Override public void run() {
24339                    synchronized (ActivityManagerService.this) {
24340                        mProcessStats.writeStateAsyncLocked();
24341                    }
24342                }
24343            });
24344        }
24345
24346        if (DEBUG_OOM_ADJ) {
24347            final long duration = SystemClock.uptimeMillis() - now;
24348            if (false) {
24349                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
24350                        new RuntimeException("here").fillInStackTrace());
24351            } else {
24352                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
24353            }
24354        }
24355    }
24356
24357    @Override
24358    public void makePackageIdle(String packageName, int userId) {
24359        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
24360                != PackageManager.PERMISSION_GRANTED) {
24361            String msg = "Permission Denial: makePackageIdle() from pid="
24362                    + Binder.getCallingPid()
24363                    + ", uid=" + Binder.getCallingUid()
24364                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
24365            Slog.w(TAG, msg);
24366            throw new SecurityException(msg);
24367        }
24368        final int callingPid = Binder.getCallingPid();
24369        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
24370                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
24371        long callingId = Binder.clearCallingIdentity();
24372        synchronized(this) {
24373            try {
24374                IPackageManager pm = AppGlobals.getPackageManager();
24375                int pkgUid = -1;
24376                try {
24377                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
24378                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
24379                } catch (RemoteException e) {
24380                }
24381                if (pkgUid == -1) {
24382                    throw new IllegalArgumentException("Unknown package name " + packageName);
24383                }
24384
24385                if (mLocalPowerManager != null) {
24386                    mLocalPowerManager.startUidChanges();
24387                }
24388                final int appId = UserHandle.getAppId(pkgUid);
24389                final int N = mActiveUids.size();
24390                for (int i=N-1; i>=0; i--) {
24391                    final UidRecord uidRec = mActiveUids.valueAt(i);
24392                    final long bgTime = uidRec.lastBackgroundTime;
24393                    if (bgTime > 0 && !uidRec.idle) {
24394                        if (UserHandle.getAppId(uidRec.uid) == appId) {
24395                            if (userId == UserHandle.USER_ALL ||
24396                                    userId == UserHandle.getUserId(uidRec.uid)) {
24397                                EventLogTags.writeAmUidIdle(uidRec.uid);
24398                                uidRec.idle = true;
24399                                uidRec.setIdle = true;
24400                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
24401                                        + " from package " + packageName + " user " + userId);
24402                                doStopUidLocked(uidRec.uid, uidRec);
24403                            }
24404                        }
24405                    }
24406                }
24407            } finally {
24408                if (mLocalPowerManager != null) {
24409                    mLocalPowerManager.finishUidChanges();
24410                }
24411                Binder.restoreCallingIdentity(callingId);
24412            }
24413        }
24414    }
24415
24416    final void idleUids() {
24417        synchronized (this) {
24418            final int N = mActiveUids.size();
24419            if (N <= 0) {
24420                return;
24421            }
24422            final long nowElapsed = SystemClock.elapsedRealtime();
24423            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
24424            long nextTime = 0;
24425            if (mLocalPowerManager != null) {
24426                mLocalPowerManager.startUidChanges();
24427            }
24428            for (int i=N-1; i>=0; i--) {
24429                final UidRecord uidRec = mActiveUids.valueAt(i);
24430                final long bgTime = uidRec.lastBackgroundTime;
24431                if (bgTime > 0 && !uidRec.idle) {
24432                    if (bgTime <= maxBgTime) {
24433                        EventLogTags.writeAmUidIdle(uidRec.uid);
24434                        uidRec.idle = true;
24435                        uidRec.setIdle = true;
24436                        doStopUidLocked(uidRec.uid, uidRec);
24437                    } else {
24438                        if (nextTime == 0 || nextTime > bgTime) {
24439                            nextTime = bgTime;
24440                        }
24441                    }
24442                }
24443            }
24444            if (mLocalPowerManager != null) {
24445                mLocalPowerManager.finishUidChanges();
24446            }
24447            if (nextTime > 0) {
24448                mHandler.removeMessages(IDLE_UIDS_MSG);
24449                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24450                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
24451            }
24452        }
24453    }
24454
24455    /**
24456     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
24457     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
24458     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
24459     */
24460    @VisibleForTesting
24461    @GuardedBy("this")
24462    void incrementProcStateSeqAndNotifyAppsLocked() {
24463        if (mWaitForNetworkTimeoutMs <= 0) {
24464            return;
24465        }
24466        // Used for identifying which uids need to block for network.
24467        ArrayList<Integer> blockingUids = null;
24468        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
24469            final UidRecord uidRec = mActiveUids.valueAt(i);
24470            // If the network is not restricted for uid, then nothing to do here.
24471            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
24472                continue;
24473            }
24474            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
24475                continue;
24476            }
24477            // If process state is not changed, then there's nothing to do.
24478            if (uidRec.setProcState == uidRec.curProcState) {
24479                continue;
24480            }
24481            final int blockState = getBlockStateForUid(uidRec);
24482            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
24483            // there's nothing the app needs to do in this scenario.
24484            if (blockState == NETWORK_STATE_NO_CHANGE) {
24485                continue;
24486            }
24487            synchronized (uidRec.networkStateLock) {
24488                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
24489                if (blockState == NETWORK_STATE_BLOCK) {
24490                    if (blockingUids == null) {
24491                        blockingUids = new ArrayList<>();
24492                    }
24493                    blockingUids.add(uidRec.uid);
24494                } else {
24495                    if (DEBUG_NETWORK) {
24496                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
24497                                + " threads for uid: " + uidRec);
24498                    }
24499                    if (uidRec.waitingForNetwork) {
24500                        uidRec.networkStateLock.notifyAll();
24501                    }
24502                }
24503            }
24504        }
24505
24506        // There are no uids that need to block, so nothing more to do.
24507        if (blockingUids == null) {
24508            return;
24509        }
24510
24511        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
24512            final ProcessRecord app = mLruProcesses.get(i);
24513            if (!blockingUids.contains(app.uid)) {
24514                continue;
24515            }
24516            if (!app.killedByAm && app.thread != null) {
24517                final UidRecord uidRec = mActiveUids.get(app.uid);
24518                try {
24519                    if (DEBUG_NETWORK) {
24520                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
24521                                + uidRec);
24522                    }
24523                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
24524                } catch (RemoteException ignored) {
24525                }
24526            }
24527        }
24528    }
24529
24530    /**
24531     * Checks if the uid is coming from background to foreground or vice versa and returns
24532     * appropriate block state based on this.
24533     *
24534     * @return blockState based on whether the uid is coming from background to foreground or
24535     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
24536     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
24537     *         {@link #NETWORK_STATE_NO_CHANGE}.
24538     */
24539    @VisibleForTesting
24540    int getBlockStateForUid(UidRecord uidRec) {
24541        // Denotes whether uid's process state is currently allowed network access.
24542        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
24543                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
24544        // Denotes whether uid's process state was previously allowed network access.
24545        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
24546                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
24547
24548        // When the uid is coming to foreground, AMS should inform the app thread that it should
24549        // block for the network rules to get updated before launching an activity.
24550        if (!wasAllowed && isAllowed) {
24551            return NETWORK_STATE_BLOCK;
24552        }
24553        // When the uid is going to background, AMS should inform the app thread that if an
24554        // activity launch is blocked for the network rules to get updated, it should be unblocked.
24555        if (wasAllowed && !isAllowed) {
24556            return NETWORK_STATE_UNBLOCK;
24557        }
24558        return NETWORK_STATE_NO_CHANGE;
24559    }
24560
24561    final void runInBackgroundDisabled(int uid) {
24562        synchronized (this) {
24563            UidRecord uidRec = mActiveUids.get(uid);
24564            if (uidRec != null) {
24565                // This uid is actually running...  should it be considered background now?
24566                if (uidRec.idle) {
24567                    doStopUidLocked(uidRec.uid, uidRec);
24568                }
24569            } else {
24570                // This uid isn't actually running...  still send a report about it being "stopped".
24571                doStopUidLocked(uid, null);
24572            }
24573        }
24574    }
24575
24576    /**
24577     * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
24578     */
24579    void doStopUidForIdleUidsLocked() {
24580        final int size = mActiveUids.size();
24581        for (int i = 0; i < size; i++) {
24582            final int uid = mActiveUids.keyAt(i);
24583            if (UserHandle.isCore(uid)) {
24584                continue;
24585            }
24586            final UidRecord uidRec = mActiveUids.valueAt(i);
24587            if (!uidRec.idle) {
24588                continue;
24589            }
24590            doStopUidLocked(uidRec.uid, uidRec);
24591        }
24592    }
24593
24594    final void doStopUidLocked(int uid, final UidRecord uidRec) {
24595        mServices.stopInBackgroundLocked(uid);
24596        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
24597    }
24598
24599    /**
24600     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
24601     */
24602    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
24603            long duration, String tag) {
24604        if (DEBUG_WHITELISTS) {
24605            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
24606                    + targetUid + ", " + duration + ")");
24607        }
24608
24609        synchronized (mPidsSelfLocked) {
24610            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
24611            if (pr == null) {
24612                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
24613                        + callerPid);
24614                return;
24615            }
24616            if (!pr.whitelistManager) {
24617                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
24618                        != PackageManager.PERMISSION_GRANTED) {
24619                    if (DEBUG_WHITELISTS) {
24620                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
24621                                + ": pid " + callerPid + " is not allowed");
24622                    }
24623                    return;
24624                }
24625            }
24626        }
24627
24628        tempWhitelistUidLocked(targetUid, duration, tag);
24629    }
24630
24631    /**
24632     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
24633     */
24634    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
24635        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
24636        setUidTempWhitelistStateLocked(targetUid, true);
24637        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
24638    }
24639
24640    void pushTempWhitelist() {
24641        final int N;
24642        final PendingTempWhitelist[] list;
24643
24644        // First copy out the pending changes...  we need to leave them in the map for now,
24645        // in case someone needs to check what is coming up while we don't have the lock held.
24646        synchronized(this) {
24647            N = mPendingTempWhitelist.size();
24648            list = new PendingTempWhitelist[N];
24649            for (int i = 0; i < N; i++) {
24650                list[i] = mPendingTempWhitelist.valueAt(i);
24651            }
24652        }
24653
24654        // Now safely dispatch changes to device idle controller.
24655        for (int i = 0; i < N; i++) {
24656            PendingTempWhitelist ptw = list[i];
24657            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
24658                    ptw.duration, true, ptw.tag);
24659        }
24660
24661        // And now we can safely remove them from the map.
24662        synchronized(this) {
24663            for (int i = 0; i < N; i++) {
24664                PendingTempWhitelist ptw = list[i];
24665                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
24666                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
24667                    mPendingTempWhitelist.removeAt(index);
24668                }
24669            }
24670        }
24671    }
24672
24673    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
24674        boolean changed = false;
24675        for (int i=mActiveUids.size()-1; i>=0; i--) {
24676            final UidRecord uidRec = mActiveUids.valueAt(i);
24677            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
24678                uidRec.curWhitelist = onWhitelist;
24679                changed = true;
24680            }
24681        }
24682        if (changed) {
24683            updateOomAdjLocked();
24684        }
24685    }
24686
24687    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
24688        boolean changed = false;
24689        final UidRecord uidRec = mActiveUids.get(uid);
24690        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
24691            uidRec.curWhitelist = onWhitelist;
24692            updateOomAdjLocked();
24693        }
24694    }
24695
24696    final void trimApplications() {
24697        synchronized (this) {
24698            int i;
24699
24700            // First remove any unused application processes whose package
24701            // has been removed.
24702            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
24703                final ProcessRecord app = mRemovedProcesses.get(i);
24704                if (app.activities.size() == 0 && app.recentTasks.size() == 0
24705                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
24706                    Slog.i(
24707                        TAG, "Exiting empty application process "
24708                        + app.toShortString() + " ("
24709                        + (app.thread != null ? app.thread.asBinder() : null)
24710                        + ")\n");
24711                    if (app.pid > 0 && app.pid != MY_PID) {
24712                        app.kill("empty", false);
24713                    } else if (app.thread != null) {
24714                        try {
24715                            app.thread.scheduleExit();
24716                        } catch (Exception e) {
24717                            // Ignore exceptions.
24718                        }
24719                    }
24720                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
24721                    mRemovedProcesses.remove(i);
24722
24723                    if (app.persistent) {
24724                        addAppLocked(app.info, null, false, null /* ABI override */);
24725                    }
24726                }
24727            }
24728
24729            // Now update the oom adj for all processes.
24730            updateOomAdjLocked();
24731        }
24732    }
24733
24734    /** This method sends the specified signal to each of the persistent apps */
24735    public void signalPersistentProcesses(int sig) throws RemoteException {
24736        if (sig != SIGNAL_USR1) {
24737            throw new SecurityException("Only SIGNAL_USR1 is allowed");
24738        }
24739
24740        synchronized (this) {
24741            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
24742                    != PackageManager.PERMISSION_GRANTED) {
24743                throw new SecurityException("Requires permission "
24744                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
24745            }
24746
24747            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
24748                ProcessRecord r = mLruProcesses.get(i);
24749                if (r.thread != null && r.persistent) {
24750                    sendSignal(r.pid, sig);
24751                }
24752            }
24753        }
24754    }
24755
24756    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
24757        if (proc == null || proc == mProfileProc) {
24758            proc = mProfileProc;
24759            profileType = mProfileType;
24760            clearProfilerLocked();
24761        }
24762        if (proc == null) {
24763            return;
24764        }
24765        try {
24766            proc.thread.profilerControl(false, null, profileType);
24767        } catch (RemoteException e) {
24768            throw new IllegalStateException("Process disappeared");
24769        }
24770    }
24771
24772    private void clearProfilerLocked() {
24773        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
24774            try {
24775                mProfilerInfo.profileFd.close();
24776            } catch (IOException e) {
24777            }
24778        }
24779        mProfileApp = null;
24780        mProfileProc = null;
24781        mProfilerInfo = null;
24782    }
24783
24784    public boolean profileControl(String process, int userId, boolean start,
24785            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
24786
24787        try {
24788            synchronized (this) {
24789                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
24790                // its own permission.
24791                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
24792                        != PackageManager.PERMISSION_GRANTED) {
24793                    throw new SecurityException("Requires permission "
24794                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
24795                }
24796
24797                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
24798                    throw new IllegalArgumentException("null profile info or fd");
24799                }
24800
24801                ProcessRecord proc = null;
24802                if (process != null) {
24803                    proc = findProcessLocked(process, userId, "profileControl");
24804                }
24805
24806                if (start && (proc == null || proc.thread == null)) {
24807                    throw new IllegalArgumentException("Unknown process: " + process);
24808                }
24809
24810                if (start) {
24811                    stopProfilerLocked(null, 0);
24812                    setProfileApp(proc.info, proc.processName, profilerInfo);
24813                    mProfileProc = proc;
24814                    mProfileType = profileType;
24815                    ParcelFileDescriptor fd = profilerInfo.profileFd;
24816                    try {
24817                        fd = fd.dup();
24818                    } catch (IOException e) {
24819                        fd = null;
24820                    }
24821                    profilerInfo.profileFd = fd;
24822                    proc.thread.profilerControl(start, profilerInfo, profileType);
24823                    fd = null;
24824                    try {
24825                        mProfilerInfo.profileFd.close();
24826                    } catch (IOException e) {
24827                    }
24828                    mProfilerInfo.profileFd = null;
24829                } else {
24830                    stopProfilerLocked(proc, profileType);
24831                    if (profilerInfo != null && profilerInfo.profileFd != null) {
24832                        try {
24833                            profilerInfo.profileFd.close();
24834                        } catch (IOException e) {
24835                        }
24836                    }
24837                }
24838
24839                return true;
24840            }
24841        } catch (RemoteException e) {
24842            throw new IllegalStateException("Process disappeared");
24843        } finally {
24844            if (profilerInfo != null && profilerInfo.profileFd != null) {
24845                try {
24846                    profilerInfo.profileFd.close();
24847                } catch (IOException e) {
24848                }
24849            }
24850        }
24851    }
24852
24853    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
24854        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
24855                userId, true, ALLOW_FULL_ONLY, callName, null);
24856        ProcessRecord proc = null;
24857        try {
24858            int pid = Integer.parseInt(process);
24859            synchronized (mPidsSelfLocked) {
24860                proc = mPidsSelfLocked.get(pid);
24861            }
24862        } catch (NumberFormatException e) {
24863        }
24864
24865        if (proc == null) {
24866            ArrayMap<String, SparseArray<ProcessRecord>> all
24867                    = mProcessNames.getMap();
24868            SparseArray<ProcessRecord> procs = all.get(process);
24869            if (procs != null && procs.size() > 0) {
24870                proc = procs.valueAt(0);
24871                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
24872                    for (int i=1; i<procs.size(); i++) {
24873                        ProcessRecord thisProc = procs.valueAt(i);
24874                        if (thisProc.userId == userId) {
24875                            proc = thisProc;
24876                            break;
24877                        }
24878                    }
24879                }
24880            }
24881        }
24882
24883        return proc;
24884    }
24885
24886    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
24887            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
24888
24889        try {
24890            synchronized (this) {
24891                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
24892                // its own permission (same as profileControl).
24893                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
24894                        != PackageManager.PERMISSION_GRANTED) {
24895                    throw new SecurityException("Requires permission "
24896                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
24897                }
24898
24899                if (fd == null) {
24900                    throw new IllegalArgumentException("null fd");
24901                }
24902
24903                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
24904                if (proc == null || proc.thread == null) {
24905                    throw new IllegalArgumentException("Unknown process: " + process);
24906                }
24907
24908                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24909                if (!isDebuggable) {
24910                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24911                        throw new SecurityException("Process not debuggable: " + proc);
24912                    }
24913                }
24914
24915                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
24916                fd = null;
24917                return true;
24918            }
24919        } catch (RemoteException e) {
24920            throw new IllegalStateException("Process disappeared");
24921        } finally {
24922            if (fd != null) {
24923                try {
24924                    fd.close();
24925                } catch (IOException e) {
24926                }
24927            }
24928        }
24929    }
24930
24931    @Override
24932    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
24933            String reportPackage) {
24934        if (processName != null) {
24935            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
24936                    "setDumpHeapDebugLimit()");
24937        } else {
24938            synchronized (mPidsSelfLocked) {
24939                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
24940                if (proc == null) {
24941                    throw new SecurityException("No process found for calling pid "
24942                            + Binder.getCallingPid());
24943                }
24944                if (!Build.IS_DEBUGGABLE
24945                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24946                    throw new SecurityException("Not running a debuggable build");
24947                }
24948                processName = proc.processName;
24949                uid = proc.uid;
24950                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
24951                    throw new SecurityException("Package " + reportPackage + " is not running in "
24952                            + proc);
24953                }
24954            }
24955        }
24956        synchronized (this) {
24957            if (maxMemSize > 0) {
24958                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
24959            } else {
24960                if (uid != 0) {
24961                    mMemWatchProcesses.remove(processName, uid);
24962                } else {
24963                    mMemWatchProcesses.getMap().remove(processName);
24964                }
24965            }
24966        }
24967    }
24968
24969    @Override
24970    public void dumpHeapFinished(String path) {
24971        synchronized (this) {
24972            if (Binder.getCallingPid() != mMemWatchDumpPid) {
24973                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
24974                        + " does not match last pid " + mMemWatchDumpPid);
24975                return;
24976            }
24977            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
24978                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
24979                        + " does not match last path " + mMemWatchDumpFile);
24980                return;
24981            }
24982            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
24983            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
24984
24985            // Forced gc to clean up the remnant hprof fd.
24986            Runtime.getRuntime().gc();
24987        }
24988    }
24989
24990    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
24991    public void monitor() {
24992        synchronized (this) { }
24993    }
24994
24995    void onCoreSettingsChange(Bundle settings) {
24996        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24997            ProcessRecord processRecord = mLruProcesses.get(i);
24998            try {
24999                if (processRecord.thread != null) {
25000                    processRecord.thread.setCoreSettings(settings);
25001                }
25002            } catch (RemoteException re) {
25003                /* ignore */
25004            }
25005        }
25006    }
25007
25008    // Multi-user methods
25009
25010    /**
25011     * Start user, if its not already running, but don't bring it to foreground.
25012     */
25013    @Override
25014    public boolean startUserInBackground(final int userId) {
25015        return startUserInBackgroundWithListener(userId, null);
25016    }
25017
25018    @Override
25019    public boolean startUserInBackgroundWithListener(final int userId,
25020                @Nullable IProgressListener unlockListener) {
25021        return mUserController.startUser(userId, /* foreground */ false, unlockListener);
25022    }
25023
25024    @Override
25025    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
25026        return mUserController.unlockUser(userId, token, secret, listener);
25027    }
25028
25029    @Override
25030    public boolean switchUser(final int targetUserId) {
25031        return mUserController.switchUser(targetUserId);
25032    }
25033
25034    @Override
25035    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
25036        return mUserController.stopUser(userId, force, callback);
25037    }
25038
25039    @Override
25040    public UserInfo getCurrentUser() {
25041        return mUserController.getCurrentUser();
25042    }
25043
25044    String getStartedUserState(int userId) {
25045        final UserState userState = mUserController.getStartedUserState(userId);
25046        return UserState.stateToString(userState.state);
25047    }
25048
25049    @Override
25050    public boolean isUserRunning(int userId, int flags) {
25051        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
25052                && checkCallingPermission(INTERACT_ACROSS_USERS)
25053                    != PackageManager.PERMISSION_GRANTED) {
25054            String msg = "Permission Denial: isUserRunning() from pid="
25055                    + Binder.getCallingPid()
25056                    + ", uid=" + Binder.getCallingUid()
25057                    + " requires " + INTERACT_ACROSS_USERS;
25058            Slog.w(TAG, msg);
25059            throw new SecurityException(msg);
25060        }
25061        return mUserController.isUserRunning(userId, flags);
25062    }
25063
25064    @Override
25065    public int[] getRunningUserIds() {
25066        if (checkCallingPermission(INTERACT_ACROSS_USERS)
25067                != PackageManager.PERMISSION_GRANTED) {
25068            String msg = "Permission Denial: isUserRunning() from pid="
25069                    + Binder.getCallingPid()
25070                    + ", uid=" + Binder.getCallingUid()
25071                    + " requires " + INTERACT_ACROSS_USERS;
25072            Slog.w(TAG, msg);
25073            throw new SecurityException(msg);
25074        }
25075        return mUserController.getStartedUserArray();
25076    }
25077
25078    @Override
25079    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
25080        mUserController.registerUserSwitchObserver(observer, name);
25081    }
25082
25083    @Override
25084    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
25085        mUserController.unregisterUserSwitchObserver(observer);
25086    }
25087
25088    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
25089        if (info == null) return null;
25090        ApplicationInfo newInfo = new ApplicationInfo(info);
25091        newInfo.initForUser(userId);
25092        return newInfo;
25093    }
25094
25095    public boolean isUserStopped(int userId) {
25096        return mUserController.getStartedUserState(userId) == null;
25097    }
25098
25099    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
25100        if (aInfo == null
25101                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
25102            return aInfo;
25103        }
25104
25105        ActivityInfo info = new ActivityInfo(aInfo);
25106        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
25107        return info;
25108    }
25109
25110    private boolean processSanityChecksLocked(ProcessRecord process) {
25111        if (process == null || process.thread == null) {
25112            return false;
25113        }
25114
25115        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25116        if (!isDebuggable) {
25117            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25118                return false;
25119            }
25120        }
25121
25122        return true;
25123    }
25124
25125    public boolean startBinderTracking() throws RemoteException {
25126        synchronized (this) {
25127            mBinderTransactionTrackingEnabled = true;
25128            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25129            // permission (same as profileControl).
25130            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25131                    != PackageManager.PERMISSION_GRANTED) {
25132                throw new SecurityException("Requires permission "
25133                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25134            }
25135
25136            for (int i = 0; i < mLruProcesses.size(); i++) {
25137                ProcessRecord process = mLruProcesses.get(i);
25138                if (!processSanityChecksLocked(process)) {
25139                    continue;
25140                }
25141                try {
25142                    process.thread.startBinderTracking();
25143                } catch (RemoteException e) {
25144                    Log.v(TAG, "Process disappared");
25145                }
25146            }
25147            return true;
25148        }
25149    }
25150
25151    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
25152        try {
25153            synchronized (this) {
25154                mBinderTransactionTrackingEnabled = false;
25155                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25156                // permission (same as profileControl).
25157                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25158                        != PackageManager.PERMISSION_GRANTED) {
25159                    throw new SecurityException("Requires permission "
25160                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25161                }
25162
25163                if (fd == null) {
25164                    throw new IllegalArgumentException("null fd");
25165                }
25166
25167                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
25168                pw.println("Binder transaction traces for all processes.\n");
25169                for (ProcessRecord process : mLruProcesses) {
25170                    if (!processSanityChecksLocked(process)) {
25171                        continue;
25172                    }
25173
25174                    pw.println("Traces for process: " + process.processName);
25175                    pw.flush();
25176                    try {
25177                        TransferPipe tp = new TransferPipe();
25178                        try {
25179                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
25180                            tp.go(fd.getFileDescriptor());
25181                        } finally {
25182                            tp.kill();
25183                        }
25184                    } catch (IOException e) {
25185                        pw.println("Failure while dumping IPC traces from " + process +
25186                                ".  Exception: " + e);
25187                        pw.flush();
25188                    } catch (RemoteException e) {
25189                        pw.println("Got a RemoteException while dumping IPC traces from " +
25190                                process + ".  Exception: " + e);
25191                        pw.flush();
25192                    }
25193                }
25194                fd = null;
25195                return true;
25196            }
25197        } finally {
25198            if (fd != null) {
25199                try {
25200                    fd.close();
25201                } catch (IOException e) {
25202                }
25203            }
25204        }
25205    }
25206
25207    @VisibleForTesting
25208    final class LocalService extends ActivityManagerInternal {
25209        @Override
25210        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
25211                int targetUserId) {
25212            synchronized (ActivityManagerService.this) {
25213                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
25214                        targetPkg, intent, null, targetUserId);
25215            }
25216        }
25217
25218        @Override
25219        public String checkContentProviderAccess(String authority, int userId) {
25220            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
25221        }
25222
25223        @Override
25224        public void onWakefulnessChanged(int wakefulness) {
25225            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
25226        }
25227
25228        @Override
25229        public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
25230                String processName, String abiOverride, int uid, Runnable crashHandler) {
25231            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
25232                    processName, abiOverride, uid, crashHandler);
25233        }
25234
25235        @Override
25236        public SleepToken acquireSleepToken(String tag, int displayId) {
25237            Preconditions.checkNotNull(tag);
25238            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
25239        }
25240
25241        @Override
25242        public ComponentName getHomeActivityForUser(int userId) {
25243            synchronized (ActivityManagerService.this) {
25244                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
25245                return homeActivity == null ? null : homeActivity.realActivity;
25246            }
25247        }
25248
25249        @Override
25250        public void onUserRemoved(int userId) {
25251            synchronized (ActivityManagerService.this) {
25252                ActivityManagerService.this.onUserStoppedLocked(userId);
25253            }
25254            mBatteryStatsService.onUserRemoved(userId);
25255            mUserController.onUserRemoved(userId);
25256        }
25257
25258        @Override
25259        public void onLocalVoiceInteractionStarted(IBinder activity,
25260                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
25261            synchronized (ActivityManagerService.this) {
25262                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
25263                        voiceSession, voiceInteractor);
25264            }
25265        }
25266
25267        @Override
25268        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
25269            synchronized (ActivityManagerService.this) {
25270                mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
25271                        reasons, timestamp);
25272            }
25273        }
25274
25275        @Override
25276        public void notifyAppTransitionFinished() {
25277            synchronized (ActivityManagerService.this) {
25278                mStackSupervisor.notifyAppTransitionDone();
25279            }
25280        }
25281
25282        @Override
25283        public void notifyAppTransitionCancelled() {
25284            synchronized (ActivityManagerService.this) {
25285                mStackSupervisor.notifyAppTransitionDone();
25286            }
25287        }
25288
25289        @Override
25290        public List<IBinder> getTopVisibleActivities() {
25291            synchronized (ActivityManagerService.this) {
25292                return mStackSupervisor.getTopVisibleActivities();
25293            }
25294        }
25295
25296        @Override
25297        public void notifyDockedStackMinimizedChanged(boolean minimized) {
25298            synchronized (ActivityManagerService.this) {
25299                mStackSupervisor.setDockedStackMinimized(minimized);
25300            }
25301        }
25302
25303        @Override
25304        public void killForegroundAppsForUser(int userHandle) {
25305            synchronized (ActivityManagerService.this) {
25306                final ArrayList<ProcessRecord> procs = new ArrayList<>();
25307                final int NP = mProcessNames.getMap().size();
25308                for (int ip = 0; ip < NP; ip++) {
25309                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
25310                    final int NA = apps.size();
25311                    for (int ia = 0; ia < NA; ia++) {
25312                        final ProcessRecord app = apps.valueAt(ia);
25313                        if (app.persistent) {
25314                            // We don't kill persistent processes.
25315                            continue;
25316                        }
25317                        if (app.removed) {
25318                            procs.add(app);
25319                        } else if (app.userId == userHandle && app.foregroundActivities) {
25320                            app.removed = true;
25321                            procs.add(app);
25322                        }
25323                    }
25324                }
25325
25326                final int N = procs.size();
25327                for (int i = 0; i < N; i++) {
25328                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
25329                }
25330            }
25331        }
25332
25333        @Override
25334        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
25335                long duration) {
25336            if (!(target instanceof PendingIntentRecord)) {
25337                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
25338                return;
25339            }
25340            synchronized (ActivityManagerService.this) {
25341                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
25342            }
25343        }
25344
25345        @Override
25346        public void setDeviceIdleWhitelist(int[] appids) {
25347            synchronized (ActivityManagerService.this) {
25348                mDeviceIdleWhitelist = appids;
25349            }
25350        }
25351
25352        @Override
25353        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
25354            synchronized (ActivityManagerService.this) {
25355                mDeviceIdleTempWhitelist = appids;
25356                setAppIdTempWhitelistStateLocked(changingAppId, adding);
25357            }
25358        }
25359
25360        @Override
25361        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
25362                int userId) {
25363            Preconditions.checkNotNull(values, "Configuration must not be null");
25364            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
25365            synchronized (ActivityManagerService.this) {
25366                updateConfigurationLocked(values, null, false, true, userId,
25367                        false /* deferResume */);
25368            }
25369        }
25370
25371        @Override
25372        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
25373                Bundle bOptions) {
25374            Preconditions.checkNotNull(intents, "intents");
25375            final String[] resolvedTypes = new String[intents.length];
25376            for (int i = 0; i < intents.length; i++) {
25377                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
25378            }
25379
25380            // UID of the package on user userId.
25381            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
25382            // packageUid may not be initialized.
25383            int packageUid = 0;
25384            try {
25385                packageUid = AppGlobals.getPackageManager().getPackageUid(
25386                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
25387            } catch (RemoteException e) {
25388                // Shouldn't happen.
25389            }
25390
25391            synchronized (ActivityManagerService.this) {
25392                return mActivityStartController.startActivitiesInPackage(packageUid, packageName,
25393                        intents, resolvedTypes, null /* resultTo */,
25394                        SafeActivityOptions.fromBundle(bOptions), userId);
25395            }
25396        }
25397
25398        @Override
25399        public int getUidProcessState(int uid) {
25400            return getUidState(uid);
25401        }
25402
25403        @Override
25404        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
25405            synchronized (ActivityManagerService.this) {
25406
25407                // We might change the visibilities here, so prepare an empty app transition which
25408                // might be overridden later if we actually change visibilities.
25409                final boolean wasTransitionSet =
25410                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
25411                if (!wasTransitionSet) {
25412                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
25413                            false /* alwaysKeepCurrent */);
25414                }
25415                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
25416
25417                // If there was a transition set already we don't want to interfere with it as we
25418                // might be starting it too early.
25419                if (!wasTransitionSet) {
25420                    mWindowManager.executeAppTransition();
25421                }
25422            }
25423            if (callback != null) {
25424                callback.run();
25425            }
25426        }
25427
25428        @Override
25429        public boolean isSystemReady() {
25430            // no need to synchronize(this) just to read & return the value
25431            return mSystemReady;
25432        }
25433
25434        @Override
25435        public void notifyKeyguardTrustedChanged() {
25436            synchronized (ActivityManagerService.this) {
25437                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
25438                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
25439                }
25440            }
25441        }
25442
25443        /**
25444         * Sets if the given pid has an overlay UI or not.
25445         *
25446         * @param pid The pid we are setting overlay UI for.
25447         * @param hasOverlayUi True if the process has overlay UI.
25448         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
25449         */
25450        @Override
25451        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
25452            synchronized (ActivityManagerService.this) {
25453                final ProcessRecord pr;
25454                synchronized (mPidsSelfLocked) {
25455                    pr = mPidsSelfLocked.get(pid);
25456                    if (pr == null) {
25457                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
25458                        return;
25459                    }
25460                }
25461                if (pr.hasOverlayUi == hasOverlayUi) {
25462                    return;
25463                }
25464                pr.hasOverlayUi = hasOverlayUi;
25465                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
25466                updateOomAdjLocked(pr, true);
25467            }
25468        }
25469
25470        /**
25471         * Called after the network policy rules are updated by
25472         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
25473         * and {@param procStateSeq}.
25474         */
25475        @Override
25476        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
25477            if (DEBUG_NETWORK) {
25478                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
25479                        + uid + " seq: " + procStateSeq);
25480            }
25481            UidRecord record;
25482            synchronized (ActivityManagerService.this) {
25483                record = mActiveUids.get(uid);
25484                if (record == null) {
25485                    if (DEBUG_NETWORK) {
25486                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
25487                                + " procStateSeq: " + procStateSeq);
25488                    }
25489                    return;
25490                }
25491            }
25492            synchronized (record.networkStateLock) {
25493                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
25494                    if (DEBUG_NETWORK) {
25495                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
25496                                + " been handled for uid: " + uid);
25497                    }
25498                    return;
25499                }
25500                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
25501                if (record.curProcStateSeq > procStateSeq) {
25502                    if (DEBUG_NETWORK) {
25503                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
25504                                + ", curProcstateSeq: " + record.curProcStateSeq
25505                                + ", procStateSeq: " + procStateSeq);
25506                    }
25507                    return;
25508                }
25509                if (record.waitingForNetwork) {
25510                    if (DEBUG_NETWORK) {
25511                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
25512                                + ", procStateSeq: " + procStateSeq);
25513                    }
25514                    record.networkStateLock.notifyAll();
25515                }
25516            }
25517        }
25518
25519        @Override
25520        public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
25521            synchronized (ActivityManagerService.this) {
25522                mActiveVoiceInteractionServiceComponent = component;
25523            }
25524        }
25525
25526        /**
25527         * Called after virtual display Id is updated by
25528         * {@link com.android.server.vr.Vr2dDisplay} with a specific
25529         * {@param vrVr2dDisplayId}.
25530         */
25531        @Override
25532        public void setVr2dDisplayId(int vr2dDisplayId) {
25533            if (DEBUG_STACK) {
25534                Slog.d(TAG, "setVr2dDisplayId called for: " +
25535                        vr2dDisplayId);
25536            }
25537            synchronized (ActivityManagerService.this) {
25538                mVr2dDisplayId = vr2dDisplayId;
25539            }
25540        }
25541
25542        @Override
25543        public void saveANRState(String reason) {
25544            synchronized (ActivityManagerService.this) {
25545                final StringWriter sw = new StringWriter();
25546                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
25547                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
25548                if (reason != null) {
25549                    pw.println("  Reason: " + reason);
25550                }
25551                pw.println();
25552                mActivityStartController.dump(pw, "  ", null);
25553                pw.println();
25554                pw.println("-------------------------------------------------------------------------------");
25555                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
25556                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
25557                        "" /* header */);
25558                pw.println();
25559                pw.close();
25560
25561                mLastANRState = sw.toString();
25562            }
25563        }
25564
25565        @Override
25566        public void clearSavedANRState() {
25567            synchronized (ActivityManagerService.this) {
25568                mLastANRState = null;
25569            }
25570        }
25571
25572        @Override
25573        public void setFocusedActivity(IBinder token) {
25574            synchronized (ActivityManagerService.this) {
25575                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
25576                if (r == null) {
25577                    throw new IllegalArgumentException(
25578                            "setFocusedActivity: No activity record matching token=" + token);
25579                }
25580                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
25581                        r, "setFocusedActivity")) {
25582                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
25583                }
25584            }
25585        }
25586
25587        @Override
25588        public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
25589            synchronized (ActivityManagerService.this) {
25590                if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
25591                    ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
25592                    if (types == null) {
25593                        if (uid < 0) {
25594                            return;
25595                        }
25596                        types = new ArrayMap<>();
25597                        mAllowAppSwitchUids.put(userId, types);
25598                    }
25599                    if (uid < 0) {
25600                        types.remove(type);
25601                    } else {
25602                        types.put(type, uid);
25603                    }
25604                }
25605            }
25606        }
25607
25608        @Override
25609        public boolean isRuntimeRestarted() {
25610            return mSystemServiceManager.isRuntimeRestarted();
25611        }
25612
25613        @Override
25614        public boolean hasRunningActivity(int uid, @Nullable String packageName) {
25615            if (packageName == null) return false;
25616
25617            synchronized (ActivityManagerService.this) {
25618                for (int i = 0; i < mLruProcesses.size(); i++) {
25619                    final ProcessRecord processRecord = mLruProcesses.get(i);
25620                    if (processRecord.uid == uid) {
25621                        for (int j = 0; j < processRecord.activities.size(); j++) {
25622                            final ActivityRecord activityRecord = processRecord.activities.get(j);
25623                            if (packageName.equals(activityRecord.packageName)) {
25624                                return true;
25625                            }
25626                        }
25627                    }
25628                }
25629            }
25630            return false;
25631        }
25632
25633        @Override
25634        public void registerScreenObserver(ScreenObserver observer) {
25635            mScreenObservers.add(observer);
25636        }
25637
25638        @Override
25639        public boolean canStartMoreUsers() {
25640            return mUserController.canStartMoreUsers();
25641        }
25642
25643        @Override
25644        public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
25645            mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
25646        }
25647
25648        @Override
25649        public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
25650            mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
25651        }
25652
25653        @Override
25654        public int getMaxRunningUsers() {
25655            return mUserController.mMaxRunningUsers;
25656        }
25657
25658        public boolean isCallerRecents(int callingUid) {
25659            return getRecentTasks().isCallerRecents(callingUid);
25660        }
25661    }
25662
25663    /**
25664     * Called by app main thread to wait for the network policy rules to get updated.
25665     *
25666     * @param procStateSeq The sequence number indicating the process state change that the main
25667     *                     thread is interested in.
25668     */
25669    @Override
25670    public void waitForNetworkStateUpdate(long procStateSeq) {
25671        final int callingUid = Binder.getCallingUid();
25672        if (DEBUG_NETWORK) {
25673            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
25674        }
25675        UidRecord record;
25676        synchronized (this) {
25677            record = mActiveUids.get(callingUid);
25678            if (record == null) {
25679                return;
25680            }
25681        }
25682        synchronized (record.networkStateLock) {
25683            if (record.lastDispatchedProcStateSeq < procStateSeq) {
25684                if (DEBUG_NETWORK) {
25685                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
25686                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
25687                            + " lastProcStateSeqDispatchedToObservers: "
25688                            + record.lastDispatchedProcStateSeq);
25689                }
25690                return;
25691            }
25692            if (record.curProcStateSeq > procStateSeq) {
25693                if (DEBUG_NETWORK) {
25694                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
25695                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
25696                            + ", procStateSeq: " + procStateSeq);
25697                }
25698                return;
25699            }
25700            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
25701                if (DEBUG_NETWORK) {
25702                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
25703                            + procStateSeq + ", so no need to wait. Uid: "
25704                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
25705                            + record.lastNetworkUpdatedProcStateSeq);
25706                }
25707                return;
25708            }
25709            try {
25710                if (DEBUG_NETWORK) {
25711                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
25712                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
25713                }
25714                final long startTime = SystemClock.uptimeMillis();
25715                record.waitingForNetwork = true;
25716                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
25717                record.waitingForNetwork = false;
25718                final long totalTime = SystemClock.uptimeMillis() - startTime;
25719                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
25720                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
25721                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
25722                            + procStateSeq + " UidRec: " + record
25723                            + " validateUidRec: " + mValidateUids.get(callingUid));
25724                }
25725            } catch (InterruptedException e) {
25726                Thread.currentThread().interrupt();
25727            }
25728        }
25729    }
25730
25731    public void waitForBroadcastIdle(PrintWriter pw) {
25732        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
25733        while (true) {
25734            boolean idle = true;
25735            synchronized (this) {
25736                for (BroadcastQueue queue : mBroadcastQueues) {
25737                    if (!queue.isIdle()) {
25738                        final String msg = "Waiting for queue " + queue + " to become idle...";
25739                        pw.println(msg);
25740                        pw.flush();
25741                        Slog.v(TAG, msg);
25742                        idle = false;
25743                    }
25744                }
25745            }
25746
25747            if (idle) {
25748                final String msg = "All broadcast queues are idle!";
25749                pw.println(msg);
25750                pw.flush();
25751                Slog.v(TAG, msg);
25752                return;
25753            } else {
25754                SystemClock.sleep(1000);
25755            }
25756        }
25757    }
25758
25759    /**
25760     * Return the user id of the last resumed activity.
25761     */
25762    @Override
25763    public @UserIdInt int getLastResumedActivityUserId() {
25764        enforceCallingPermission(
25765                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
25766        synchronized (this) {
25767            if (mLastResumedActivity == null) {
25768                return mUserController.getCurrentUserId();
25769            }
25770            return mLastResumedActivity.userId;
25771        }
25772    }
25773
25774    /**
25775     * Kill processes for the user with id userId and that depend on the package named packageName
25776     */
25777    @Override
25778    public void killPackageDependents(String packageName, int userId) {
25779        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
25780        if (packageName == null) {
25781            throw new NullPointerException(
25782                    "Cannot kill the dependents of a package without its name.");
25783        }
25784
25785        long callingId = Binder.clearCallingIdentity();
25786        IPackageManager pm = AppGlobals.getPackageManager();
25787        int pkgUid = -1;
25788        try {
25789            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
25790        } catch (RemoteException e) {
25791        }
25792        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
25793            throw new IllegalArgumentException(
25794                    "Cannot kill dependents of non-existing package " + packageName);
25795        }
25796        try {
25797            synchronized(this) {
25798                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
25799                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
25800                        "dep: " + packageName);
25801            }
25802        } finally {
25803            Binder.restoreCallingIdentity(callingId);
25804        }
25805    }
25806
25807    @Override
25808    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
25809            CharSequence message) throws RemoteException {
25810        if (message != null) {
25811            enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
25812                    "dismissKeyguard()");
25813        }
25814        final long callingId = Binder.clearCallingIdentity();
25815        try {
25816            mKeyguardController.dismissKeyguard(token, callback, message);
25817        } finally {
25818            Binder.restoreCallingIdentity(callingId);
25819        }
25820    }
25821
25822    @Override
25823    public int restartUserInBackground(final int userId) {
25824        return mUserController.restartUser(userId, /* foreground */ false);
25825    }
25826
25827    @Override
25828    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
25829        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
25830                "scheduleApplicationInfoChanged()");
25831
25832        synchronized (this) {
25833            final long origId = Binder.clearCallingIdentity();
25834            try {
25835                updateApplicationInfoLocked(packageNames, userId);
25836            } finally {
25837                Binder.restoreCallingIdentity(origId);
25838            }
25839        }
25840    }
25841
25842    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
25843        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
25844        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
25845            final ProcessRecord app = mLruProcesses.get(i);
25846            if (app.thread == null) {
25847                continue;
25848            }
25849
25850            if (userId != UserHandle.USER_ALL && app.userId != userId) {
25851                continue;
25852            }
25853
25854            final int packageCount = app.pkgList.size();
25855            for (int j = 0; j < packageCount; j++) {
25856                final String packageName = app.pkgList.keyAt(j);
25857                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
25858                    try {
25859                        final ApplicationInfo ai = AppGlobals.getPackageManager()
25860                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
25861                        if (ai != null) {
25862                            app.thread.scheduleApplicationInfoChanged(ai);
25863                        }
25864                    } catch (RemoteException e) {
25865                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
25866                                    packageName, app));
25867                    }
25868                }
25869            }
25870        }
25871        if (updateFrameworkRes) {
25872            // Update system server components that need to know about changed overlays. Because the
25873            // overlay is applied in ActivityThread, we need to serialize through its thread too.
25874            final Executor executor = ActivityThread.currentActivityThread().getExecutor();
25875            final DisplayManagerInternal display =
25876                    LocalServices.getService(DisplayManagerInternal.class);
25877            if (display != null) {
25878                executor.execute(display::onOverlayChanged);
25879            }
25880            if (mWindowManager != null) {
25881                executor.execute(mWindowManager::onOverlayChanged);
25882            }
25883        }
25884    }
25885
25886    /**
25887     * Attach an agent to the specified process (proces name or PID)
25888     */
25889    public void attachAgent(String process, String path) {
25890        try {
25891            synchronized (this) {
25892                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
25893                if (proc == null || proc.thread == null) {
25894                    throw new IllegalArgumentException("Unknown process: " + process);
25895                }
25896
25897                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25898                if (!isDebuggable) {
25899                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25900                        throw new SecurityException("Process not debuggable: " + proc);
25901                    }
25902                }
25903
25904                proc.thread.attachAgent(path);
25905            }
25906        } catch (RemoteException e) {
25907            throw new IllegalStateException("Process disappeared");
25908        }
25909    }
25910
25911    @VisibleForTesting
25912    public static class Injector {
25913        private NetworkManagementInternal mNmi;
25914
25915        public Context getContext() {
25916            return null;
25917        }
25918
25919        public AppOpsService getAppOpsService(File file, Handler handler) {
25920            return new AppOpsService(file, handler);
25921        }
25922
25923        public Handler getUiHandler(ActivityManagerService service) {
25924            return service.new UiHandler();
25925        }
25926
25927        public boolean isNetworkRestrictedForUid(int uid) {
25928            if (ensureHasNetworkManagementInternal()) {
25929                return mNmi.isNetworkRestrictedForUid(uid);
25930            }
25931            return false;
25932        }
25933
25934        private boolean ensureHasNetworkManagementInternal() {
25935            if (mNmi == null) {
25936                mNmi = LocalServices.getService(NetworkManagementInternal.class);
25937            }
25938            return mNmi != null;
25939        }
25940    }
25941
25942    @Override
25943    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
25944            throws RemoteException {
25945        synchronized (this) {
25946            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
25947            if (r == null) {
25948                return;
25949            }
25950            final long origId = Binder.clearCallingIdentity();
25951            try {
25952                r.setShowWhenLocked(showWhenLocked);
25953            } finally {
25954                Binder.restoreCallingIdentity(origId);
25955            }
25956        }
25957    }
25958
25959    @Override
25960    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
25961        synchronized (this) {
25962            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
25963            if (r == null) {
25964                return;
25965            }
25966            final long origId = Binder.clearCallingIdentity();
25967            try {
25968                r.setTurnScreenOn(turnScreenOn);
25969            } finally {
25970                Binder.restoreCallingIdentity(origId);
25971            }
25972        }
25973    }
25974
25975    @Override
25976    public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
25977            throws RemoteException {
25978        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
25979                "registerRemoteAnimations");
25980        synchronized (this) {
25981            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
25982            if (r == null) {
25983                return;
25984            }
25985            final long origId = Binder.clearCallingIdentity();
25986            try {
25987                r.registerRemoteAnimations(definition);
25988            } finally {
25989                Binder.restoreCallingIdentity(origId);
25990            }
25991        }
25992    }
25993}
25994