OSDN Git Service

Merge "Import translations. DO NOT MERGE" into pi-dev
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityManagerService.java
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
17 package com.android.server.am;
18
19 import static android.Manifest.permission.BIND_VOICE_INTERACTION;
20 import static android.Manifest.permission.CHANGE_CONFIGURATION;
21 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
22 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
23 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
24 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
25 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
26 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
27 import static android.Manifest.permission.READ_FRAME_BUFFER;
28 import static android.Manifest.permission.REMOVE_TASKS;
29 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
30 import static android.Manifest.permission.STOP_APP_SWITCHES;
31 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
32 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
33 import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
34 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
35 import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT;
36 import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA;
37 import static android.app.ActivityManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
38 import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE;
39 import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
40 import static android.app.AppOpsManager.OP_NONE;
41 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
42 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
43 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
44 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
45 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
46 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
47 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
48 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
49 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
50 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
51 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
52 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
53 import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
54 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
55 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
56 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
57 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
58 import static android.content.pm.PackageManager.GET_PROVIDERS;
59 import static android.content.pm.PackageManager.MATCH_ANY_USER;
60 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
61 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
62 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
63 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
64 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
65 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
66 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
67 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
68 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
69 import static android.os.Build.VERSION_CODES.N;
70 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
71 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
72 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
73 import static android.os.IServiceManager.DUMP_FLAG_PROTO;
74 import static android.os.Process.BLUETOOTH_UID;
75 import static android.os.Process.FIRST_APPLICATION_UID;
76 import static android.os.Process.FIRST_ISOLATED_UID;
77 import static android.os.Process.LAST_ISOLATED_UID;
78 import static android.os.Process.NFC_UID;
79 import static android.os.Process.PHONE_UID;
80 import static android.os.Process.PROC_CHAR;
81 import static android.os.Process.PROC_OUT_LONG;
82 import static android.os.Process.PROC_PARENS;
83 import static android.os.Process.PROC_SPACE_TERM;
84 import static android.os.Process.ProcessStartResult;
85 import static android.os.Process.ROOT_UID;
86 import static android.os.Process.SCHED_FIFO;
87 import static android.os.Process.SCHED_OTHER;
88 import static android.os.Process.SCHED_RESET_ON_FORK;
89 import static android.os.Process.SE_UID;
90 import static android.os.Process.SHELL_UID;
91 import static android.os.Process.SIGNAL_QUIT;
92 import static android.os.Process.SIGNAL_USR1;
93 import static android.os.Process.SYSTEM_UID;
94 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
95 import static android.os.Process.THREAD_GROUP_DEFAULT;
96 import static android.os.Process.THREAD_GROUP_RESTRICTED;
97 import static android.os.Process.THREAD_GROUP_TOP_APP;
98 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
99 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
100 import static android.os.Process.getFreeMemory;
101 import static android.os.Process.getTotalMemory;
102 import static android.os.Process.isThreadInProcess;
103 import static android.os.Process.killProcess;
104 import static android.os.Process.killProcessQuiet;
105 import static android.os.Process.myPid;
106 import static android.os.Process.myUid;
107 import static android.os.Process.readProcFile;
108 import static android.os.Process.removeAllProcessGroups;
109 import static android.os.Process.sendSignal;
110 import static android.os.Process.setProcessGroup;
111 import static android.os.Process.setThreadPriority;
112 import static android.os.Process.setThreadScheduler;
113 import static android.os.Process.startWebView;
114 import static android.os.Process.zygoteProcess;
115 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
116 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
117 import static android.provider.Settings.Global.DEBUG_APP;
118 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
119 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
120 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
121 import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
122 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
123 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
124 import static android.provider.Settings.System.FONT_SCALE;
125 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
126 import static android.text.format.DateUtils.DAY_IN_MILLIS;
127 import static android.view.Display.DEFAULT_DISPLAY;
128 import static android.view.Display.INVALID_DISPLAY;
129 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
130 import static com.android.internal.util.XmlUtils.readIntAttribute;
131 import static com.android.internal.util.XmlUtils.readLongAttribute;
132 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
133 import static com.android.internal.util.XmlUtils.writeIntAttribute;
134 import static com.android.internal.util.XmlUtils.writeLongAttribute;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
140 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
141 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
142 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
143 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
144 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
145 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
146 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
147 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
148 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
149 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
150 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
151 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
152 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
153 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
154 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
155 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
156 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
157 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
158 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
159 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
160 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
161 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
162 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
163 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
164 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
165 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
166 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
167 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
168 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
169 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
170 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
171 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
172 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
173 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
174 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
175 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
176 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
177 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
178 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
179 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
180 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
181 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
182 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
183 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
184 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
185 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
186 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
187 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
188 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
189 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
190 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
191 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
192 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
193 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
194 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
195 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
196 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
197 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
198 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
199 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
200 import static com.android.server.am.MemoryStatUtil.hasMemcg;
201 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
202 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
203 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
204 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
205 import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
206 import static android.view.WindowManager.TRANSIT_NONE;
207 import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
208 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
209 import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
210 import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
211 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
212 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
213 import static org.xmlpull.v1.XmlPullParser.START_TAG;
214
215 import android.Manifest;
216 import android.Manifest.permission;
217 import android.annotation.NonNull;
218 import android.annotation.Nullable;
219 import android.annotation.UserIdInt;
220 import android.app.Activity;
221 import android.app.ActivityManager;
222 import android.app.ActivityManager.RunningTaskInfo;
223 import android.app.ActivityManager.StackInfo;
224 import android.app.ActivityManager.TaskSnapshot;
225 import android.app.ActivityManagerInternal;
226 import android.app.ActivityManagerInternal.ScreenObserver;
227 import android.app.ActivityManagerInternal.SleepToken;
228 import android.app.ActivityManagerProto;
229 import android.app.ActivityOptions;
230 import android.app.ActivityThread;
231 import android.app.AlertDialog;
232 import android.app.AppGlobals;
233 import android.app.AppOpsManager;
234 import android.app.ApplicationErrorReport;
235 import android.app.ApplicationThreadConstants;
236 import android.app.BroadcastOptions;
237 import android.app.ContentProviderHolder;
238 import android.app.Dialog;
239 import android.app.GrantedUriPermission;
240 import android.app.IActivityController;
241 import android.app.IActivityManager;
242 import android.app.IApplicationThread;
243 import android.app.IAssistDataReceiver;
244 import android.app.IInstrumentationWatcher;
245 import android.app.INotificationManager;
246 import android.app.IProcessObserver;
247 import android.app.IServiceConnection;
248 import android.app.IStopUserCallback;
249 import android.app.ITaskStackListener;
250 import android.app.IUiAutomationConnection;
251 import android.app.IUidObserver;
252 import android.app.IUserSwitchObserver;
253 import android.app.Instrumentation;
254 import android.app.Notification;
255 import android.app.NotificationManager;
256 import android.app.PendingIntent;
257 import android.app.PictureInPictureParams;
258 import android.app.ProcessMemoryState;
259 import android.app.ProfilerInfo;
260 import android.app.RemoteAction;
261 import android.app.WaitResult;
262 import android.app.WindowConfiguration.ActivityType;
263 import android.app.WindowConfiguration.WindowingMode;
264 import android.app.admin.DevicePolicyCache;
265 import android.app.assist.AssistContent;
266 import android.app.assist.AssistStructure;
267 import android.app.backup.IBackupManager;
268 import android.app.servertransaction.ConfigurationChangeItem;
269 import android.app.usage.UsageEvents;
270 import android.app.usage.UsageStatsManagerInternal;
271 import android.appwidget.AppWidgetManager;
272 import android.content.ActivityNotFoundException;
273 import android.content.BroadcastReceiver;
274 import android.content.ClipData;
275 import android.content.ComponentCallbacks2;
276 import android.content.ComponentName;
277 import android.content.ContentProvider;
278 import android.content.ContentResolver;
279 import android.content.Context;
280 import android.content.DialogInterface;
281 import android.content.IContentProvider;
282 import android.content.IIntentReceiver;
283 import android.content.IIntentSender;
284 import android.content.Intent;
285 import android.content.IntentFilter;
286 import android.content.pm.ActivityInfo;
287 import android.content.pm.ApplicationInfo;
288 import android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy;
289 import android.content.pm.ConfigurationInfo;
290 import android.content.pm.IPackageDataObserver;
291 import android.content.pm.IPackageManager;
292 import android.content.pm.InstrumentationInfo;
293 import android.content.pm.PackageInfo;
294 import android.content.pm.PackageManager;
295 import android.content.pm.PackageManager.NameNotFoundException;
296 import android.content.pm.PackageManagerInternal;
297 import android.content.pm.ParceledListSlice;
298 import android.content.pm.PathPermission;
299 import android.content.pm.PermissionInfo;
300 import android.content.pm.ProviderInfo;
301 import android.content.pm.ResolveInfo;
302 import android.content.pm.SELinuxUtil;
303 import android.content.pm.ServiceInfo;
304 import android.content.pm.UserInfo;
305 import android.content.res.CompatibilityInfo;
306 import android.content.res.Configuration;
307 import android.content.res.Resources;
308 import android.database.ContentObserver;
309 import android.graphics.Bitmap;
310 import android.graphics.Point;
311 import android.graphics.Rect;
312 import android.hardware.display.DisplayManagerInternal;
313 import android.location.LocationManager;
314 import android.media.audiofx.AudioEffect;
315 import android.metrics.LogMaker;
316 import android.net.Proxy;
317 import android.net.ProxyInfo;
318 import android.net.Uri;
319 import android.os.BatteryStats;
320 import android.os.Binder;
321 import android.os.Build;
322 import android.os.Bundle;
323 import android.os.Debug;
324 import android.os.DropBoxManager;
325 import android.os.Environment;
326 import android.os.FactoryTest;
327 import android.os.FileObserver;
328 import android.os.FileUtils;
329 import android.os.Handler;
330 import android.os.IBinder;
331 import android.os.IDeviceIdentifiersPolicyService;
332 import android.os.IPermissionController;
333 import android.os.IProcessInfoService;
334 import android.os.IProgressListener;
335 import android.os.LocaleList;
336 import android.os.Looper;
337 import android.os.Message;
338 import android.os.Parcel;
339 import android.os.ParcelFileDescriptor;
340 import android.os.PersistableBundle;
341 import android.os.PowerManager;
342 import android.os.PowerManager.ServiceType;
343 import android.os.PowerManagerInternal;
344 import android.os.Process;
345 import android.os.RemoteCallbackList;
346 import android.os.RemoteException;
347 import android.os.ResultReceiver;
348 import android.os.ServiceManager;
349 import android.os.ShellCallback;
350 import android.os.StrictMode;
351 import android.os.SystemClock;
352 import android.os.SystemProperties;
353 import android.os.Trace;
354 import android.os.TransactionTooLargeException;
355 import android.os.UpdateLock;
356 import android.os.UserHandle;
357 import android.os.UserManager;
358 import android.os.WorkSource;
359 import android.os.storage.IStorageManager;
360 import android.os.storage.StorageManager;
361 import android.os.storage.StorageManagerInternal;
362 import android.provider.Downloads;
363 import android.provider.Settings;
364 import android.service.voice.IVoiceInteractionSession;
365 import android.service.voice.VoiceInteractionManagerInternal;
366 import android.telecom.TelecomManager;
367 import android.text.TextUtils;
368 import android.text.format.DateUtils;
369 import android.text.format.Time;
370 import android.text.style.SuggestionSpan;
371 import android.util.ArrayMap;
372 import android.util.ArraySet;
373 import android.util.AtomicFile;
374 import android.util.DebugUtils;
375 import android.util.EventLog;
376 import android.util.Log;
377 import android.util.LongSparseArray;
378 import android.util.Pair;
379 import android.util.PrintWriterPrinter;
380 import android.util.Slog;
381 import android.util.SparseArray;
382 import android.util.SparseIntArray;
383 import android.util.StatsLog;
384 import android.util.TimeUtils;
385 import android.util.TimingsTraceLog;
386 import android.util.Xml;
387 import android.util.proto.ProtoOutputStream;
388 import android.util.proto.ProtoUtils;
389 import android.view.Gravity;
390 import android.view.IRecentsAnimationRunner;
391 import android.view.LayoutInflater;
392 import android.view.RemoteAnimationAdapter;
393 import android.view.RemoteAnimationDefinition;
394 import android.view.View;
395 import android.view.WindowManager;
396 import android.view.autofill.AutofillManagerInternal;
397
398 import com.android.internal.R;
399 import com.android.internal.annotations.GuardedBy;
400 import com.android.internal.annotations.VisibleForTesting;
401 import com.android.internal.app.AssistUtils;
402 import com.android.internal.app.DumpHeapActivity;
403 import com.android.internal.app.IAppOpsCallback;
404 import com.android.internal.app.IAppOpsService;
405 import com.android.internal.app.IVoiceInteractor;
406 import com.android.internal.app.ProcessMap;
407 import com.android.internal.app.SystemUserHomeActivity;
408 import com.android.internal.app.procstats.ProcessStats;
409 import com.android.internal.logging.MetricsLogger;
410 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
411 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
412 import com.android.internal.notification.SystemNotificationChannels;
413 import com.android.internal.os.BackgroundThread;
414 import com.android.internal.os.BatteryStatsImpl;
415 import com.android.internal.os.BinderInternal;
416 import com.android.internal.os.logging.MetricsLoggerWrapper;
417 import com.android.internal.os.ByteTransferPipe;
418 import com.android.internal.os.IResultReceiver;
419 import com.android.internal.os.ProcessCpuTracker;
420 import com.android.internal.os.TransferPipe;
421 import com.android.internal.os.Zygote;
422 import com.android.internal.policy.IKeyguardDismissCallback;
423 import com.android.internal.policy.KeyguardDismissCallback;
424 import com.android.internal.telephony.TelephonyIntents;
425 import com.android.internal.util.ArrayUtils;
426 import com.android.internal.util.DumpUtils;
427 import com.android.internal.util.FastPrintWriter;
428 import com.android.internal.util.FastXmlSerializer;
429 import com.android.internal.util.MemInfoReader;
430 import com.android.internal.util.Preconditions;
431 import com.android.server.AlarmManagerInternal;
432 import com.android.server.AppOpsService;
433 import com.android.server.AttributeCache;
434 import com.android.server.BinderCallsStatsService;
435 import com.android.server.DeviceIdleController;
436 import com.android.server.IntentResolver;
437 import com.android.server.IoThread;
438 import com.android.server.LocalServices;
439 import com.android.server.LockGuard;
440 import com.android.server.NetworkManagementInternal;
441 import com.android.server.RescueParty;
442 import com.android.server.ServiceThread;
443 import com.android.server.SystemConfig;
444 import com.android.server.SystemService;
445 import com.android.server.SystemServiceManager;
446 import com.android.server.ThreadPriorityBooster;
447 import com.android.server.Watchdog;
448 import com.android.server.am.ActivityStack.ActivityState;
449 import com.android.server.am.MemoryStatUtil.MemoryStat;
450 import com.android.server.am.ActivityManagerServiceProto;
451 import com.android.server.am.ActivityManagerServiceDumpActivitiesProto;
452 import com.android.server.am.ActivityManagerServiceDumpBroadcastsProto;
453 import com.android.server.am.ActivityManagerServiceDumpProcessesProto;
454 import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
455 import com.android.server.am.ActivityManagerServiceDumpServicesProto;
456 import com.android.server.am.GrantUriProto;
457 import com.android.server.am.ImportanceTokenProto;
458 import com.android.server.am.MemInfoDumpProto;
459 import com.android.server.am.NeededUriGrantsProto;
460 import com.android.server.am.ProcessOomProto;
461 import com.android.server.am.ProcessToGcProto;
462 import com.android.server.am.StickyBroadcastProto;
463 import com.android.server.firewall.IntentFirewall;
464 import com.android.server.job.JobSchedulerInternal;
465 import com.android.server.pm.Installer;
466 import com.android.server.pm.Installer.InstallerException;
467 import com.android.server.pm.dex.DexManager;
468 import com.android.server.utils.PriorityDump;
469 import com.android.server.vr.VrManagerInternal;
470 import com.android.server.wm.PinnedStackWindowController;
471 import com.android.server.wm.WindowManagerService;
472
473 import dalvik.system.VMRuntime;
474
475 import libcore.io.IoUtils;
476 import libcore.util.EmptyArray;
477
478 import com.google.android.collect.Lists;
479 import com.google.android.collect.Maps;
480
481 import org.xmlpull.v1.XmlPullParser;
482 import org.xmlpull.v1.XmlPullParserException;
483 import org.xmlpull.v1.XmlSerializer;
484
485 import java.io.File;
486 import java.io.FileDescriptor;
487 import java.io.FileInputStream;
488 import java.io.FileNotFoundException;
489 import java.io.FileOutputStream;
490 import java.io.IOException;
491 import java.io.InputStreamReader;
492 import java.io.PrintWriter;
493 import java.io.StringWriter;
494 import java.io.UnsupportedEncodingException;
495 import java.lang.ref.WeakReference;
496 import java.nio.charset.StandardCharsets;
497 import java.text.DateFormat;
498 import java.text.SimpleDateFormat;
499 import java.util.ArrayList;
500 import java.util.Arrays;
501 import java.util.Collections;
502 import java.util.Comparator;
503 import java.util.Date;
504 import java.util.HashMap;
505 import java.util.HashSet;
506 import java.util.Iterator;
507 import java.util.List;
508 import java.util.Locale;
509 import java.util.Map;
510 import java.util.Objects;
511 import java.util.Set;
512 import java.util.concurrent.CountDownLatch;
513 import java.util.concurrent.Executor;
514 import java.util.concurrent.atomic.AtomicBoolean;
515 import java.util.concurrent.atomic.AtomicLong;
516
517 public class ActivityManagerService extends IActivityManager.Stub
518         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
519
520     /**
521      * Priority we boost main thread and RT of top app to.
522      */
523     public static final int TOP_APP_PRIORITY_BOOST = -10;
524
525     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
526     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
527     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
528     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
529     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
530     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
531     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
532     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
533     private static final String TAG_LRU = TAG + POSTFIX_LRU;
534     private static final String TAG_MU = TAG + POSTFIX_MU;
535     private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
536     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
537     private static final String TAG_POWER = TAG + POSTFIX_POWER;
538     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
539     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
540     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
541     private static final String TAG_PSS = TAG + POSTFIX_PSS;
542     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
543     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
544     private static final String TAG_STACK = TAG + POSTFIX_STACK;
545     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
546     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
547     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
548     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
549
550     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
551     // here so that while the job scheduler can depend on AMS, the other way around
552     // need not be the case.
553     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
554
555     /** Control over CPU and battery monitoring */
556     // write battery stats every 30 minutes.
557     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
558     static final boolean MONITOR_CPU_USAGE = true;
559     // don't sample cpu less than every 5 seconds.
560     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
561     // wait possibly forever for next cpu sample.
562     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
563     static final boolean MONITOR_THREAD_CPU_USAGE = false;
564
565     // The flags that are set for all calls we make to the package manager.
566     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
567
568     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
569
570     // Maximum number of receivers an app can register.
571     private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000;
572
573     // Amount of time after a call to stopAppSwitches() during which we will
574     // prevent further untrusted switches from happening.
575     static final long APP_SWITCH_DELAY_TIME = 5*1000;
576
577     // How long we wait for a launched process to attach to the activity manager
578     // before we decide it's never going to come up for real.
579     static final int PROC_START_TIMEOUT = 10*1000;
580     // How long we wait for an attached process to publish its content providers
581     // before we decide it must be hung.
582     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
583
584     /**
585      * How long we wait for an provider to be published. Should be longer than
586      * {@link #CONTENT_PROVIDER_PUBLISH_TIMEOUT}.
587      */
588     static final int CONTENT_PROVIDER_WAIT_TIMEOUT = 20 * 1000;
589
590     // How long we wait for a launched process to attach to the activity manager
591     // before we decide it's never going to come up for real, when the process was
592     // started with a wrapper for instrumentation (such as Valgrind) because it
593     // could take much longer than usual.
594     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
595
596     // How long we allow a receiver to run before giving up on it.
597     static final int BROADCAST_FG_TIMEOUT = 10*1000;
598     static final int BROADCAST_BG_TIMEOUT = 60*1000;
599
600     // How long we wait until we timeout on key dispatching.
601     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
602
603     // How long we wait until we timeout on key dispatching during instrumentation.
604     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
605
606     // Disable hidden API checks for the newly started instrumentation.
607     // Must be kept in sync with Am.
608     private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
609
610     // How long to wait in getAssistContextExtras for the activity and foreground services
611     // to respond with the result.
612     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
613
614     // How long top wait when going through the modern assist (which doesn't need to block
615     // on getting this result before starting to launch its UI).
616     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
617
618     // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
619     static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
620
621     // Maximum number of persisted Uri grants a package is allowed
622     static final int MAX_PERSISTED_URI_GRANTS = 128;
623
624     static final int MY_PID = myPid();
625
626     static final String[] EMPTY_STRING_ARRAY = new String[0];
627
628     // How many bytes to write into the dropbox log before truncating
629     static final int DROPBOX_MAX_SIZE = 192 * 1024;
630     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
631     // as one line, but close enough for now.
632     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
633
634     /** If a UID observer takes more than this long, send a WTF. */
635     private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
636
637     // Access modes for handleIncomingUser.
638     static final int ALLOW_NON_FULL = 0;
639     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
640     static final int ALLOW_FULL_ONLY = 2;
641
642     // Necessary ApplicationInfo flags to mark an app as persistent
643     private static final int PERSISTENT_MASK =
644             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
645
646     // Intent sent when remote bugreport collection has been completed
647     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
648             "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
649
650     // Used to indicate that an app transition should be animated.
651     static final boolean ANIMATE = true;
652
653     // Determines whether to take full screen screenshots
654     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
655
656     /**
657      * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
658      */
659     private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
660
661     /**
662      * State indicating that there is no need for any blocking for network.
663      */
664     @VisibleForTesting
665     static final int NETWORK_STATE_NO_CHANGE = 0;
666
667     /**
668      * State indicating that the main thread needs to be informed about the network wait.
669      */
670     @VisibleForTesting
671     static final int NETWORK_STATE_BLOCK = 1;
672
673     /**
674      * State indicating that any threads waiting for network state to get updated can be unblocked.
675      */
676     @VisibleForTesting
677     static final int NETWORK_STATE_UNBLOCK = 2;
678
679     // Max character limit for a notification title. If the notification title is larger than this
680     // the notification will not be legible to the user.
681     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
682
683     private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
684
685     /** All system services */
686     SystemServiceManager mSystemServiceManager;
687
688     // Wrapper around VoiceInteractionServiceManager
689     private AssistUtils mAssistUtils;
690
691     // Keeps track of the active voice interaction service component, notified from
692     // VoiceInteractionManagerService
693     ComponentName mActiveVoiceInteractionServiceComponent;
694
695     private Installer mInstaller;
696
697     /** Run all ActivityStacks through this */
698     final ActivityStackSupervisor mStackSupervisor;
699     private final KeyguardController mKeyguardController;
700
701     private final ActivityStartController mActivityStartController;
702
703     private final ClientLifecycleManager mLifecycleManager;
704
705     final TaskChangeNotificationController mTaskChangeNotificationController;
706
707     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
708
709     final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
710
711     public final IntentFirewall mIntentFirewall;
712
713     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
714     // default action automatically.  Important for devices without direct input
715     // devices.
716     private boolean mShowDialogs = true;
717
718     private final VrController mVrController;
719
720     // VR Vr2d Display Id.
721     int mVr2dDisplayId = INVALID_DISPLAY;
722
723     // Whether we should use SCHED_FIFO for UI and RenderThreads.
724     private boolean mUseFifoUiScheduling = false;
725
726     private static final String SYSUI_COMPONENT_NAME = "com.android.systemui/.SystemUIService";
727
728     BroadcastQueue mFgBroadcastQueue;
729     BroadcastQueue mBgBroadcastQueue;
730     // Convenient for easy iteration over the queues. Foreground is first
731     // so that dispatch of foreground broadcasts gets precedence.
732     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
733
734     BroadcastStats mLastBroadcastStats;
735     BroadcastStats mCurBroadcastStats;
736
737     BroadcastQueue broadcastQueueForIntent(Intent intent) {
738         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
739         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
740                 "Broadcast intent " + intent + " on "
741                 + (isFg ? "foreground" : "background") + " queue");
742         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
743     }
744
745     /**
746      * The last resumed activity. This is identical to the current resumed activity most
747      * of the time but could be different when we're pausing one activity before we resume
748      * another activity.
749      */
750     private ActivityRecord mLastResumedActivity;
751
752     /**
753      * The activity that is currently being traced as the active resumed activity.
754      *
755      * @see #updateResumedAppTrace
756      */
757     private @Nullable ActivityRecord mTracedResumedActivity;
758
759     /**
760      * If non-null, we are tracking the time the user spends in the currently focused app.
761      */
762     private AppTimeTracker mCurAppTimeTracker;
763
764     /**
765      * List of intents that were used to start the most recent tasks.
766      */
767     private final RecentTasks mRecentTasks;
768
769     /**
770      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
771      */
772     String mDeviceOwnerName;
773
774     /**
775      * The controller for all operations related to locktask.
776      */
777     private final LockTaskController mLockTaskController;
778
779     final UserController mUserController;
780
781     /**
782      * Packages that are being allowed to perform unrestricted app switches.  Mapping is
783      * User -> Type -> uid.
784      */
785     final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
786
787     final AppErrors mAppErrors;
788
789     final AppWarnings mAppWarnings;
790
791     /**
792      * Dump of the activity state at the time of the last ANR. Cleared after
793      * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
794      */
795     String mLastANRState;
796
797     /**
798      * Indicates the maximum time spent waiting for the network rules to get updated.
799      */
800     @VisibleForTesting
801     long mWaitForNetworkTimeoutMs;
802
803     /** Total # of UID change events dispatched, shown in dumpsys. */
804     int mUidChangeDispatchCount;
805
806     /**
807      * Helper class which strips out priority and proto arguments then calls the dump function with
808      * the appropriate arguments. If priority arguments are omitted, function calls the legacy
809      * dump command.
810      * If priority arguments are omitted all sections are dumped, otherwise sections are dumped
811      * according to their priority.
812      */
813     private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
814         @Override
815         public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
816                 boolean asProto) {
817             if (asProto) return;
818             doDump(fd, pw, new String[]{"activities"}, asProto);
819             doDump(fd, pw, new String[]{"service", SYSUI_COMPONENT_NAME}, asProto);
820         }
821
822         @Override
823         public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
824             doDump(fd, pw, new String[]{"-a", "--normal-priority"}, asProto);
825         }
826
827         @Override
828         public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
829             doDump(fd, pw, args, asProto);
830         }
831     };
832
833     public boolean canShowErrorDialogs() {
834         return mShowDialogs && !mSleeping && !mShuttingDown
835                 && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
836                 && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
837                         mUserController.getCurrentUserId())
838                 && !(UserManager.isDeviceInDemoMode(mContext)
839                         && mUserController.getCurrentUser().isDemo());
840     }
841
842     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
843             THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
844
845     static void boostPriorityForLockedSection() {
846         sThreadPriorityBooster.boost();
847     }
848
849     static void resetPriorityAfterLockedSection() {
850         sThreadPriorityBooster.reset();
851     }
852
853     public class PendingAssistExtras extends Binder implements Runnable {
854         public final ActivityRecord activity;
855         public boolean isHome;
856         public final Bundle extras;
857         public final Intent intent;
858         public final String hint;
859         public final IAssistDataReceiver receiver;
860         public final int userHandle;
861         public boolean haveResult = false;
862         public Bundle result = null;
863         public AssistStructure structure = null;
864         public AssistContent content = null;
865         public Bundle receiverExtras;
866
867         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
868                 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
869                 int _userHandle) {
870             activity = _activity;
871             extras = _extras;
872             intent = _intent;
873             hint = _hint;
874             receiver = _receiver;
875             receiverExtras = _receiverExtras;
876             userHandle = _userHandle;
877         }
878
879         @Override
880         public void run() {
881             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
882             synchronized (this) {
883                 haveResult = true;
884                 notifyAll();
885             }
886             pendingAssistExtrasTimedOut(this);
887         }
888     }
889
890     final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
891
892     /**
893      * Process management.
894      */
895     final ProcessList mProcessList = new ProcessList();
896
897     /**
898      * All of the applications we currently have running organized by name.
899      * The keys are strings of the application package name (as
900      * returned by the package manager), and the keys are ApplicationRecord
901      * objects.
902      */
903     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
904
905     /**
906      * Tracking long-term execution of processes to look for abuse and other
907      * bad app behavior.
908      */
909     final ProcessStatsService mProcessStats;
910
911     /**
912      * The currently running isolated processes.
913      */
914     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
915
916     /**
917      * Counter for assigning isolated process uids, to avoid frequently reusing the
918      * same ones.
919      */
920     int mNextIsolatedProcessUid = 0;
921
922     /**
923      * The currently running heavy-weight process, if any.
924      */
925     ProcessRecord mHeavyWeightProcess = null;
926
927     /**
928      * Non-persistent appId whitelist for background restrictions
929      */
930     int[] mBackgroundAppIdWhitelist = new int[] {
931             BLUETOOTH_UID
932     };
933
934     /**
935      * Broadcast actions that will always be deliverable to unlaunched/background apps
936      */
937     ArraySet<String> mBackgroundLaunchBroadcasts;
938
939     /**
940      * All of the processes we currently have running organized by pid.
941      * The keys are the pid running the application.
942      *
943      * <p>NOTE: This object is protected by its own lock, NOT the global
944      * activity manager lock!
945      */
946     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
947
948     /**
949      * All of the processes that have been forced to be important.  The key
950      * is the pid of the caller who requested it (we hold a death
951      * link on it).
952      */
953     abstract class ImportanceToken implements IBinder.DeathRecipient {
954         final int pid;
955         final IBinder token;
956         final String reason;
957
958         ImportanceToken(int _pid, IBinder _token, String _reason) {
959             pid = _pid;
960             token = _token;
961             reason = _reason;
962         }
963
964         @Override
965         public String toString() {
966             return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
967                     + " " + reason + " " + pid + " " + token + " }";
968         }
969
970         void writeToProto(ProtoOutputStream proto, long fieldId) {
971             final long pToken = proto.start(fieldId);
972             proto.write(ImportanceTokenProto.PID, pid);
973             if (token != null) {
974                 proto.write(ImportanceTokenProto.TOKEN, token.toString());
975             }
976             proto.write(ImportanceTokenProto.REASON, reason);
977             proto.end(pToken);
978         }
979     }
980     final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
981
982     /**
983      * List of records for processes that someone had tried to start before the
984      * system was ready.  We don't start them at that point, but ensure they
985      * are started by the time booting is complete.
986      */
987     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
988
989     /**
990      * List of persistent applications that are in the process
991      * of being started.
992      */
993     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
994
995     /**
996      * Processes that are being forcibly torn down.
997      */
998     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
999
1000     /**
1001      * List of running applications, sorted by recent usage.
1002      * The first entry in the list is the least recently used.
1003      */
1004     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
1005
1006     /**
1007      * Where in mLruProcesses that the processes hosting activities start.
1008      */
1009     int mLruProcessActivityStart = 0;
1010
1011     /**
1012      * Where in mLruProcesses that the processes hosting services start.
1013      * This is after (lower index) than mLruProcessesActivityStart.
1014      */
1015     int mLruProcessServiceStart = 0;
1016
1017     /**
1018      * List of processes that should gc as soon as things are idle.
1019      */
1020     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
1021
1022     /**
1023      * Processes we want to collect PSS data from.
1024      */
1025     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
1026
1027     private boolean mBinderTransactionTrackingEnabled = false;
1028
1029     /**
1030      * Last time we requested PSS data of all processes.
1031      */
1032     long mLastFullPssTime = SystemClock.uptimeMillis();
1033
1034     /**
1035      * If set, the next time we collect PSS data we should do a full collection
1036      * with data from native processes and the kernel.
1037      */
1038     boolean mFullPssPending = false;
1039
1040     /**
1041      * This is the process holding what we currently consider to be
1042      * the "home" activity.
1043      */
1044     ProcessRecord mHomeProcess;
1045
1046     /**
1047      * This is the process holding the activity the user last visited that
1048      * is in a different process from the one they are currently in.
1049      */
1050     ProcessRecord mPreviousProcess;
1051
1052     /**
1053      * The time at which the previous process was last visible.
1054      */
1055     long mPreviousProcessVisibleTime;
1056
1057     /**
1058      * Track all uids that have actively running processes.
1059      */
1060     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1061
1062     /**
1063      * This is for verifying the UID report flow.
1064      */
1065     static final boolean VALIDATE_UID_STATES = true;
1066     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1067
1068     /**
1069      * Packages that the user has asked to have run in screen size
1070      * compatibility mode instead of filling the screen.
1071      */
1072     final CompatModePackages mCompatModePackages;
1073
1074     /**
1075      * Set of IntentSenderRecord objects that are currently active.
1076      */
1077     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1078             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1079
1080     /**
1081      * Fingerprints (hashCode()) of stack traces that we've
1082      * already logged DropBox entries for.  Guarded by itself.  If
1083      * something (rogue user app) forces this over
1084      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1085      */
1086     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1087     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1088
1089     /**
1090      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1091      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1092      */
1093     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1094
1095     /**
1096      * Resolver for broadcast intents to registered receivers.
1097      * Holds BroadcastFilter (subclass of IntentFilter).
1098      */
1099     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1100             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1101         @Override
1102         protected boolean allowFilterResult(
1103                 BroadcastFilter filter, List<BroadcastFilter> dest) {
1104             IBinder target = filter.receiverList.receiver.asBinder();
1105             for (int i = dest.size() - 1; i >= 0; i--) {
1106                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
1107                     return false;
1108                 }
1109             }
1110             return true;
1111         }
1112
1113         @Override
1114         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1115             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1116                     || userId == filter.owningUserId) {
1117                 return super.newResult(filter, match, userId);
1118             }
1119             return null;
1120         }
1121
1122         @Override
1123         protected BroadcastFilter[] newArray(int size) {
1124             return new BroadcastFilter[size];
1125         }
1126
1127         @Override
1128         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1129             return packageName.equals(filter.packageName);
1130         }
1131     };
1132
1133     /**
1134      * State of all active sticky broadcasts per user.  Keys are the action of the
1135      * sticky Intent, values are an ArrayList of all broadcasted intents with
1136      * that action (which should usually be one).  The SparseArray is keyed
1137      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1138      * for stickies that are sent to all users.
1139      */
1140     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1141             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1142
1143     final ActiveServices mServices;
1144
1145     final static class Association {
1146         final int mSourceUid;
1147         final String mSourceProcess;
1148         final int mTargetUid;
1149         final ComponentName mTargetComponent;
1150         final String mTargetProcess;
1151
1152         int mCount;
1153         long mTime;
1154
1155         int mNesting;
1156         long mStartTime;
1157
1158         // states of the source process when the bind occurred.
1159         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1160         long mLastStateUptime;
1161         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1162                 - ActivityManager.MIN_PROCESS_STATE+1];
1163
1164         Association(int sourceUid, String sourceProcess, int targetUid,
1165                 ComponentName targetComponent, String targetProcess) {
1166             mSourceUid = sourceUid;
1167             mSourceProcess = sourceProcess;
1168             mTargetUid = targetUid;
1169             mTargetComponent = targetComponent;
1170             mTargetProcess = targetProcess;
1171         }
1172     }
1173
1174     /**
1175      * When service association tracking is enabled, this is all of the associations we
1176      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1177      * -> association data.
1178      */
1179     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1180             mAssociations = new SparseArray<>();
1181     boolean mTrackingAssociations;
1182
1183     /**
1184      * Backup/restore process management
1185      */
1186     String mBackupAppName = null;
1187     BackupRecord mBackupTarget = null;
1188
1189     final ProviderMap mProviderMap;
1190
1191     /**
1192      * List of content providers who have clients waiting for them.  The
1193      * application is currently being launched and the provider will be
1194      * removed from this list once it is published.
1195      */
1196     final ArrayList<ContentProviderRecord> mLaunchingProviders
1197             = new ArrayList<ContentProviderRecord>();
1198
1199     /**
1200      * File storing persisted {@link #mGrantedUriPermissions}.
1201      */
1202     private final AtomicFile mGrantFile;
1203
1204     /** XML constants used in {@link #mGrantFile} */
1205     private static final String TAG_URI_GRANTS = "uri-grants";
1206     private static final String TAG_URI_GRANT = "uri-grant";
1207     private static final String ATTR_USER_HANDLE = "userHandle";
1208     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1209     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1210     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1211     private static final String ATTR_TARGET_PKG = "targetPkg";
1212     private static final String ATTR_URI = "uri";
1213     private static final String ATTR_MODE_FLAGS = "modeFlags";
1214     private static final String ATTR_CREATED_TIME = "createdTime";
1215     private static final String ATTR_PREFIX = "prefix";
1216
1217     /**
1218      * Global set of specific {@link Uri} permissions that have been granted.
1219      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1220      * to {@link UriPermission#uri} to {@link UriPermission}.
1221      */
1222     @GuardedBy("this")
1223     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1224             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1225
1226     public static class GrantUri {
1227         public final int sourceUserId;
1228         public final Uri uri;
1229         public boolean prefix;
1230
1231         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1232             this.sourceUserId = sourceUserId;
1233             this.uri = uri;
1234             this.prefix = prefix;
1235         }
1236
1237         @Override
1238         public int hashCode() {
1239             int hashCode = 1;
1240             hashCode = 31 * hashCode + sourceUserId;
1241             hashCode = 31 * hashCode + uri.hashCode();
1242             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1243             return hashCode;
1244         }
1245
1246         @Override
1247         public boolean equals(Object o) {
1248             if (o instanceof GrantUri) {
1249                 GrantUri other = (GrantUri) o;
1250                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1251                         && prefix == other.prefix;
1252             }
1253             return false;
1254         }
1255
1256         @Override
1257         public String toString() {
1258             String result = uri.toString() + " [user " + sourceUserId + "]";
1259             if (prefix) result += " [prefix]";
1260             return result;
1261         }
1262
1263         public String toSafeString() {
1264             String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1265             if (prefix) result += " [prefix]";
1266             return result;
1267         }
1268
1269         public void writeToProto(ProtoOutputStream proto, long fieldId) {
1270             long token = proto.start(fieldId);
1271             proto.write(GrantUriProto.URI, uri.toString());
1272             proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
1273             proto.end(token);
1274         }
1275
1276         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1277             if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
1278                 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1279                         ContentProvider.getUriWithoutUserId(uri), false);
1280             } else {
1281                 return new GrantUri(defaultSourceUserHandle, uri, false);
1282             }
1283         }
1284     }
1285
1286     boolean mSystemProvidersInstalled;
1287
1288     CoreSettingsObserver mCoreSettingsObserver;
1289
1290     FontScaleSettingObserver mFontScaleSettingObserver;
1291
1292     private final class FontScaleSettingObserver extends ContentObserver {
1293         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1294         private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
1295
1296         public FontScaleSettingObserver() {
1297             super(mHandler);
1298             ContentResolver resolver = mContext.getContentResolver();
1299             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1300             resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
1301                     UserHandle.USER_ALL);
1302         }
1303
1304         @Override
1305         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1306             if (mFontScaleUri.equals(uri)) {
1307                 updateFontScaleIfNeeded(userId);
1308             } else if (mHideErrorDialogsUri.equals(uri)) {
1309                 synchronized (ActivityManagerService.this) {
1310                     updateShouldShowDialogsLocked(getGlobalConfiguration());
1311                 }
1312             }
1313         }
1314     }
1315
1316     DevelopmentSettingsObserver mDevelopmentSettingsObserver;
1317
1318     private final class DevelopmentSettingsObserver extends ContentObserver {
1319         private final Uri mUri = Settings.Global
1320                 .getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
1321
1322         private final ComponentName mBugreportStorageProvider = new ComponentName(
1323                 "com.android.shell", "com.android.shell.BugreportStorageProvider");
1324
1325         public DevelopmentSettingsObserver() {
1326             super(mHandler);
1327             mContext.getContentResolver().registerContentObserver(mUri, false, this,
1328                     UserHandle.USER_ALL);
1329             // Always kick once to ensure that we match current state
1330             onChange();
1331         }
1332
1333         @Override
1334         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1335             if (mUri.equals(uri)) {
1336                 onChange();
1337             }
1338         }
1339
1340         public void onChange() {
1341             final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
1342                     Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, Build.IS_ENG ? 1 : 0) != 0;
1343             mContext.getPackageManager().setComponentEnabledSetting(mBugreportStorageProvider,
1344                     enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1345                             : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
1346                     0);
1347         }
1348     }
1349
1350     /**
1351      * Thread-local storage used to carry caller permissions over through
1352      * indirect content-provider access.
1353      */
1354     private class Identity {
1355         public final IBinder token;
1356         public final int pid;
1357         public final int uid;
1358
1359         Identity(IBinder _token, int _pid, int _uid) {
1360             token = _token;
1361             pid = _pid;
1362             uid = _uid;
1363         }
1364     }
1365
1366     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1367
1368     /**
1369      * All information we have collected about the runtime performance of
1370      * any user id that can impact battery performance.
1371      */
1372     final BatteryStatsService mBatteryStatsService;
1373
1374     /**
1375      * Information about component usage
1376      */
1377     UsageStatsManagerInternal mUsageStatsService;
1378
1379     /**
1380      * Access to DeviceIdleController service.
1381      */
1382     DeviceIdleController.LocalService mLocalDeviceIdleController;
1383
1384     /**
1385      * Power-save whitelisted app-ids (not including except-idle-whitelisted ones).
1386      */
1387     int[] mDeviceIdleWhitelist = new int[0];
1388
1389     /**
1390      * Power-save whitelisted app-ids (including except-idle-whitelisted ones).
1391      */
1392     int[] mDeviceIdleExceptIdleWhitelist = new int[0];
1393
1394     /**
1395      * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1396      */
1397     int[] mDeviceIdleTempWhitelist = new int[0];
1398
1399     static final class PendingTempWhitelist {
1400         final int targetUid;
1401         final long duration;
1402         final String tag;
1403
1404         PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1405             targetUid = _targetUid;
1406             duration = _duration;
1407             tag = _tag;
1408         }
1409
1410         void writeToProto(ProtoOutputStream proto, long fieldId) {
1411             final long token = proto.start(fieldId);
1412             proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
1413             proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
1414             proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TAG, tag);
1415             proto.end(token);
1416         }
1417     }
1418
1419     final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1420
1421     /**
1422      * Information about and control over application operations
1423      */
1424     final AppOpsService mAppOpsService;
1425
1426     /** Current sequencing integer of the configuration, for skipping old configurations. */
1427     private int mConfigurationSeq;
1428
1429     /**
1430      * Temp object used when global and/or display override configuration is updated. It is also
1431      * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1432      * anyone...
1433      */
1434     private Configuration mTempConfig = new Configuration();
1435
1436     private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1437             new UpdateConfigurationResult();
1438     private static final class UpdateConfigurationResult {
1439         // Configuration changes that were updated.
1440         int changes;
1441         // If the activity was relaunched to match the new configuration.
1442         boolean activityRelaunched;
1443
1444         void reset() {
1445             changes = 0;
1446             activityRelaunched = false;
1447         }
1448     }
1449
1450     boolean mSuppressResizeConfigChanges;
1451
1452     /**
1453      * Hardware-reported OpenGLES version.
1454      */
1455     final int GL_ES_VERSION;
1456
1457     /**
1458      * List of initialization arguments to pass to all processes when binding applications to them.
1459      * For example, references to the commonly used services.
1460      */
1461     ArrayMap<String, IBinder> mAppBindArgs;
1462     ArrayMap<String, IBinder> mIsolatedAppBindArgs;
1463
1464     /**
1465      * Temporary to avoid allocations.  Protected by main lock.
1466      */
1467     final StringBuilder mStringBuilder = new StringBuilder(256);
1468
1469     /**
1470      * Used to control how we initialize the service.
1471      */
1472     ComponentName mTopComponent;
1473     String mTopAction = Intent.ACTION_MAIN;
1474     String mTopData;
1475
1476     volatile boolean mProcessesReady = false;
1477     volatile boolean mSystemReady = false;
1478     volatile boolean mOnBattery = false;
1479     volatile int mFactoryTest;
1480
1481     @GuardedBy("this") boolean mBooting = false;
1482     @GuardedBy("this") boolean mCallFinishBooting = false;
1483     @GuardedBy("this") boolean mBootAnimationComplete = false;
1484     @GuardedBy("this") boolean mLaunchWarningShown = false;
1485     private @GuardedBy("this") boolean mCheckedForSetup = false;
1486
1487     final Context mContext;
1488
1489     /**
1490      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1491      * change at runtime. Use mContext for non-UI purposes.
1492      */
1493     final Context mUiContext;
1494
1495     /**
1496      * The time at which we will allow normal application switches again,
1497      * after a call to {@link #stopAppSwitches()}.
1498      */
1499     long mAppSwitchesAllowedTime;
1500
1501     /**
1502      * This is set to true after the first switch after mAppSwitchesAllowedTime
1503      * is set; any switches after that will clear the time.
1504      */
1505     boolean mDidAppSwitch;
1506
1507     /**
1508      * Last time (in uptime) at which we checked for power usage.
1509      */
1510     long mLastPowerCheckUptime;
1511
1512     /**
1513      * Set while we are wanting to sleep, to prevent any
1514      * activities from being started/resumed.
1515      *
1516      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1517      *
1518      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1519      * while in the sleep state until there is a pending transition out of sleep, in which case
1520      * mSleeping is set to false, and remains false while awake.
1521      *
1522      * Whether mSleeping can quickly toggled between true/false without the device actually
1523      * display changing states is undefined.
1524      */
1525     private boolean mSleeping = false;
1526
1527     /**
1528      * The process state used for processes that are running the top activities.
1529      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1530      */
1531     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1532
1533     /**
1534      * Set while we are running a voice interaction.  This overrides
1535      * sleeping while it is active.
1536      */
1537     IVoiceInteractionSession mRunningVoice;
1538
1539     /**
1540      * For some direct access we need to power manager.
1541      */
1542     PowerManagerInternal mLocalPowerManager;
1543
1544     /**
1545      * We want to hold a wake lock while running a voice interaction session, since
1546      * this may happen with the screen off and we need to keep the CPU running to
1547      * be able to continue to interact with the user.
1548      */
1549     PowerManager.WakeLock mVoiceWakeLock;
1550
1551     /**
1552      * State of external calls telling us if the device is awake or asleep.
1553      */
1554     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1555
1556     /**
1557      * State of external calls telling us if the device is awake or asleep.
1558      */
1559     private boolean mKeyguardShown = false;
1560
1561     /**
1562      * Set if we are shutting down the system, similar to sleeping.
1563      */
1564     boolean mShuttingDown = false;
1565
1566     /**
1567      * Current sequence id for oom_adj computation traversal.
1568      */
1569     int mAdjSeq = 0;
1570
1571     /**
1572      * Current sequence id for process LRU updating.
1573      */
1574     int mLruSeq = 0;
1575
1576     /**
1577      * Keep track of the non-cached/empty process we last found, to help
1578      * determine how to distribute cached/empty processes next time.
1579      */
1580     int mNumNonCachedProcs = 0;
1581
1582     /**
1583      * Keep track of the number of cached hidden procs, to balance oom adj
1584      * distribution between those and empty procs.
1585      */
1586     int mNumCachedHiddenProcs = 0;
1587
1588     /**
1589      * Keep track of the number of service processes we last found, to
1590      * determine on the next iteration which should be B services.
1591      */
1592     int mNumServiceProcs = 0;
1593     int mNewNumAServiceProcs = 0;
1594     int mNewNumServiceProcs = 0;
1595
1596     /**
1597      * Allow the current computed overall memory level of the system to go down?
1598      * This is set to false when we are killing processes for reasons other than
1599      * memory management, so that the now smaller process list will not be taken as
1600      * an indication that memory is tighter.
1601      */
1602     boolean mAllowLowerMemLevel = false;
1603
1604     /**
1605      * The last computed memory level, for holding when we are in a state that
1606      * processes are going away for other reasons.
1607      */
1608     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1609
1610     /**
1611      * The last total number of process we have, to determine if changes actually look
1612      * like a shrinking number of process due to lower RAM.
1613      */
1614     int mLastNumProcesses;
1615
1616     /**
1617      * The uptime of the last time we performed idle maintenance.
1618      */
1619     long mLastIdleTime = SystemClock.uptimeMillis();
1620
1621     /**
1622      * Total time spent with RAM that has been added in the past since the last idle time.
1623      */
1624     long mLowRamTimeSinceLastIdle = 0;
1625
1626     /**
1627      * If RAM is currently low, when that horrible situation started.
1628      */
1629     long mLowRamStartTime = 0;
1630
1631     /**
1632      * For reporting to battery stats the current top application.
1633      */
1634     private String mCurResumedPackage = null;
1635     private int mCurResumedUid = -1;
1636
1637     /**
1638      * For reporting to battery stats the apps currently running foreground
1639      * service.  The ProcessMap is package/uid tuples; each of these contain
1640      * an array of the currently foreground processes.
1641      */
1642     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1643             = new ProcessMap<ArrayList<ProcessRecord>>();
1644
1645     /**
1646      * Set if the systemServer made a call to enterSafeMode.
1647      */
1648     boolean mSafeMode;
1649
1650     /**
1651      * If true, we are running under a test environment so will sample PSS from processes
1652      * much more rapidly to try to collect better data when the tests are rapidly
1653      * running through apps.
1654      */
1655     boolean mTestPssMode = false;
1656
1657     String mDebugApp = null;
1658     boolean mWaitForDebugger = false;
1659     boolean mDebugTransient = false;
1660     String mOrigDebugApp = null;
1661     boolean mOrigWaitForDebugger = false;
1662     boolean mAlwaysFinishActivities = false;
1663     boolean mForceResizableActivities;
1664     /**
1665      * Flag that indicates if multi-window is enabled.
1666      *
1667      * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1668      * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1669      * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1670      * At least one of the forms of multi-window must be enabled in order for this flag to be
1671      * initialized to 'true'.
1672      *
1673      * @see #mSupportsSplitScreenMultiWindow
1674      * @see #mSupportsFreeformWindowManagement
1675      * @see #mSupportsPictureInPicture
1676      * @see #mSupportsMultiDisplay
1677      */
1678     boolean mSupportsMultiWindow;
1679     boolean mSupportsSplitScreenMultiWindow;
1680     boolean mSupportsFreeformWindowManagement;
1681     boolean mSupportsPictureInPicture;
1682     boolean mSupportsMultiDisplay;
1683     boolean mSupportsLeanbackOnly;
1684     IActivityController mController = null;
1685     boolean mControllerIsAMonkey = false;
1686     String mProfileApp = null;
1687     ProcessRecord mProfileProc = null;
1688     ProfilerInfo mProfilerInfo = null;
1689
1690     /**
1691      * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
1692      * is not null, this map is checked and the mapped agent installed during bind-time. Note:
1693      * A non-null agent in mProfileInfo overrides this.
1694      */
1695     private @Nullable Map<String, String> mAppAgentMap = null;
1696
1697     int mProfileType = 0;
1698     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1699     String mMemWatchDumpProcName;
1700     String mMemWatchDumpFile;
1701     int mMemWatchDumpPid;
1702     int mMemWatchDumpUid;
1703     String mTrackAllocationApp = null;
1704     String mNativeDebuggingApp = null;
1705
1706     final long[] mTmpLong = new long[3];
1707
1708     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1709
1710     /**
1711      * A global counter for generating sequence numbers.
1712      * This value will be used when incrementing sequence numbers in individual uidRecords.
1713      *
1714      * Having a global counter ensures that seq numbers are monotonically increasing for a
1715      * particular uid even when the uidRecord is re-created.
1716      */
1717     @GuardedBy("this")
1718     @VisibleForTesting
1719     long mProcStateSeqCounter = 0;
1720
1721     /**
1722      * A global counter for generating sequence numbers to uniquely identify pending process starts.
1723      */
1724     @GuardedBy("this")
1725     private long mProcStartSeqCounter = 0;
1726
1727     /**
1728      * Contains {@link ProcessRecord} objects for pending process starts.
1729      *
1730      * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1731      */
1732     @GuardedBy("this")
1733     private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1734
1735     private final Injector mInjector;
1736
1737     static final class ProcessChangeItem {
1738         static final int CHANGE_ACTIVITIES = 1<<0;
1739         int changes;
1740         int uid;
1741         int pid;
1742         int processState;
1743         boolean foregroundActivities;
1744     }
1745
1746     static final class UidObserverRegistration {
1747         final int uid;
1748         final String pkg;
1749         final int which;
1750         final int cutpoint;
1751
1752         /**
1753          * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
1754          * We show it in dumpsys.
1755          */
1756         int mSlowDispatchCount;
1757
1758         /** Max time it took for each dispatch. */
1759         int mMaxDispatchTime;
1760
1761         final SparseIntArray lastProcStates;
1762
1763         // Please keep the enum lists in sync
1764         private static int[] ORIG_ENUMS = new int[]{
1765                 ActivityManager.UID_OBSERVER_IDLE,
1766                 ActivityManager.UID_OBSERVER_ACTIVE,
1767                 ActivityManager.UID_OBSERVER_GONE,
1768                 ActivityManager.UID_OBSERVER_PROCSTATE,
1769         };
1770         private static int[] PROTO_ENUMS = new int[]{
1771                 ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
1772                 ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
1773                 ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
1774                 ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
1775         };
1776
1777         UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1778             uid = _uid;
1779             pkg = _pkg;
1780             which = _which;
1781             cutpoint = _cutpoint;
1782             if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1783                 lastProcStates = new SparseIntArray();
1784             } else {
1785                 lastProcStates = null;
1786             }
1787         }
1788
1789         void writeToProto(ProtoOutputStream proto, long fieldId) {
1790             final long token = proto.start(fieldId);
1791             proto.write(UidObserverRegistrationProto.UID, uid);
1792             proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
1793             ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
1794                     which, ORIG_ENUMS, PROTO_ENUMS);
1795             proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
1796             if (lastProcStates != null) {
1797                 final int NI = lastProcStates.size();
1798                 for (int i=0; i<NI; i++) {
1799                     final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
1800                     proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
1801                     proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
1802                     proto.end(pToken);
1803                 }
1804             }
1805             proto.end(token);
1806         }
1807     }
1808
1809     final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1810
1811     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1812     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1813
1814     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1815     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1816
1817     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1818     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1819
1820     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1821     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1822
1823     OomAdjObserver mCurOomAdjObserver;
1824     int mCurOomAdjUid;
1825
1826     interface OomAdjObserver {
1827         void onOomAdjMessage(String msg);
1828     }
1829
1830     /**
1831      * Runtime CPU use collection thread.  This object's lock is used to
1832      * perform synchronization with the thread (notifying it to run).
1833      */
1834     final Thread mProcessCpuThread;
1835
1836     /**
1837      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1838      * Must acquire this object's lock when accessing it.
1839      * NOTE: this lock will be held while doing long operations (trawling
1840      * through all processes in /proc), so it should never be acquired by
1841      * any critical paths such as when holding the main activity manager lock.
1842      */
1843     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1844             MONITOR_THREAD_CPU_USAGE);
1845     final AtomicLong mLastCpuTime = new AtomicLong(0);
1846     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1847     final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1848
1849     long mLastWriteTime = 0;
1850
1851     /**
1852      * Used to retain an update lock when the foreground activity is in
1853      * immersive mode.
1854      */
1855     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1856
1857     /**
1858      * Set to true after the system has finished booting.
1859      */
1860     boolean mBooted = false;
1861
1862     /**
1863      * Current boot phase.
1864      */
1865     int mBootPhase;
1866
1867     WindowManagerService mWindowManager;
1868     final ActivityThread mSystemThread;
1869
1870     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1871         final ProcessRecord mApp;
1872         final int mPid;
1873         final IApplicationThread mAppThread;
1874
1875         AppDeathRecipient(ProcessRecord app, int pid,
1876                 IApplicationThread thread) {
1877             if (DEBUG_ALL) Slog.v(
1878                 TAG, "New death recipient " + this
1879                 + " for thread " + thread.asBinder());
1880             mApp = app;
1881             mPid = pid;
1882             mAppThread = thread;
1883         }
1884
1885         @Override
1886         public void binderDied() {
1887             if (DEBUG_ALL) Slog.v(
1888                 TAG, "Death received in " + this
1889                 + " for thread " + mAppThread.asBinder());
1890             synchronized(ActivityManagerService.this) {
1891                 appDiedLocked(mApp, mPid, mAppThread, true);
1892             }
1893         }
1894     }
1895
1896     static final int SHOW_ERROR_UI_MSG = 1;
1897     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1898     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1899     static final int UPDATE_CONFIGURATION_MSG = 4;
1900     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1901     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1902     static final int SERVICE_TIMEOUT_MSG = 12;
1903     static final int UPDATE_TIME_ZONE = 13;
1904     static final int SHOW_UID_ERROR_UI_MSG = 14;
1905     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1906     static final int PROC_START_TIMEOUT_MSG = 20;
1907     static final int KILL_APPLICATION_MSG = 22;
1908     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1909     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1910     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1911     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1912     static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1913     static final int CLEAR_DNS_CACHE_MSG = 28;
1914     static final int UPDATE_HTTP_PROXY_MSG = 29;
1915     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1916     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1917     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1918     static final int REPORT_MEM_USAGE_MSG = 33;
1919     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1920     static final int PERSIST_URI_GRANTS_MSG = 38;
1921     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1922     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1923     static final int FINISH_BOOTING_MSG = 45;
1924     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1925     static final int DISMISS_DIALOG_UI_MSG = 48;
1926     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1927     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1928     static final int DELETE_DUMPHEAP_MSG = 51;
1929     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1930     static final int REPORT_TIME_TRACKER_MSG = 54;
1931     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1932     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1933     static final int IDLE_UIDS_MSG = 58;
1934     static final int LOG_STACK_STATE = 60;
1935     static final int VR_MODE_CHANGE_MSG = 61;
1936     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1937     static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
1938     static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
1939     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1940     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1941     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1942     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1943     static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1944
1945     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1946     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1947     static final int FIRST_COMPAT_MODE_MSG = 300;
1948     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1949
1950     static final String SERVICE_RECORD_KEY = "servicerecord";
1951
1952     static ServiceThread sKillThread = null;
1953     static KillHandler sKillHandler = null;
1954
1955     CompatModeDialog mCompatModeDialog;
1956     long mLastMemUsageReportTime = 0;
1957
1958     /**
1959      * Flag whether the current user is a "monkey", i.e. whether
1960      * the UI is driven by a UI automation tool.
1961      */
1962     private boolean mUserIsMonkey;
1963
1964     /** The dimensions of the thumbnails in the Recents UI. */
1965     int mThumbnailWidth;
1966     int mThumbnailHeight;
1967     float mFullscreenThumbnailScale;
1968
1969     final ServiceThread mHandlerThread;
1970     final MainHandler mHandler;
1971     final Handler mUiHandler;
1972     final ServiceThread mProcStartHandlerThread;
1973     final Handler mProcStartHandler;
1974
1975     final ActivityManagerConstants mConstants;
1976
1977     // Encapsulates the global setting "hidden_api_blacklist_exemptions"
1978     final HiddenApiSettings mHiddenApiBlacklist;
1979
1980     PackageManagerInternal mPackageManagerInt;
1981
1982     // VoiceInteraction session ID that changes for each new request except when
1983     // being called for multiwindow assist in a single session.
1984     private int mViSessionId = 1000;
1985
1986     final boolean mPermissionReviewRequired;
1987
1988     boolean mHasHeavyWeightFeature;
1989
1990     /**
1991      * Whether to force background check on all apps (for battery saver) or not.
1992      */
1993     boolean mForceBackgroundCheck;
1994
1995     private static String sTheRealBuildSerial = Build.UNKNOWN;
1996
1997     /**
1998      * Current global configuration information. Contains general settings for the entire system,
1999      * also corresponds to the merged configuration of the default display.
2000      */
2001     Configuration getGlobalConfiguration() {
2002         return mStackSupervisor.getConfiguration();
2003     }
2004
2005     final class KillHandler extends Handler {
2006         static final int KILL_PROCESS_GROUP_MSG = 4000;
2007
2008         public KillHandler(Looper looper) {
2009             super(looper, null, true);
2010         }
2011
2012         @Override
2013         public void handleMessage(Message msg) {
2014             switch (msg.what) {
2015                 case KILL_PROCESS_GROUP_MSG:
2016                 {
2017                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2018                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
2019                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2020                 }
2021                 break;
2022
2023                 default:
2024                     super.handleMessage(msg);
2025             }
2026         }
2027     }
2028
2029     final class UiHandler extends Handler {
2030         public UiHandler() {
2031             super(com.android.server.UiThread.get().getLooper(), null, true);
2032         }
2033
2034         @Override
2035         public void handleMessage(Message msg) {
2036             switch (msg.what) {
2037             case SHOW_ERROR_UI_MSG: {
2038                 mAppErrors.handleShowAppErrorUi(msg);
2039                 ensureBootCompleted();
2040             } break;
2041             case SHOW_NOT_RESPONDING_UI_MSG: {
2042                 mAppErrors.handleShowAnrUi(msg);
2043                 ensureBootCompleted();
2044             } break;
2045             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
2046                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
2047                 synchronized (ActivityManagerService.this) {
2048                     ProcessRecord proc = (ProcessRecord) data.get("app");
2049                     if (proc == null) {
2050                         Slog.e(TAG, "App not found when showing strict mode dialog.");
2051                         break;
2052                     }
2053                     if (proc.crashDialog != null) {
2054                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
2055                         return;
2056                     }
2057                     AppErrorResult res = (AppErrorResult) data.get("result");
2058                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
2059                         Dialog d = new StrictModeViolationDialog(mUiContext,
2060                                 ActivityManagerService.this, res, proc);
2061                         d.show();
2062                         proc.crashDialog = d;
2063                     } else {
2064                         // The device is asleep, so just pretend that the user
2065                         // saw a crash dialog and hit "force quit".
2066                         res.set(0);
2067                     }
2068                 }
2069                 ensureBootCompleted();
2070             } break;
2071             case SHOW_FACTORY_ERROR_UI_MSG: {
2072                 Dialog d = new FactoryErrorDialog(
2073                         mUiContext, msg.getData().getCharSequence("msg"));
2074                 d.show();
2075                 ensureBootCompleted();
2076             } break;
2077             case WAIT_FOR_DEBUGGER_UI_MSG: {
2078                 synchronized (ActivityManagerService.this) {
2079                     ProcessRecord app = (ProcessRecord)msg.obj;
2080                     if (msg.arg1 != 0) {
2081                         if (!app.waitedForDebugger) {
2082                             Dialog d = new AppWaitingForDebuggerDialog(
2083                                     ActivityManagerService.this,
2084                                     mUiContext, app);
2085                             app.waitDialog = d;
2086                             app.waitedForDebugger = true;
2087                             d.show();
2088                         }
2089                     } else {
2090                         if (app.waitDialog != null) {
2091                             app.waitDialog.dismiss();
2092                             app.waitDialog = null;
2093                         }
2094                     }
2095                 }
2096             } break;
2097             case SHOW_UID_ERROR_UI_MSG: {
2098                 if (mShowDialogs) {
2099                     AlertDialog d = new BaseErrorDialog(mUiContext);
2100                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2101                     d.setCancelable(false);
2102                     d.setTitle(mUiContext.getText(R.string.android_system_label));
2103                     d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
2104                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2105                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2106                     d.show();
2107                 }
2108             } break;
2109             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
2110                 if (mShowDialogs) {
2111                     AlertDialog d = new BaseErrorDialog(mUiContext);
2112                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2113                     d.setCancelable(false);
2114                     d.setTitle(mUiContext.getText(R.string.android_system_label));
2115                     d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
2116                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2117                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2118                     d.show();
2119                 }
2120             } break;
2121             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
2122                 synchronized (ActivityManagerService.this) {
2123                     ActivityRecord ar = (ActivityRecord) msg.obj;
2124                     if (mCompatModeDialog != null) {
2125                         if (mCompatModeDialog.mAppInfo.packageName.equals(
2126                                 ar.info.applicationInfo.packageName)) {
2127                             return;
2128                         }
2129                         mCompatModeDialog.dismiss();
2130                         mCompatModeDialog = null;
2131                     }
2132                     if (ar != null && false) {
2133                         if (mCompatModePackages.getPackageAskCompatModeLocked(
2134                                 ar.packageName)) {
2135                             int mode = mCompatModePackages.computeCompatModeLocked(
2136                                     ar.info.applicationInfo);
2137                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
2138                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
2139                                 mCompatModeDialog = new CompatModeDialog(
2140                                         ActivityManagerService.this, mUiContext,
2141                                         ar.info.applicationInfo);
2142                                 mCompatModeDialog.show();
2143                             }
2144                         }
2145                     }
2146                 }
2147                 break;
2148             }
2149             case DISMISS_DIALOG_UI_MSG: {
2150                 final Dialog d = (Dialog) msg.obj;
2151                 d.dismiss();
2152                 break;
2153             }
2154             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
2155                 dispatchProcessesChanged();
2156                 break;
2157             }
2158             case DISPATCH_PROCESS_DIED_UI_MSG: {
2159                 final int pid = msg.arg1;
2160                 final int uid = msg.arg2;
2161                 dispatchProcessDied(pid, uid);
2162                 break;
2163             }
2164             case DISPATCH_UIDS_CHANGED_UI_MSG: {
2165                 dispatchUidsChanged();
2166             } break;
2167             case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
2168                 dispatchOomAdjObserver((String)msg.obj);
2169             } break;
2170             case PUSH_TEMP_WHITELIST_UI_MSG: {
2171                 pushTempWhitelist();
2172             } break;
2173             }
2174         }
2175     }
2176
2177     final class MainHandler extends Handler {
2178         public MainHandler(Looper looper) {
2179             super(looper, null, true);
2180         }
2181
2182         @Override
2183         public void handleMessage(Message msg) {
2184             switch (msg.what) {
2185             case UPDATE_CONFIGURATION_MSG: {
2186                 final ContentResolver resolver = mContext.getContentResolver();
2187                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
2188                         msg.arg1);
2189             } break;
2190             case GC_BACKGROUND_PROCESSES_MSG: {
2191                 synchronized (ActivityManagerService.this) {
2192                     performAppGcsIfAppropriateLocked();
2193                 }
2194             } break;
2195             case SERVICE_TIMEOUT_MSG: {
2196                 mServices.serviceTimeout((ProcessRecord)msg.obj);
2197             } break;
2198             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
2199                 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
2200             } break;
2201             case SERVICE_FOREGROUND_CRASH_MSG: {
2202                 mServices.serviceForegroundCrash(
2203                     (ProcessRecord) msg.obj, msg.getData().getCharSequence(SERVICE_RECORD_KEY));
2204             } break;
2205             case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
2206                 RemoteCallbackList<IResultReceiver> callbacks
2207                         = (RemoteCallbackList<IResultReceiver>)msg.obj;
2208                 int N = callbacks.beginBroadcast();
2209                 for (int i = 0; i < N; i++) {
2210                     try {
2211                         callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2212                     } catch (RemoteException e) {
2213                     }
2214                 }
2215                 callbacks.finishBroadcast();
2216                 // We have to clean up the RemoteCallbackList here, because otherwise it will
2217                 // needlessly hold the enclosed callbacks until the remote process dies.
2218                 callbacks.kill();
2219             } break;
2220             case UPDATE_TIME_ZONE: {
2221                 synchronized (ActivityManagerService.this) {
2222                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2223                         ProcessRecord r = mLruProcesses.get(i);
2224                         if (r.thread != null) {
2225                             try {
2226                                 r.thread.updateTimeZone();
2227                             } catch (RemoteException ex) {
2228                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2229                             }
2230                         }
2231                     }
2232                 }
2233             } break;
2234             case CLEAR_DNS_CACHE_MSG: {
2235                 synchronized (ActivityManagerService.this) {
2236                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2237                         ProcessRecord r = mLruProcesses.get(i);
2238                         if (r.thread != null) {
2239                             try {
2240                                 r.thread.clearDnsCache();
2241                             } catch (RemoteException ex) {
2242                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2243                             }
2244                         }
2245                     }
2246                 }
2247             } break;
2248             case UPDATE_HTTP_PROXY_MSG: {
2249                 ProxyInfo proxy = (ProxyInfo)msg.obj;
2250                 String host = "";
2251                 String port = "";
2252                 String exclList = "";
2253                 Uri pacFileUrl = Uri.EMPTY;
2254                 if (proxy != null) {
2255                     host = proxy.getHost();
2256                     port = Integer.toString(proxy.getPort());
2257                     exclList = proxy.getExclusionListAsString();
2258                     pacFileUrl = proxy.getPacFileUrl();
2259                 }
2260                 synchronized (ActivityManagerService.this) {
2261                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2262                         ProcessRecord r = mLruProcesses.get(i);
2263                         // Don't dispatch to isolated processes as they can't access
2264                         // ConnectivityManager and don't have network privileges anyway.
2265                         if (r.thread != null && !r.isolated) {
2266                             try {
2267                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2268                             } catch (RemoteException ex) {
2269                                 Slog.w(TAG, "Failed to update http proxy for: " +
2270                                         r.info.processName);
2271                             }
2272                         }
2273                     }
2274                 }
2275             } break;
2276             case PROC_START_TIMEOUT_MSG: {
2277                 ProcessRecord app = (ProcessRecord)msg.obj;
2278                 synchronized (ActivityManagerService.this) {
2279                     processStartTimedOutLocked(app);
2280                 }
2281             } break;
2282             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2283                 ProcessRecord app = (ProcessRecord)msg.obj;
2284                 synchronized (ActivityManagerService.this) {
2285                     processContentProviderPublishTimedOutLocked(app);
2286                 }
2287             } break;
2288             case KILL_APPLICATION_MSG: {
2289                 synchronized (ActivityManagerService.this) {
2290                     final int appId = msg.arg1;
2291                     final int userId = msg.arg2;
2292                     Bundle bundle = (Bundle)msg.obj;
2293                     String pkg = bundle.getString("pkg");
2294                     String reason = bundle.getString("reason");
2295                     forceStopPackageLocked(pkg, appId, false, false, true, false,
2296                             false, userId, reason);
2297                 }
2298             } break;
2299             case FINALIZE_PENDING_INTENT_MSG: {
2300                 ((PendingIntentRecord)msg.obj).completeFinalize();
2301             } break;
2302             case POST_HEAVY_NOTIFICATION_MSG: {
2303                 INotificationManager inm = NotificationManager.getService();
2304                 if (inm == null) {
2305                     return;
2306                 }
2307
2308                 ActivityRecord root = (ActivityRecord)msg.obj;
2309                 ProcessRecord process = root.app;
2310                 if (process == null) {
2311                     return;
2312                 }
2313
2314                 try {
2315                     Context context = mContext.createPackageContext(process.info.packageName, 0);
2316                     String text = mContext.getString(R.string.heavy_weight_notification,
2317                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
2318                     Notification notification =
2319                             new Notification.Builder(context,
2320                                     SystemNotificationChannels.HEAVY_WEIGHT_APP)
2321                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2322                             .setWhen(0)
2323                             .setOngoing(true)
2324                             .setTicker(text)
2325                             .setColor(mContext.getColor(
2326                                     com.android.internal.R.color.system_notification_accent_color))
2327                             .setContentTitle(text)
2328                             .setContentText(
2329                                     mContext.getText(R.string.heavy_weight_notification_detail))
2330                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2331                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2332                                     new UserHandle(root.userId)))
2333                             .build();
2334                     try {
2335                         inm.enqueueNotificationWithTag("android", "android", null,
2336                                 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2337                                 notification, root.userId);
2338                     } catch (RuntimeException e) {
2339                         Slog.w(ActivityManagerService.TAG,
2340                                 "Error showing notification for heavy-weight app", e);
2341                     } catch (RemoteException e) {
2342                     }
2343                 } catch (NameNotFoundException e) {
2344                     Slog.w(TAG, "Unable to create context for heavy notification", e);
2345                 }
2346             } break;
2347             case CANCEL_HEAVY_NOTIFICATION_MSG: {
2348                 INotificationManager inm = NotificationManager.getService();
2349                 if (inm == null) {
2350                     return;
2351                 }
2352                 try {
2353                     inm.cancelNotificationWithTag("android", null,
2354                             SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2355                 } catch (RuntimeException e) {
2356                     Slog.w(ActivityManagerService.TAG,
2357                             "Error canceling notification for service", e);
2358                 } catch (RemoteException e) {
2359                 }
2360             } break;
2361             case CHECK_EXCESSIVE_POWER_USE_MSG: {
2362                 synchronized (ActivityManagerService.this) {
2363                     checkExcessivePowerUsageLocked();
2364                     removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2365                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2366                     sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2367                 }
2368             } break;
2369             case REPORT_MEM_USAGE_MSG: {
2370                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2371                 Thread thread = new Thread() {
2372                     @Override public void run() {
2373                         reportMemUsage(memInfos);
2374                     }
2375                 };
2376                 thread.start();
2377                 break;
2378             }
2379             case IMMERSIVE_MODE_LOCK_MSG: {
2380                 final boolean nextState = (msg.arg1 != 0);
2381                 if (mUpdateLock.isHeld() != nextState) {
2382                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2383                             "Applying new update lock state '" + nextState
2384                             + "' for " + (ActivityRecord)msg.obj);
2385                     if (nextState) {
2386                         mUpdateLock.acquire();
2387                     } else {
2388                         mUpdateLock.release();
2389                     }
2390                 }
2391                 break;
2392             }
2393             case PERSIST_URI_GRANTS_MSG: {
2394                 writeGrantedUriPermissions();
2395                 break;
2396             }
2397             case UPDATE_TIME_PREFERENCE_MSG: {
2398                 // The user's time format preference might have changed.
2399                 // For convenience we re-use the Intent extra values.
2400                 synchronized (ActivityManagerService.this) {
2401                     for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2402                         ProcessRecord r = mLruProcesses.get(i);
2403                         if (r.thread != null) {
2404                             try {
2405                                 r.thread.updateTimePrefs(msg.arg1);
2406                             } catch (RemoteException ex) {
2407                                 Slog.w(TAG, "Failed to update preferences for: "
2408                                         + r.info.processName);
2409                             }
2410                         }
2411                     }
2412                 }
2413                 break;
2414             }
2415             case ENTER_ANIMATION_COMPLETE_MSG: {
2416                 synchronized (ActivityManagerService.this) {
2417                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2418                     if (r != null && r.app != null && r.app.thread != null) {
2419                         try {
2420                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2421                         } catch (RemoteException e) {
2422                         }
2423                     }
2424                 }
2425                 break;
2426             }
2427             case FINISH_BOOTING_MSG: {
2428                 if (msg.arg1 != 0) {
2429                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2430                     finishBooting();
2431                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2432                 }
2433                 if (msg.arg2 != 0) {
2434                     enableScreenAfterBoot();
2435                 }
2436                 break;
2437             }
2438             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2439                 try {
2440                     Locale l = (Locale) msg.obj;
2441                     IBinder service = ServiceManager.getService("mount");
2442                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2443                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2444                     storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2445                 } catch (RemoteException e) {
2446                     Log.e(TAG, "Error storing locale for decryption UI", e);
2447                 }
2448                 break;
2449             }
2450             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2451                 final int uid = msg.arg1;
2452                 final byte[] firstPacket = (byte[]) msg.obj;
2453
2454                 synchronized (mPidsSelfLocked) {
2455                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2456                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2457                         if (p.uid == uid) {
2458                             try {
2459                                 p.thread.notifyCleartextNetwork(firstPacket);
2460                             } catch (RemoteException ignored) {
2461                             }
2462                         }
2463                     }
2464                 }
2465                 break;
2466             }
2467             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2468                 final String procName;
2469                 final int uid;
2470                 final long memLimit;
2471                 final String reportPackage;
2472                 synchronized (ActivityManagerService.this) {
2473                     procName = mMemWatchDumpProcName;
2474                     uid = mMemWatchDumpUid;
2475                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2476                     if (val == null) {
2477                         val = mMemWatchProcesses.get(procName, 0);
2478                     }
2479                     if (val != null) {
2480                         memLimit = val.first;
2481                         reportPackage = val.second;
2482                     } else {
2483                         memLimit = 0;
2484                         reportPackage = null;
2485                     }
2486                 }
2487                 if (procName == null) {
2488                     return;
2489                 }
2490
2491                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2492                         "Showing dump heap notification from " + procName + "/" + uid);
2493
2494                 INotificationManager inm = NotificationManager.getService();
2495                 if (inm == null) {
2496                     return;
2497                 }
2498
2499                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2500
2501
2502                 Intent deleteIntent = new Intent();
2503                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2504                 Intent intent = new Intent();
2505                 intent.setClassName("android", DumpHeapActivity.class.getName());
2506                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2507                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2508                 if (reportPackage != null) {
2509                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2510                 }
2511                 int userId = UserHandle.getUserId(uid);
2512                 Notification notification =
2513                         new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2514                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2515                         .setWhen(0)
2516                         .setOngoing(true)
2517                         .setAutoCancel(true)
2518                         .setTicker(text)
2519                         .setColor(mContext.getColor(
2520                                 com.android.internal.R.color.system_notification_accent_color))
2521                         .setContentTitle(text)
2522                         .setContentText(
2523                                 mContext.getText(R.string.dump_heap_notification_detail))
2524                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2525                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2526                                 new UserHandle(userId)))
2527                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2528                                 deleteIntent, 0, UserHandle.SYSTEM))
2529                         .build();
2530
2531                 try {
2532                     inm.enqueueNotificationWithTag("android", "android", null,
2533                             SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2534                             notification, userId);
2535                 } catch (RuntimeException e) {
2536                     Slog.w(ActivityManagerService.TAG,
2537                             "Error showing notification for dump heap", e);
2538                 } catch (RemoteException e) {
2539                 }
2540             } break;
2541             case DELETE_DUMPHEAP_MSG: {
2542                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2543                         null, DumpHeapActivity.JAVA_URI,
2544                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2545                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2546                         UserHandle.myUserId());
2547                 synchronized (ActivityManagerService.this) {
2548                     mMemWatchDumpFile = null;
2549                     mMemWatchDumpProcName = null;
2550                     mMemWatchDumpPid = -1;
2551                     mMemWatchDumpUid = -1;
2552                 }
2553             } break;
2554             case REPORT_TIME_TRACKER_MSG: {
2555                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2556                 tracker.deliverResult(mContext);
2557             } break;
2558             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2559                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2560                 try {
2561                     connection.shutdown();
2562                 } catch (RemoteException e) {
2563                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2564                 }
2565                 // Only a UiAutomation can set this flag and now that
2566                 // it is finished we make sure it is reset to its default.
2567                 mUserIsMonkey = false;
2568             } break;
2569             case IDLE_UIDS_MSG: {
2570                 idleUids();
2571             } break;
2572             case VR_MODE_CHANGE_MSG: {
2573                 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2574                     return;
2575                 }
2576                 synchronized (ActivityManagerService.this) {
2577                     final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2578                     mWindowManager.disableNonVrUi(disableNonVrUi);
2579                     if (disableNonVrUi) {
2580                         // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2581                         // then remove the pinned stack.
2582                         mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2583                     }
2584                 }
2585             } break;
2586             case DISPATCH_SCREEN_AWAKE_MSG: {
2587                 final boolean isAwake = msg.arg1 != 0;
2588                 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2589                     mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2590                 }
2591             } break;
2592             case DISPATCH_SCREEN_KEYGUARD_MSG: {
2593                 final boolean isShowing = msg.arg1 != 0;
2594                 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2595                     mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2596                 }
2597             } break;
2598             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2599                 synchronized (ActivityManagerService.this) {
2600                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2601                         ProcessRecord r = mLruProcesses.get(i);
2602                         if (r.thread != null) {
2603                             try {
2604                                 r.thread.handleTrustStorageUpdate();
2605                             } catch (RemoteException ex) {
2606                                 Slog.w(TAG, "Failed to handle trust storage update for: " +
2607                                         r.info.processName);
2608                             }
2609                         }
2610                     }
2611                 }
2612             } break;
2613             }
2614         }
2615     };
2616
2617     static final int COLLECT_PSS_BG_MSG = 1;
2618
2619     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2620         @Override
2621         public void handleMessage(Message msg) {
2622             switch (msg.what) {
2623             case COLLECT_PSS_BG_MSG: {
2624                 long start = SystemClock.uptimeMillis();
2625                 MemInfoReader memInfo = null;
2626                 synchronized (ActivityManagerService.this) {
2627                     if (mFullPssPending) {
2628                         mFullPssPending = false;
2629                         memInfo = new MemInfoReader();
2630                     }
2631                 }
2632                 if (memInfo != null) {
2633                     updateCpuStatsNow();
2634                     long nativeTotalPss = 0;
2635                     final List<ProcessCpuTracker.Stats> stats;
2636                     synchronized (mProcessCpuTracker) {
2637                         stats = mProcessCpuTracker.getStats( (st)-> {
2638                             return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2639                         });
2640                     }
2641                     final int N = stats.size();
2642                     for (int j = 0; j < N; j++) {
2643                         synchronized (mPidsSelfLocked) {
2644                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2645                                 // This is one of our own processes; skip it.
2646                                 continue;
2647                             }
2648                         }
2649                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2650                     }
2651                     memInfo.readMemInfo();
2652                     synchronized (ActivityManagerService.this) {
2653                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2654                                 + (SystemClock.uptimeMillis()-start) + "ms");
2655                         final long cachedKb = memInfo.getCachedSizeKb();
2656                         final long freeKb = memInfo.getFreeSizeKb();
2657                         final long zramKb = memInfo.getZramTotalSizeKb();
2658                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2659                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2660                                 kernelKb*1024, nativeTotalPss*1024);
2661                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2662                                 nativeTotalPss);
2663                     }
2664                 }
2665
2666                 int num = 0;
2667                 long[] tmp = new long[3];
2668                 do {
2669                     ProcessRecord proc;
2670                     int procState;
2671                     int statType;
2672                     int pid;
2673                     long lastPssTime;
2674                     synchronized (ActivityManagerService.this) {
2675                         if (mPendingPssProcesses.size() <= 0) {
2676                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2677                                     "Collected pss of " + num + " processes in "
2678                                     + (SystemClock.uptimeMillis() - start) + "ms");
2679                             mPendingPssProcesses.clear();
2680                             return;
2681                         }
2682                         proc = mPendingPssProcesses.remove(0);
2683                         procState = proc.pssProcState;
2684                         statType = proc.pssStatType;
2685                         lastPssTime = proc.lastPssTime;
2686                         long now = SystemClock.uptimeMillis();
2687                         if (proc.thread != null && procState == proc.setProcState
2688                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2689                                         < now) {
2690                             pid = proc.pid;
2691                         } else {
2692                             ProcessList.abortNextPssTime(proc.procStateMemTracker);
2693                             if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2694                                     ": still need " +
2695                                     (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE-now) +
2696                                     "ms until safe");
2697                             proc = null;
2698                             pid = 0;
2699                         }
2700                     }
2701                     if (proc != null) {
2702                         long startTime = SystemClock.currentThreadTimeMillis();
2703                         long pss = Debug.getPss(pid, tmp, null);
2704                         long endTime = SystemClock.currentThreadTimeMillis();
2705                         synchronized (ActivityManagerService.this) {
2706                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2707                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2708                                 num++;
2709                                 ProcessList.commitNextPssTime(proc.procStateMemTracker);
2710                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2],
2711                                         statType, endTime-startTime, SystemClock.uptimeMillis());
2712                             } else {
2713                                 ProcessList.abortNextPssTime(proc.procStateMemTracker);
2714                                 if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2715                                         ": " + (proc.thread == null ? "NO_THREAD " : "") +
2716                                         (proc.pid != pid ? "PID_CHANGED " : "") +
2717                                         " initState=" + procState + " curState=" +
2718                                         proc.setProcState + " " +
2719                                         (proc.lastPssTime != lastPssTime ? "TIME_CHANGED" : ""));
2720                             }
2721                         }
2722                     }
2723                 } while (true);
2724             }
2725             }
2726         }
2727     };
2728
2729     public void setSystemProcess() {
2730         try {
2731             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
2732                     DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
2733             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2734             ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
2735                     DUMP_FLAG_PRIORITY_HIGH);
2736             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2737             ServiceManager.addService("dbinfo", new DbBinder(this));
2738             if (MONITOR_CPU_USAGE) {
2739                 ServiceManager.addService("cpuinfo", new CpuBinder(this),
2740                         /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
2741             }
2742             ServiceManager.addService("permission", new PermissionController(this));
2743             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2744
2745             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2746                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2747             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2748
2749             synchronized (this) {
2750                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2751                 app.persistent = true;
2752                 app.pid = MY_PID;
2753                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2754                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2755                 synchronized (mPidsSelfLocked) {
2756                     mPidsSelfLocked.put(app.pid, app);
2757                 }
2758                 updateLruProcessLocked(app, false, null);
2759                 updateOomAdjLocked();
2760             }
2761         } catch (PackageManager.NameNotFoundException e) {
2762             throw new RuntimeException(
2763                     "Unable to find android system package", e);
2764         }
2765
2766         // Start watching app ops after we and the package manager are up and running.
2767         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2768                 new IAppOpsCallback.Stub() {
2769                     @Override public void opChanged(int op, int uid, String packageName) {
2770                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2771                             if (mAppOpsService.checkOperation(op, uid, packageName)
2772                                     != AppOpsManager.MODE_ALLOWED) {
2773                                 runInBackgroundDisabled(uid);
2774                             }
2775                         }
2776                     }
2777                 });
2778     }
2779
2780     public void setWindowManager(WindowManagerService wm) {
2781         synchronized (this) {
2782             mWindowManager = wm;
2783             mStackSupervisor.setWindowManager(wm);
2784             mLockTaskController.setWindowManager(wm);
2785         }
2786     }
2787
2788     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2789         mUsageStatsService = usageStatsManager;
2790     }
2791
2792     public void startObservingNativeCrashes() {
2793         final NativeCrashListener ncl = new NativeCrashListener(this);
2794         ncl.start();
2795     }
2796
2797     public IAppOpsService getAppOpsService() {
2798         return mAppOpsService;
2799     }
2800
2801     static class MemBinder extends Binder {
2802         ActivityManagerService mActivityManagerService;
2803         private final PriorityDump.PriorityDumper mPriorityDumper =
2804                 new PriorityDump.PriorityDumper() {
2805             @Override
2806             public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
2807                     boolean asProto) {
2808                 dump(fd, pw, new String[] {"-a"}, asProto);
2809             }
2810
2811             @Override
2812             public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
2813                 mActivityManagerService.dumpApplicationMemoryUsage(
2814                         fd, pw, "  ", args, false, null, asProto);
2815             }
2816         };
2817
2818         MemBinder(ActivityManagerService activityManagerService) {
2819             mActivityManagerService = activityManagerService;
2820         }
2821
2822         @Override
2823         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2824             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2825                     "meminfo", pw)) return;
2826             PriorityDump.dump(mPriorityDumper, fd, pw, args);
2827         }
2828     }
2829
2830     static class GraphicsBinder extends Binder {
2831         ActivityManagerService mActivityManagerService;
2832         GraphicsBinder(ActivityManagerService activityManagerService) {
2833             mActivityManagerService = activityManagerService;
2834         }
2835
2836         @Override
2837         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2838             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2839                     "gfxinfo", pw)) return;
2840             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2841         }
2842     }
2843
2844     static class DbBinder extends Binder {
2845         ActivityManagerService mActivityManagerService;
2846         DbBinder(ActivityManagerService activityManagerService) {
2847             mActivityManagerService = activityManagerService;
2848         }
2849
2850         @Override
2851         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2852             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2853                     "dbinfo", pw)) return;
2854             mActivityManagerService.dumpDbInfo(fd, pw, args);
2855         }
2856     }
2857
2858     static class CpuBinder extends Binder {
2859         ActivityManagerService mActivityManagerService;
2860         private final PriorityDump.PriorityDumper mPriorityDumper =
2861                 new PriorityDump.PriorityDumper() {
2862             @Override
2863             public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
2864                     boolean asProto) {
2865                 if (asProto) return;
2866                 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2867                         "cpuinfo", pw)) return;
2868                 synchronized (mActivityManagerService.mProcessCpuTracker) {
2869                     pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2870                     pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2871                             SystemClock.uptimeMillis()));
2872                 }
2873             }
2874         };
2875
2876         CpuBinder(ActivityManagerService activityManagerService) {
2877             mActivityManagerService = activityManagerService;
2878         }
2879
2880         @Override
2881         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2882             PriorityDump.dump(mPriorityDumper, fd, pw, args);
2883         }
2884     }
2885
2886     public static final class Lifecycle extends SystemService {
2887         private final ActivityManagerService mService;
2888
2889         public Lifecycle(Context context) {
2890             super(context);
2891             mService = new ActivityManagerService(context);
2892         }
2893
2894         @Override
2895         public void onStart() {
2896             mService.start();
2897         }
2898
2899         @Override
2900         public void onBootPhase(int phase) {
2901             mService.mBootPhase = phase;
2902             if (phase == PHASE_SYSTEM_SERVICES_READY) {
2903                 mService.mBatteryStatsService.systemServicesReady();
2904                 mService.mServices.systemServicesReady();
2905             }
2906         }
2907
2908         @Override
2909         public void onCleanupUser(int userId) {
2910             mService.mBatteryStatsService.onCleanupUser(userId);
2911         }
2912
2913         public ActivityManagerService getService() {
2914             return mService;
2915         }
2916     }
2917
2918     /**
2919      * Encapsulates global settings related to hidden API enforcement behaviour, including tracking
2920      * the latest value via a content observer.
2921      */
2922     static class HiddenApiSettings extends ContentObserver {
2923
2924         private final Context mContext;
2925         private boolean mBlacklistDisabled;
2926         private String mExemptionsStr;
2927         private List<String> mExemptions = Collections.emptyList();
2928         private int mLogSampleRate = -1;
2929         @HiddenApiEnforcementPolicy private int mPolicyPreP = HIDDEN_API_ENFORCEMENT_DEFAULT;
2930         @HiddenApiEnforcementPolicy private int mPolicyP = HIDDEN_API_ENFORCEMENT_DEFAULT;
2931
2932         public HiddenApiSettings(Handler handler, Context context) {
2933             super(handler);
2934             mContext = context;
2935         }
2936
2937         public void registerObserver() {
2938             mContext.getContentResolver().registerContentObserver(
2939                     Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
2940                     false,
2941                     this);
2942             mContext.getContentResolver().registerContentObserver(
2943                     Settings.Global.getUriFor(Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE),
2944                     false,
2945                     this);
2946             mContext.getContentResolver().registerContentObserver(
2947                     Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS),
2948                     false,
2949                     this);
2950             mContext.getContentResolver().registerContentObserver(
2951                     Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_P_APPS),
2952                     false,
2953                     this);
2954             update();
2955         }
2956
2957         private void update() {
2958             String exemptions = Settings.Global.getString(mContext.getContentResolver(),
2959                     Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS);
2960             if (!TextUtils.equals(exemptions, mExemptionsStr)) {
2961                 mExemptionsStr = exemptions;
2962                 if ("*".equals(exemptions)) {
2963                     mBlacklistDisabled = true;
2964                     mExemptions = Collections.emptyList();
2965                 } else {
2966                     mBlacklistDisabled = false;
2967                     mExemptions = TextUtils.isEmpty(exemptions)
2968                             ? Collections.emptyList()
2969                             : Arrays.asList(exemptions.split(","));
2970                 }
2971                 if (!zygoteProcess.setApiBlacklistExemptions(mExemptions)) {
2972                   Slog.e(TAG, "Failed to set API blacklist exemptions!");
2973                   // leave mExemptionsStr as is, so we don't try to send the same list again.
2974                   mExemptions = Collections.emptyList();
2975                 }
2976             }
2977             int logSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
2978                     Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, -1);
2979             if (logSampleRate < 0 || logSampleRate > 0x10000) {
2980                 logSampleRate = -1;
2981             }
2982             if (logSampleRate != -1 && logSampleRate != mLogSampleRate) {
2983                 mLogSampleRate = logSampleRate;
2984                 zygoteProcess.setHiddenApiAccessLogSampleRate(mLogSampleRate);
2985             }
2986             mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS);
2987             mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS);
2988         }
2989
2990         private @HiddenApiEnforcementPolicy int getValidEnforcementPolicy(String settingsKey) {
2991             int policy = Settings.Global.getInt(mContext.getContentResolver(), settingsKey,
2992                     ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT);
2993             if (ApplicationInfo.isValidHiddenApiEnforcementPolicy(policy)) {
2994                 return policy;
2995             } else {
2996                 return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
2997             }
2998         }
2999
3000         boolean isDisabled() {
3001             return mBlacklistDisabled;
3002         }
3003
3004         @HiddenApiEnforcementPolicy int getPolicyForPrePApps() {
3005             return mPolicyPreP;
3006         }
3007
3008         @HiddenApiEnforcementPolicy int getPolicyForPApps() {
3009             return mPolicyP;
3010         }
3011
3012         public void onChange(boolean selfChange) {
3013             update();
3014         }
3015     }
3016
3017     @VisibleForTesting
3018     public ActivityManagerService(Injector injector) {
3019         mInjector = injector;
3020         mContext = mInjector.getContext();
3021         mUiContext = null;
3022         GL_ES_VERSION = 0;
3023         mActivityStartController = null;
3024         mAppErrors = null;
3025         mAppWarnings = null;
3026         mAppOpsService = mInjector.getAppOpsService(null, null);
3027         mBatteryStatsService = null;
3028         mCompatModePackages = null;
3029         mConstants = null;
3030         mGrantFile = null;
3031         mHandler = null;
3032         mHandlerThread = null;
3033         mIntentFirewall = null;
3034         mKeyguardController = null;
3035         mPermissionReviewRequired = false;
3036         mProcessCpuThread = null;
3037         mProcessStats = null;
3038         mProviderMap = null;
3039         mRecentTasks = null;
3040         mServices = null;
3041         mStackSupervisor = null;
3042         mSystemThread = null;
3043         mTaskChangeNotificationController = null;
3044         mUiHandler = injector.getUiHandler(null);
3045         mUserController = null;
3046         mVrController = null;
3047         mLockTaskController = null;
3048         mLifecycleManager = null;
3049         mProcStartHandlerThread = null;
3050         mProcStartHandler = null;
3051         mHiddenApiBlacklist = null;
3052     }
3053
3054     // Note: This method is invoked on the main thread but may need to attach various
3055     // handlers to other threads.  So take care to be explicit about the looper.
3056     public ActivityManagerService(Context systemContext) {
3057         LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
3058         mInjector = new Injector();
3059         mContext = systemContext;
3060
3061         mFactoryTest = FactoryTest.getMode();
3062         mSystemThread = ActivityThread.currentActivityThread();
3063         mUiContext = mSystemThread.getSystemUiContext();
3064
3065         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
3066
3067         mPermissionReviewRequired = mContext.getResources().getBoolean(
3068                 com.android.internal.R.bool.config_permissionReviewRequired);
3069
3070         mHandlerThread = new ServiceThread(TAG,
3071                 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
3072         mHandlerThread.start();
3073         mHandler = new MainHandler(mHandlerThread.getLooper());
3074         mUiHandler = mInjector.getUiHandler(this);
3075
3076         mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
3077                 THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
3078         mProcStartHandlerThread.start();
3079         mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
3080
3081         mConstants = new ActivityManagerConstants(this, mHandler);
3082
3083         /* static; one-time init here */
3084         if (sKillHandler == null) {
3085             sKillThread = new ServiceThread(TAG + ":kill",
3086                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
3087             sKillThread.start();
3088             sKillHandler = new KillHandler(sKillThread.getLooper());
3089         }
3090
3091         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
3092                 "foreground", BROADCAST_FG_TIMEOUT, false);
3093         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
3094                 "background", BROADCAST_BG_TIMEOUT, true);
3095         mBroadcastQueues[0] = mFgBroadcastQueue;
3096         mBroadcastQueues[1] = mBgBroadcastQueue;
3097
3098         mServices = new ActiveServices(this);
3099         mProviderMap = new ProviderMap(this);
3100         mAppErrors = new AppErrors(mUiContext, this);
3101
3102         File dataDir = Environment.getDataDirectory();
3103         File systemDir = new File(dataDir, "system");
3104         systemDir.mkdirs();
3105
3106         mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
3107
3108         // TODO: Move creation of battery stats service outside of activity manager service.
3109         mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
3110         mBatteryStatsService.getActiveStatistics().readLocked();
3111         mBatteryStatsService.scheduleWriteToDisk();
3112         mOnBattery = DEBUG_POWER ? true
3113                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
3114         mBatteryStatsService.getActiveStatistics().setCallback(this);
3115
3116         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
3117
3118         mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
3119
3120         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
3121
3122         mUserController = new UserController(this);
3123
3124         mVrController = new VrController(this);
3125
3126         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
3127             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
3128
3129         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
3130             mUseFifoUiScheduling = true;
3131         }
3132
3133         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
3134         mTempConfig.setToDefaults();
3135         mTempConfig.setLocales(LocaleList.getDefault());
3136         mConfigurationSeq = mTempConfig.seq = 1;
3137         mStackSupervisor = createStackSupervisor();
3138         mStackSupervisor.onConfigurationChanged(mTempConfig);
3139         mKeyguardController = mStackSupervisor.getKeyguardController();
3140         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
3141         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
3142         mTaskChangeNotificationController =
3143                 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
3144         mActivityStartController = new ActivityStartController(this);
3145         mRecentTasks = createRecentTasks();
3146         mStackSupervisor.setRecentTasks(mRecentTasks);
3147         mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
3148         mLifecycleManager = new ClientLifecycleManager();
3149
3150         mProcessCpuThread = new Thread("CpuTracker") {
3151             @Override
3152             public void run() {
3153                 synchronized (mProcessCpuTracker) {
3154                     mProcessCpuInitLatch.countDown();
3155                     mProcessCpuTracker.init();
3156                 }
3157                 while (true) {
3158                     try {
3159                         try {
3160                             synchronized(this) {
3161                                 final long now = SystemClock.uptimeMillis();
3162                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
3163                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
3164                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
3165                                 //        + ", write delay=" + nextWriteDelay);
3166                                 if (nextWriteDelay < nextCpuDelay) {
3167                                     nextCpuDelay = nextWriteDelay;
3168                                 }
3169                                 if (nextCpuDelay > 0) {
3170                                     mProcessCpuMutexFree.set(true);
3171                                     this.wait(nextCpuDelay);
3172                                 }
3173                             }
3174                         } catch (InterruptedException e) {
3175                         }
3176                         updateCpuStatsNow();
3177                     } catch (Exception e) {
3178                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
3179                     }
3180                 }
3181             }
3182         };
3183
3184         mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);
3185
3186         Watchdog.getInstance().addMonitor(this);
3187         Watchdog.getInstance().addThread(mHandler);
3188
3189         // bind background thread to little cores
3190         // this is expected to fail inside of framework tests because apps can't touch cpusets directly
3191         // make sure we've already adjusted system_server's internal view of itself first
3192         updateOomAdjLocked();
3193         try {
3194             Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(),
3195                     Process.THREAD_GROUP_BG_NONINTERACTIVE);
3196         } catch (Exception e) {
3197             Slog.w(TAG, "Setting background thread cpuset failed");
3198         }
3199
3200     }
3201
3202     protected ActivityStackSupervisor createStackSupervisor() {
3203         final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
3204         supervisor.initialize();
3205         return supervisor;
3206     }
3207
3208     protected RecentTasks createRecentTasks() {
3209         return new RecentTasks(this, mStackSupervisor);
3210     }
3211
3212     RecentTasks getRecentTasks() {
3213         return mRecentTasks;
3214     }
3215
3216     public void setSystemServiceManager(SystemServiceManager mgr) {
3217         mSystemServiceManager = mgr;
3218     }
3219
3220     public void setInstaller(Installer installer) {
3221         mInstaller = installer;
3222     }
3223
3224     private void start() {
3225         removeAllProcessGroups();
3226         mProcessCpuThread.start();
3227
3228         mBatteryStatsService.publish();
3229         mAppOpsService.publish(mContext);
3230         Slog.d("AppOps", "AppOpsService published");
3231         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
3232         // Wait for the synchronized block started in mProcessCpuThread,
3233         // so that any other acccess to mProcessCpuTracker from main thread
3234         // will be blocked during mProcessCpuTracker initialization.
3235         try {
3236             mProcessCpuInitLatch.await();
3237         } catch (InterruptedException e) {
3238             Slog.wtf(TAG, "Interrupted wait during start", e);
3239             Thread.currentThread().interrupt();
3240             throw new IllegalStateException("Interrupted wait during start");
3241         }
3242     }
3243
3244     void onUserStoppedLocked(int userId) {
3245         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
3246         mAllowAppSwitchUids.remove(userId);
3247     }
3248
3249     public void initPowerManagement() {
3250         mStackSupervisor.initPowerManagement();
3251         mBatteryStatsService.initPowerManagement();
3252         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
3253         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
3254         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
3255         mVoiceWakeLock.setReferenceCounted(false);
3256     }
3257
3258     private ArraySet<String> getBackgroundLaunchBroadcasts() {
3259         if (mBackgroundLaunchBroadcasts == null) {
3260             mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
3261         }
3262         return mBackgroundLaunchBroadcasts;
3263     }
3264
3265     @Override
3266     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3267             throws RemoteException {
3268         if (code == SYSPROPS_TRANSACTION) {
3269             // We need to tell all apps about the system property change.
3270             ArrayList<IBinder> procs = new ArrayList<IBinder>();
3271             synchronized(this) {
3272                 final int NP = mProcessNames.getMap().size();
3273                 for (int ip=0; ip<NP; ip++) {
3274                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3275                     final int NA = apps.size();
3276                     for (int ia=0; ia<NA; ia++) {
3277                         ProcessRecord app = apps.valueAt(ia);
3278                         if (app.thread != null) {
3279                             procs.add(app.thread.asBinder());
3280                         }
3281                     }
3282                 }
3283             }
3284
3285             int N = procs.size();
3286             for (int i=0; i<N; i++) {
3287                 Parcel data2 = Parcel.obtain();
3288                 try {
3289                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
3290                             Binder.FLAG_ONEWAY);
3291                 } catch (RemoteException e) {
3292                 }
3293                 data2.recycle();
3294             }
3295         }
3296         try {
3297             return super.onTransact(code, data, reply, flags);
3298         } catch (RuntimeException e) {
3299             // The activity manager only throws certain exceptions intentionally, so let's
3300             // log all others.
3301             if (!(e instanceof SecurityException
3302                     || e instanceof IllegalArgumentException
3303                     || e instanceof IllegalStateException)) {
3304                 Slog.wtf(TAG, "Activity Manager Crash."
3305                         + " UID:" + Binder.getCallingUid()
3306                         + " PID:" + Binder.getCallingPid()
3307                         + " TRANS:" + code, e);
3308             }
3309             throw e;
3310         }
3311     }
3312
3313     void updateCpuStats() {
3314         final long now = SystemClock.uptimeMillis();
3315         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3316             return;
3317         }
3318         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3319             synchronized (mProcessCpuThread) {
3320                 mProcessCpuThread.notify();
3321             }
3322         }
3323     }
3324
3325     void updateCpuStatsNow() {
3326         synchronized (mProcessCpuTracker) {
3327             mProcessCpuMutexFree.set(false);
3328             final long now = SystemClock.uptimeMillis();
3329             boolean haveNewCpuStats = false;
3330
3331             if (MONITOR_CPU_USAGE &&
3332                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3333                 mLastCpuTime.set(now);
3334                 mProcessCpuTracker.update();
3335                 if (mProcessCpuTracker.hasGoodLastStats()) {
3336                     haveNewCpuStats = true;
3337                     //Slog.i(TAG, mProcessCpu.printCurrentState());
3338                     //Slog.i(TAG, "Total CPU usage: "
3339                     //        + mProcessCpu.getTotalCpuPercent() + "%");
3340
3341                     // Slog the cpu usage if the property is set.
3342                     if ("true".equals(SystemProperties.get("events.cpu"))) {
3343                         int user = mProcessCpuTracker.getLastUserTime();
3344                         int system = mProcessCpuTracker.getLastSystemTime();
3345                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
3346                         int irq = mProcessCpuTracker.getLastIrqTime();
3347                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3348                         int idle = mProcessCpuTracker.getLastIdleTime();
3349
3350                         int total = user + system + iowait + irq + softIrq + idle;
3351                         if (total == 0) total = 1;
3352
3353                         EventLog.writeEvent(EventLogTags.CPU,
3354                                 ((user+system+iowait+irq+softIrq) * 100) / total,
3355                                 (user * 100) / total,
3356                                 (system * 100) / total,
3357                                 (iowait * 100) / total,
3358                                 (irq * 100) / total,
3359                                 (softIrq * 100) / total);
3360                     }
3361                 }
3362             }
3363
3364             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3365             synchronized(bstats) {
3366                 synchronized(mPidsSelfLocked) {
3367                     if (haveNewCpuStats) {
3368                         if (bstats.startAddingCpuLocked()) {
3369                             int totalUTime = 0;
3370                             int totalSTime = 0;
3371                             final int N = mProcessCpuTracker.countStats();
3372                             for (int i=0; i<N; i++) {
3373                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3374                                 if (!st.working) {
3375                                     continue;
3376                                 }
3377                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3378                                 totalUTime += st.rel_utime;
3379                                 totalSTime += st.rel_stime;
3380                                 if (pr != null) {
3381                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3382                                     if (ps == null || !ps.isActive()) {
3383                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3384                                                 pr.info.uid, pr.processName);
3385                                     }
3386                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3387                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
3388                                     if (pr.lastCpuTime == 0) {
3389                                         pr.lastCpuTime = pr.curCpuTime;
3390                                     }
3391                                 } else {
3392                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3393                                     if (ps == null || !ps.isActive()) {
3394                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
3395                                                 bstats.mapUid(st.uid), st.name);
3396                                     }
3397                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3398                                 }
3399                             }
3400                             final int userTime = mProcessCpuTracker.getLastUserTime();
3401                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
3402                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3403                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
3404                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3405                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
3406                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3407                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3408                         }
3409                     }
3410                 }
3411
3412                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3413                     mLastWriteTime = now;
3414                     mBatteryStatsService.scheduleWriteToDisk();
3415                 }
3416             }
3417         }
3418     }
3419
3420     @Override
3421     public void batteryNeedsCpuUpdate() {
3422         updateCpuStatsNow();
3423     }
3424
3425     @Override
3426     public void batteryPowerChanged(boolean onBattery) {
3427         // When plugging in, update the CPU stats first before changing
3428         // the plug state.
3429         updateCpuStatsNow();
3430         synchronized (this) {
3431             synchronized(mPidsSelfLocked) {
3432                 mOnBattery = DEBUG_POWER ? true : onBattery;
3433             }
3434         }
3435     }
3436
3437     @Override
3438     public void batteryStatsReset() {
3439         BinderCallsStatsService.reset();
3440     }
3441
3442     @Override
3443     public void batterySendBroadcast(Intent intent) {
3444         synchronized (this) {
3445             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3446                     OP_NONE, null, false, false,
3447                     -1, SYSTEM_UID, UserHandle.USER_ALL);
3448         }
3449     }
3450
3451     /**
3452      * Initialize the application bind args. These are passed to each
3453      * process when the bindApplication() IPC is sent to the process. They're
3454      * lazily setup to make sure the services are running when they're asked for.
3455      */
3456     private ArrayMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3457         // Isolated processes won't get this optimization, so that we don't
3458         // violate the rules about which services they have access to.
3459         if (isolated) {
3460             if (mIsolatedAppBindArgs == null) {
3461                 mIsolatedAppBindArgs = new ArrayMap<>(1);
3462                 addServiceToMap(mIsolatedAppBindArgs, "package");
3463             }
3464             return mIsolatedAppBindArgs;
3465         }
3466
3467         if (mAppBindArgs == null) {
3468             mAppBindArgs = new ArrayMap<>();
3469
3470             // Add common services.
3471             // IMPORTANT: Before adding services here, make sure ephemeral apps can access them too.
3472             // Enable the check in ApplicationThread.bindApplication() to make sure.
3473             addServiceToMap(mAppBindArgs, "package");
3474             addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE);
3475             addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE);
3476             addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE);
3477             addServiceToMap(mAppBindArgs, Context.NETWORKMANAGEMENT_SERVICE);
3478             addServiceToMap(mAppBindArgs, Context.CONNECTIVITY_SERVICE);
3479             addServiceToMap(mAppBindArgs, Context.ACCESSIBILITY_SERVICE);
3480             addServiceToMap(mAppBindArgs, Context.INPUT_METHOD_SERVICE);
3481             addServiceToMap(mAppBindArgs, Context.INPUT_SERVICE);
3482             addServiceToMap(mAppBindArgs, "graphicsstats");
3483             addServiceToMap(mAppBindArgs, Context.APP_OPS_SERVICE);
3484             addServiceToMap(mAppBindArgs, "content");
3485             addServiceToMap(mAppBindArgs, Context.JOB_SCHEDULER_SERVICE);
3486             addServiceToMap(mAppBindArgs, Context.NOTIFICATION_SERVICE);
3487             addServiceToMap(mAppBindArgs, Context.VIBRATOR_SERVICE);
3488             addServiceToMap(mAppBindArgs, Context.ACCOUNT_SERVICE);
3489             addServiceToMap(mAppBindArgs, Context.POWER_SERVICE);
3490             addServiceToMap(mAppBindArgs, Context.USER_SERVICE);
3491             addServiceToMap(mAppBindArgs, "mount");
3492         }
3493         return mAppBindArgs;
3494     }
3495
3496     private static void addServiceToMap(ArrayMap<String, IBinder> map, String name) {
3497         final IBinder service = ServiceManager.getService(name);
3498         if (service != null) {
3499             map.put(name, service);
3500             if (false) {
3501                 Log.i(TAG, "Adding " + name + " to the pre-loaded service cache.");
3502             }
3503         }
3504     }
3505
3506     /**
3507      * Update AMS states when an activity is resumed. This should only be called by
3508      * {@link ActivityStack#onActivityStateChanged(ActivityRecord, ActivityState, String)} when an
3509      * activity is resumed.
3510      */
3511     @GuardedBy("this")
3512     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3513         final TaskRecord task = r.getTask();
3514         if (task.isActivityTypeStandard()) {
3515             if (mCurAppTimeTracker != r.appTimeTracker) {
3516                 // We are switching app tracking.  Complete the current one.
3517                 if (mCurAppTimeTracker != null) {
3518                     mCurAppTimeTracker.stop();
3519                     mHandler.obtainMessage(
3520                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3521                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3522                     mCurAppTimeTracker = null;
3523                 }
3524                 if (r.appTimeTracker != null) {
3525                     mCurAppTimeTracker = r.appTimeTracker;
3526                     startTimeTrackingFocusedActivityLocked();
3527                 }
3528             } else {
3529                 startTimeTrackingFocusedActivityLocked();
3530             }
3531         } else {
3532             r.appTimeTracker = null;
3533         }
3534         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3535         // TODO: Probably not, because we don't want to resume voice on switching
3536         // back to this activity
3537         if (task.voiceInteractor != null) {
3538             startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3539         } else {
3540             finishRunningVoiceLocked();
3541
3542             if (mLastResumedActivity != null) {
3543                 final IVoiceInteractionSession session;
3544
3545                 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3546                 if (lastResumedActivityTask != null
3547                         && lastResumedActivityTask.voiceSession != null) {
3548                     session = lastResumedActivityTask.voiceSession;
3549                 } else {
3550                     session = mLastResumedActivity.voiceSession;
3551                 }
3552
3553                 if (session != null) {
3554                     // We had been in a voice interaction session, but now focused has
3555                     // move to something different.  Just finish the session, we can't
3556                     // return to it and retain the proper state and synchronization with
3557                     // the voice interaction service.
3558                     finishVoiceTask(session);
3559                 }
3560             }
3561         }
3562
3563         if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3564             mUserController.sendForegroundProfileChanged(r.userId);
3565         }
3566         updateResumedAppTrace(r);
3567         mLastResumedActivity = r;
3568
3569         mWindowManager.setFocusedApp(r.appToken, true);
3570
3571         applyUpdateLockStateLocked(r);
3572         applyUpdateVrModeLocked(r);
3573
3574         EventLogTags.writeAmSetResumedActivity(
3575                 r == null ? -1 : r.userId,
3576                 r == null ? "NULL" : r.shortComponentName,
3577                 reason);
3578     }
3579
3580     private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
3581         if (mTracedResumedActivity != null) {
3582             Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
3583                     constructResumedTraceName(mTracedResumedActivity.packageName), 0);
3584         }
3585         if (resumed != null) {
3586             Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
3587                     constructResumedTraceName(resumed.packageName), 0);
3588         }
3589         mTracedResumedActivity = resumed;
3590     }
3591
3592     private String constructResumedTraceName(String packageName) {
3593         return "focused app: " + packageName;
3594     }
3595
3596     @Override
3597     public void setFocusedStack(int stackId) {
3598         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3599         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3600         final long callingId = Binder.clearCallingIdentity();
3601         try {
3602             synchronized (this) {
3603                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3604                 if (stack == null) {
3605                     Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3606                     return;
3607                 }
3608                 final ActivityRecord r = stack.topRunningActivityLocked();
3609                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3610                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3611                 }
3612             }
3613         } finally {
3614             Binder.restoreCallingIdentity(callingId);
3615         }
3616     }
3617
3618     @Override
3619     public void setFocusedTask(int taskId) {
3620         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3621         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3622         final long callingId = Binder.clearCallingIdentity();
3623         try {
3624             synchronized (this) {
3625                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3626                 if (task == null) {
3627                     return;
3628                 }
3629                 final ActivityRecord r = task.topRunningActivityLocked();
3630                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3631                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3632                 }
3633             }
3634         } finally {
3635             Binder.restoreCallingIdentity(callingId);
3636         }
3637     }
3638
3639     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3640     @Override
3641     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3642         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3643                 "registerTaskStackListener()");
3644         mTaskChangeNotificationController.registerTaskStackListener(listener);
3645     }
3646
3647     /**
3648      * Unregister a task stack listener so that it stops receiving callbacks.
3649      */
3650     @Override
3651     public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3652         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3653                 "unregisterTaskStackListener()");
3654          mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3655      }
3656
3657     @Override
3658     public void notifyActivityDrawn(IBinder token) {
3659         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3660         synchronized (this) {
3661             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3662             if (r != null) {
3663                 r.getStack().notifyActivityDrawnLocked(r);
3664             }
3665         }
3666     }
3667
3668     final void applyUpdateLockStateLocked(ActivityRecord r) {
3669         // Modifications to the UpdateLock state are done on our handler, outside
3670         // the activity manager's locks.  The new state is determined based on the
3671         // state *now* of the relevant activity record.  The object is passed to
3672         // the handler solely for logging detail, not to be consulted/modified.
3673         final boolean nextState = r != null && r.immersive;
3674         mHandler.sendMessage(
3675                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3676     }
3677
3678     final void applyUpdateVrModeLocked(ActivityRecord r) {
3679         // VR apps are expected to run in a main display. If an app is turning on VR for
3680         // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3681         // fullscreen stack before enabling VR Mode.
3682         // TODO: The goal of this code is to keep the VR app on the main display. When the
3683         // stack implementation changes in the future, keep in mind that the use of the fullscreen
3684         // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3685         // option would be a better choice here.
3686         if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3687             Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3688                     + " to main stack for VR");
3689             final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3690                     WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3691             moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3692         }
3693         mHandler.sendMessage(
3694                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3695     }
3696
3697     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3698         Message msg = Message.obtain();
3699         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3700         msg.obj = r.getTask().askedCompatMode ? null : r;
3701         mUiHandler.sendMessage(msg);
3702     }
3703
3704     final AppWarnings getAppWarningsLocked() {
3705         return mAppWarnings;
3706     }
3707
3708     /**
3709      * Shows app warning dialogs, if necessary.
3710      *
3711      * @param r activity record for which the warnings may be displayed
3712      */
3713     final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3714         mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3715         mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3716         mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
3717     }
3718
3719     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3720             String what, Object obj, ProcessRecord srcApp) {
3721         app.lastActivityTime = now;
3722
3723         if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3724             // Don't want to touch dependent processes that are hosting activities.
3725             return index;
3726         }
3727
3728         int lrui = mLruProcesses.lastIndexOf(app);
3729         if (lrui < 0) {
3730             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3731                     + what + " " + obj + " from " + srcApp);
3732             return index;
3733         }
3734
3735         if (lrui >= index) {
3736             // Don't want to cause this to move dependent processes *back* in the
3737             // list as if they were less frequently used.
3738             return index;
3739         }
3740
3741         if (lrui >= mLruProcessActivityStart) {
3742             // Don't want to touch dependent processes that are hosting activities.
3743             return index;
3744         }
3745
3746         mLruProcesses.remove(lrui);
3747         if (index > 0) {
3748             index--;
3749         }
3750         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3751                 + " in LRU list: " + app);
3752         mLruProcesses.add(index, app);
3753         return index;
3754     }
3755
3756     static void killProcessGroup(int uid, int pid) {
3757         if (sKillHandler != null) {
3758             sKillHandler.sendMessage(
3759                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3760         } else {
3761             Slog.w(TAG, "Asked to kill process group before system bringup!");
3762             Process.killProcessGroup(uid, pid);
3763         }
3764     }
3765
3766     final void removeLruProcessLocked(ProcessRecord app) {
3767         int lrui = mLruProcesses.lastIndexOf(app);
3768         if (lrui >= 0) {
3769             if (!app.killed) {
3770                 if (app.persistent) {
3771                     Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
3772                 } else {
3773                     Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3774                     if (app.pid > 0) {
3775                         killProcessQuiet(app.pid);
3776                         killProcessGroup(app.uid, app.pid);
3777                     } else {
3778                         app.pendingStart = false;
3779                     }
3780                 }
3781             }
3782             if (lrui <= mLruProcessActivityStart) {
3783                 mLruProcessActivityStart--;
3784             }
3785             if (lrui <= mLruProcessServiceStart) {
3786                 mLruProcessServiceStart--;
3787             }
3788             mLruProcesses.remove(lrui);
3789         }
3790     }
3791
3792     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3793             ProcessRecord client) {
3794         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3795                 || app.treatLikeActivity || app.recentTasks.size() > 0;
3796         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3797         if (!activityChange && hasActivity) {
3798             // The process has activities, so we are only allowing activity-based adjustments
3799             // to move it.  It should be kept in the front of the list with other
3800             // processes that have activities, and we don't want those to change their
3801             // order except due to activity operations.
3802             return;
3803         }
3804
3805         mLruSeq++;
3806         final long now = SystemClock.uptimeMillis();
3807         app.lastActivityTime = now;
3808
3809         // First a quick reject: if the app is already at the position we will
3810         // put it, then there is nothing to do.
3811         if (hasActivity) {
3812             final int N = mLruProcesses.size();
3813             if (N > 0 && mLruProcesses.get(N-1) == app) {
3814                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3815                 return;
3816             }
3817         } else {
3818             if (mLruProcessServiceStart > 0
3819                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3820                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3821                 return;
3822             }
3823         }
3824
3825         int lrui = mLruProcesses.lastIndexOf(app);
3826
3827         if (app.persistent && lrui >= 0) {
3828             // We don't care about the position of persistent processes, as long as
3829             // they are in the list.
3830             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3831             return;
3832         }
3833
3834         /* In progress: compute new position first, so we can avoid doing work
3835            if the process is not actually going to move.  Not yet working.
3836         int addIndex;
3837         int nextIndex;
3838         boolean inActivity = false, inService = false;
3839         if (hasActivity) {
3840             // Process has activities, put it at the very tipsy-top.
3841             addIndex = mLruProcesses.size();
3842             nextIndex = mLruProcessServiceStart;
3843             inActivity = true;
3844         } else if (hasService) {
3845             // Process has services, put it at the top of the service list.
3846             addIndex = mLruProcessActivityStart;
3847             nextIndex = mLruProcessServiceStart;
3848             inActivity = true;
3849             inService = true;
3850         } else  {
3851             // Process not otherwise of interest, it goes to the top of the non-service area.
3852             addIndex = mLruProcessServiceStart;
3853             if (client != null) {
3854                 int clientIndex = mLruProcesses.lastIndexOf(client);
3855                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3856                         + app);
3857                 if (clientIndex >= 0 && addIndex > clientIndex) {
3858                     addIndex = clientIndex;
3859                 }
3860             }
3861             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3862         }
3863
3864         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3865                 + mLruProcessActivityStart + "): " + app);
3866         */
3867
3868         if (lrui >= 0) {
3869             if (lrui < mLruProcessActivityStart) {
3870                 mLruProcessActivityStart--;
3871             }
3872             if (lrui < mLruProcessServiceStart) {
3873                 mLruProcessServiceStart--;
3874             }
3875             /*
3876             if (addIndex > lrui) {
3877                 addIndex--;
3878             }
3879             if (nextIndex > lrui) {
3880                 nextIndex--;
3881             }
3882             */
3883             mLruProcesses.remove(lrui);
3884         }
3885
3886         /*
3887         mLruProcesses.add(addIndex, app);
3888         if (inActivity) {
3889             mLruProcessActivityStart++;
3890         }
3891         if (inService) {
3892             mLruProcessActivityStart++;
3893         }
3894         */
3895
3896         int nextIndex;
3897         if (hasActivity) {
3898             final int N = mLruProcesses.size();
3899             if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
3900                     && mLruProcessActivityStart < (N - 1)) {
3901                 // Process doesn't have activities, but has clients with
3902                 // activities...  move it up, but one below the top (the top
3903                 // should always have a real activity).
3904                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3905                         "Adding to second-top of LRU activity list: " + app);
3906                 mLruProcesses.add(N - 1, app);
3907                 // To keep it from spamming the LRU list (by making a bunch of clients),
3908                 // we will push down any other entries owned by the app.
3909                 final int uid = app.info.uid;
3910                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3911                     ProcessRecord subProc = mLruProcesses.get(i);
3912                     if (subProc.info.uid == uid) {
3913                         // We want to push this one down the list.  If the process after
3914                         // it is for the same uid, however, don't do so, because we don't
3915                         // want them internally to be re-ordered.
3916                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3917                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3918                                     "Pushing uid " + uid + " swapping at " + i + ": "
3919                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3920                             ProcessRecord tmp = mLruProcesses.get(i);
3921                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3922                             mLruProcesses.set(i - 1, tmp);
3923                             i--;
3924                         }
3925                     } else {
3926                         // A gap, we can stop here.
3927                         break;
3928                     }
3929                 }
3930             } else {
3931                 // Process has activities, put it at the very tipsy-top.
3932                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3933                 mLruProcesses.add(app);
3934             }
3935             nextIndex = mLruProcessServiceStart;
3936         } else if (hasService) {
3937             // Process has services, put it at the top of the service list.
3938             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3939             mLruProcesses.add(mLruProcessActivityStart, app);
3940             nextIndex = mLruProcessServiceStart;
3941             mLruProcessActivityStart++;
3942         } else  {
3943             // Process not otherwise of interest, it goes to the top of the non-service area.
3944             int index = mLruProcessServiceStart;
3945             if (client != null) {
3946                 // If there is a client, don't allow the process to be moved up higher
3947                 // in the list than that client.
3948                 int clientIndex = mLruProcesses.lastIndexOf(client);
3949                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3950                         + " when updating " + app);
3951                 if (clientIndex <= lrui) {
3952                     // Don't allow the client index restriction to push it down farther in the
3953                     // list than it already is.
3954                     clientIndex = lrui;
3955                 }
3956                 if (clientIndex >= 0 && index > clientIndex) {
3957                     index = clientIndex;
3958                 }
3959             }
3960             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3961             mLruProcesses.add(index, app);
3962             nextIndex = index-1;
3963             mLruProcessActivityStart++;
3964             mLruProcessServiceStart++;
3965         }
3966
3967         // If the app is currently using a content provider or service,
3968         // bump those processes as well.
3969         for (int j=app.connections.size()-1; j>=0; j--) {
3970             ConnectionRecord cr = app.connections.valueAt(j);
3971             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3972                     && cr.binding.service.app != null
3973                     && cr.binding.service.app.lruSeq != mLruSeq
3974                     && !cr.binding.service.app.persistent) {
3975                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3976                         "service connection", cr, app);
3977             }
3978         }
3979         for (int j=app.conProviders.size()-1; j>=0; j--) {
3980             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3981             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3982                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3983                         "provider reference", cpr, app);
3984             }
3985         }
3986     }
3987
3988     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3989         if (uid == SYSTEM_UID) {
3990             // The system gets to run in any process.  If there are multiple
3991             // processes with the same uid, just pick the first (this
3992             // should never happen).
3993             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3994             if (procs == null) return null;
3995             final int procCount = procs.size();
3996             for (int i = 0; i < procCount; i++) {
3997                 final int procUid = procs.keyAt(i);
3998                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3999                     // Don't use an app process or different user process for system component.
4000                     continue;
4001                 }
4002                 return procs.valueAt(i);
4003             }
4004         }
4005         ProcessRecord proc = mProcessNames.get(processName, uid);
4006         if (false && proc != null && !keepIfLarge
4007                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
4008                 && proc.lastCachedPss >= 4000) {
4009             // Turn this condition on to cause killing to happen regularly, for testing.
4010             if (proc.baseProcessTracker != null) {
4011                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
4012             }
4013             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
4014         } else if (proc != null && !keepIfLarge
4015                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
4016                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
4017             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
4018             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
4019                 if (proc.baseProcessTracker != null) {
4020                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
4021                 }
4022                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
4023             }
4024         }
4025         return proc;
4026     }
4027
4028     void notifyPackageUse(String packageName, int reason) {
4029         synchronized(this) {
4030             getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
4031         }
4032     }
4033
4034     boolean isNextTransitionForward() {
4035         int transit = mWindowManager.getPendingAppTransition();
4036         return transit == TRANSIT_ACTIVITY_OPEN
4037                 || transit == TRANSIT_TASK_OPEN
4038                 || transit == TRANSIT_TASK_TO_FRONT;
4039     }
4040
4041     boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
4042             String processName, String abiOverride, int uid, Runnable crashHandler) {
4043         synchronized(this) {
4044             ApplicationInfo info = new ApplicationInfo();
4045             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
4046             // For isolated processes, the former contains the parent's uid and the latter the
4047             // actual uid of the isolated process.
4048             // In the special case introduced by this method (which is, starting an isolated
4049             // process directly from the SystemServer without an actual parent app process) the
4050             // closest thing to a parent's uid is SYSTEM_UID.
4051             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
4052             // the |isolated| logic in the ProcessRecord constructor.
4053             info.uid = SYSTEM_UID;
4054             info.processName = processName;
4055             info.className = entryPoint;
4056             info.packageName = "android";
4057             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
4058             info.targetSdkVersion = Build.VERSION.SDK_INT;
4059             ProcessRecord proc = startProcessLocked(processName, info /* info */,
4060                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
4061                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
4062                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
4063                     crashHandler);
4064             return proc != null;
4065         }
4066     }
4067
4068     @GuardedBy("this")
4069     final ProcessRecord startProcessLocked(String processName,
4070             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
4071             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
4072             boolean isolated, boolean keepIfLarge) {
4073         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
4074                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
4075                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
4076                 null /* crashHandler */);
4077     }
4078
4079     @GuardedBy("this")
4080     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
4081             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
4082             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
4083             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
4084         long startTime = SystemClock.elapsedRealtime();
4085         ProcessRecord app;
4086         if (!isolated) {
4087             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
4088             checkTime(startTime, "startProcess: after getProcessRecord");
4089
4090             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
4091                 // If we are in the background, then check to see if this process
4092                 // is bad.  If so, we will just silently fail.
4093                 if (mAppErrors.isBadProcessLocked(info)) {
4094                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
4095                             + "/" + info.processName);
4096                     return null;
4097                 }
4098             } else {
4099                 // When the user is explicitly starting a process, then clear its
4100                 // crash count so that we won't make it bad until they see at
4101                 // least one crash dialog again, and make the process good again
4102                 // if it had been bad.
4103                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
4104                         + "/" + info.processName);
4105                 mAppErrors.resetProcessCrashTimeLocked(info);
4106                 if (mAppErrors.isBadProcessLocked(info)) {
4107                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
4108                             UserHandle.getUserId(info.uid), info.uid,
4109                             info.processName);
4110                     mAppErrors.clearBadProcessLocked(info);
4111                     if (app != null) {
4112                         app.bad = false;
4113                     }
4114                 }
4115             }
4116         } else {
4117             // If this is an isolated process, it can't re-use an existing process.
4118             app = null;
4119         }
4120
4121         // We don't have to do anything more if:
4122         // (1) There is an existing application record; and
4123         // (2) The caller doesn't think it is dead, OR there is no thread
4124         //     object attached to it so we know it couldn't have crashed; and
4125         // (3) There is a pid assigned to it, so it is either starting or
4126         //     already running.
4127         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
4128                 + " app=" + app + " knownToBeDead=" + knownToBeDead
4129                 + " thread=" + (app != null ? app.thread : null)
4130                 + " pid=" + (app != null ? app.pid : -1));
4131         if (app != null && app.pid > 0) {
4132             if ((!knownToBeDead && !app.killed) || app.thread == null) {
4133                 // We already have the app running, or are waiting for it to
4134                 // come up (we have a pid but not yet its thread), so keep it.
4135                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
4136                 // If this is a new package in the process, add the package to the list
4137                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
4138                 checkTime(startTime, "startProcess: done, added package to proc");
4139                 return app;
4140             }
4141
4142             // An application record is attached to a previous process,
4143             // clean it up now.
4144             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
4145             checkTime(startTime, "startProcess: bad proc running, killing");
4146             killProcessGroup(app.uid, app.pid);
4147             handleAppDiedLocked(app, true, true);
4148             checkTime(startTime, "startProcess: done killing old proc");
4149         }
4150
4151         String hostingNameStr = hostingName != null
4152                 ? hostingName.flattenToShortString() : null;
4153
4154         if (app == null) {
4155             checkTime(startTime, "startProcess: creating new process record");
4156             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
4157             if (app == null) {
4158                 Slog.w(TAG, "Failed making new process record for "
4159                         + processName + "/" + info.uid + " isolated=" + isolated);
4160                 return null;
4161             }
4162             app.crashHandler = crashHandler;
4163             app.isolatedEntryPoint = entryPoint;
4164             app.isolatedEntryPointArgs = entryPointArgs;
4165             checkTime(startTime, "startProcess: done creating new process record");
4166         } else {
4167             // If this is a new package in the process, add the package to the list
4168             app.addPackage(info.packageName, info.versionCode, mProcessStats);
4169             checkTime(startTime, "startProcess: added package to existing proc");
4170         }
4171
4172         // If the system is not ready yet, then hold off on starting this
4173         // process until it is.
4174         if (!mProcessesReady
4175                 && !isAllowedWhileBooting(info)
4176                 && !allowWhileBooting) {
4177             if (!mProcessesOnHold.contains(app)) {
4178                 mProcessesOnHold.add(app);
4179             }
4180             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
4181                     "System not ready, putting on hold: " + app);
4182             checkTime(startTime, "startProcess: returning with proc on hold");
4183             return app;
4184         }
4185
4186         checkTime(startTime, "startProcess: stepping in to startProcess");
4187         final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
4188         checkTime(startTime, "startProcess: done starting proc!");
4189         return success ? app : null;
4190     }
4191
4192     boolean isAllowedWhileBooting(ApplicationInfo ai) {
4193         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
4194     }
4195
4196     @GuardedBy("this")
4197     private final void startProcessLocked(ProcessRecord app,
4198             String hostingType, String hostingNameStr) {
4199         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
4200     }
4201
4202     @GuardedBy("this")
4203     private final boolean startProcessLocked(ProcessRecord app,
4204             String hostingType, String hostingNameStr, String abiOverride) {
4205         return startProcessLocked(app, hostingType, hostingNameStr,
4206                 false /* disableHiddenApiChecks */, abiOverride);
4207     }
4208
4209     /**
4210      * @return {@code true} if process start is successful, false otherwise.
4211      */
4212     @GuardedBy("this")
4213     private final boolean startProcessLocked(ProcessRecord app, String hostingType,
4214             String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
4215         if (app.pendingStart) {
4216             return true;
4217         }
4218         long startTime = SystemClock.elapsedRealtime();
4219         if (app.pid > 0 && app.pid != MY_PID) {
4220             checkTime(startTime, "startProcess: removing from pids map");
4221             synchronized (mPidsSelfLocked) {
4222                 mPidsSelfLocked.remove(app.pid);
4223                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4224             }
4225             checkTime(startTime, "startProcess: done removing from pids map");
4226             app.setPid(0);
4227             app.startSeq = 0;
4228         }
4229
4230         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
4231                 "startProcessLocked removing on hold: " + app);
4232         mProcessesOnHold.remove(app);
4233
4234         checkTime(startTime, "startProcess: starting to update cpu stats");
4235         updateCpuStats();
4236         checkTime(startTime, "startProcess: done updating cpu stats");
4237
4238         try {
4239             try {
4240                 final int userId = UserHandle.getUserId(app.uid);
4241                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
4242             } catch (RemoteException e) {
4243                 throw e.rethrowAsRuntimeException();
4244             }
4245
4246             int uid = app.uid;
4247             int[] gids = null;
4248             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
4249             if (!app.isolated) {
4250                 int[] permGids = null;
4251                 try {
4252                     checkTime(startTime, "startProcess: getting gids from package manager");
4253                     final IPackageManager pm = AppGlobals.getPackageManager();
4254                     permGids = pm.getPackageGids(app.info.packageName,
4255                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
4256                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
4257                             StorageManagerInternal.class);
4258                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
4259                             app.info.packageName);
4260                 } catch (RemoteException e) {
4261                     throw e.rethrowAsRuntimeException();
4262                 }
4263
4264                 /*
4265                  * Add shared application and profile GIDs so applications can share some
4266                  * resources like shared libraries and access user-wide resources
4267                  */
4268                 if (ArrayUtils.isEmpty(permGids)) {
4269                     gids = new int[3];
4270                 } else {
4271                     gids = new int[permGids.length + 3];
4272                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
4273                 }
4274                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
4275                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
4276                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
4277
4278                 // Replace any invalid GIDs
4279                 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
4280                 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
4281             }
4282             checkTime(startTime, "startProcess: building args");
4283             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
4284                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4285                         && mTopComponent != null
4286                         && app.processName.equals(mTopComponent.getPackageName())) {
4287                     uid = 0;
4288                 }
4289                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
4290                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
4291                     uid = 0;
4292                 }
4293             }
4294             int runtimeFlags = 0;
4295             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4296                 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
4297                 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
4298                 // Also turn on CheckJNI for debuggable apps. It's quite
4299                 // awkward to turn on otherwise.
4300                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4301             }
4302             // Run the app in safe mode if its manifest requests so or the
4303             // system is booted in safe mode.
4304             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
4305                 mSafeMode == true) {
4306                 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
4307             }
4308             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4309                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4310             }
4311             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4312             if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
4313                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4314             }
4315             String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
4316             if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
4317                 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
4318             }
4319             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4320                 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4321             }
4322             if ("1".equals(SystemProperties.get("debug.assert"))) {
4323                 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
4324             }
4325             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
4326                 // Enable all debug flags required by the native debugger.
4327                 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
4328                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
4329                 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
4330                 mNativeDebuggingApp = null;
4331             }
4332
4333             if (app.info.isPrivilegedApp() &&
4334                     DexManager.isPackageSelectedToRunOob(app.pkgList.keySet())) {
4335                 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
4336             }
4337
4338             if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) {
4339                 app.info.maybeUpdateHiddenApiEnforcementPolicy(
4340                         mHiddenApiBlacklist.getPolicyForPrePApps(),
4341                         mHiddenApiBlacklist.getPolicyForPApps());
4342                 @HiddenApiEnforcementPolicy int policy =
4343                         app.info.getHiddenApiEnforcementPolicy();
4344                 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
4345                 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
4346                     throw new IllegalStateException("Invalid API policy: " + policy);
4347                 }
4348                 runtimeFlags |= policyBits;
4349             }
4350
4351             String invokeWith = null;
4352             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4353                 // Debuggable apps may include a wrapper script with their library directory.
4354                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
4355                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4356                 try {
4357                     if (new File(wrapperFileName).exists()) {
4358                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4359                     }
4360                 } finally {
4361                     StrictMode.setThreadPolicy(oldPolicy);
4362                 }
4363             }
4364
4365             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4366             if (requiredAbi == null) {
4367                 requiredAbi = Build.SUPPORTED_ABIS[0];
4368             }
4369
4370             String instructionSet = null;
4371             if (app.info.primaryCpuAbi != null) {
4372                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4373             }
4374
4375             app.gids = gids;
4376             app.requiredAbi = requiredAbi;
4377             app.instructionSet = instructionSet;
4378
4379             // the per-user SELinux context must be set
4380             if (TextUtils.isEmpty(app.info.seInfoUser)) {
4381                 Slog.wtf(TAG, "SELinux tag not defined",
4382                         new IllegalStateException("SELinux tag not defined for "
4383                         + app.info.packageName + " (uid " + app.uid + ")"));
4384             }
4385             final String seInfo = app.info.seInfo
4386                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
4387             // Start the process.  It will either succeed and return a result containing
4388             // the PID of the new process, or else throw a RuntimeException.
4389             final String entryPoint = "android.app.ActivityThread";
4390
4391             return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4392                     runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4393                     startTime);
4394         } catch (RuntimeException e) {
4395             Slog.e(TAG, "Failure starting process " + app.processName, e);
4396
4397             // Something went very wrong while trying to start this process; one
4398             // common case is when the package is frozen due to an active
4399             // upgrade. To recover, clean up any active bookkeeping related to
4400             // starting this process. (We already invoked this method once when
4401             // the package was initially frozen through KILL_APPLICATION_MSG, so
4402             // it doesn't hurt to use it again.)
4403             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4404                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4405             return false;
4406         }
4407     }
4408
4409     @GuardedBy("this")
4410     private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4411             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4412             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4413             long startTime) {
4414         app.pendingStart = true;
4415         app.killedByAm = false;
4416         app.removed = false;
4417         app.killed = false;
4418         if (app.startSeq != 0) {
4419             Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
4420                     + " with non-zero startSeq:" + app.startSeq);
4421         }
4422         if (app.pid != 0) {
4423             Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
4424                     + " with non-zero pid:" + app.pid);
4425         }
4426         final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4427         app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4428         if (mConstants.FLAG_PROCESS_START_ASYNC) {
4429             if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4430                     "Posting procStart msg for " + app.toShortString());
4431             mProcStartHandler.post(() -> {
4432                 try {
4433                     synchronized (ActivityManagerService.this) {
4434                         final String reason = isProcStartValidLocked(app, startSeq);
4435                         if (reason != null) {
4436                             Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4437                                     + " don't start process, " + reason);
4438                             app.pendingStart = false;
4439                             return;
4440                         }
4441                         app.usingWrapper = invokeWith != null
4442                                 || SystemProperties.get("wrap." + app.processName) != null;
4443                         mPendingStarts.put(startSeq, app);
4444                     }
4445                     final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4446                             app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4447                             requiredAbi, instructionSet, invokeWith, app.startTime);
4448                     synchronized (ActivityManagerService.this) {
4449                         handleProcessStartedLocked(app, startResult, startSeq);
4450                     }
4451                 } catch (RuntimeException e) {
4452                     synchronized (ActivityManagerService.this) {
4453                         Slog.e(TAG, "Failure starting process " + app.processName, e);
4454                         mPendingStarts.remove(startSeq);
4455                         app.pendingStart = false;
4456                         forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4457                                 false, false, true, false, false,
4458                                 UserHandle.getUserId(app.userId), "start failure");
4459                     }
4460                 }
4461             });
4462             return true;
4463         } else {
4464             try {
4465                 final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4466                         uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4467                         invokeWith, startTime);
4468                 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4469                         startSeq, false);
4470             } catch (RuntimeException e) {
4471                 Slog.e(TAG, "Failure starting process " + app.processName, e);
4472                 app.pendingStart = false;
4473                 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4474                         false, false, true, false, false,
4475                         UserHandle.getUserId(app.userId), "start failure");
4476             }
4477             return app.pid > 0;
4478         }
4479     }
4480
4481     private ProcessStartResult startProcess(String hostingType, String entryPoint,
4482             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4483             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4484             long startTime) {
4485         try {
4486             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4487                     app.processName);
4488             checkTime(startTime, "startProcess: asking zygote to start proc");
4489             final ProcessStartResult startResult;
4490             if (hostingType.equals("webview_service")) {
4491                 startResult = startWebView(entryPoint,
4492                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4493                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4494                         app.info.dataDir, null,
4495                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4496             } else {
4497                 startResult = Process.start(entryPoint,
4498                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4499                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4500                         app.info.dataDir, invokeWith,
4501                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4502             }
4503             checkTime(startTime, "startProcess: returned from zygote!");
4504             return startResult;
4505         } finally {
4506             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4507         }
4508     }
4509
4510     @GuardedBy("this")
4511     private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4512         StringBuilder sb = null;
4513         if (app.killedByAm) {
4514             if (sb == null) sb = new StringBuilder();
4515             sb.append("killedByAm=true;");
4516         }
4517         if (mProcessNames.get(app.processName, app.uid) != app) {
4518             if (sb == null) sb = new StringBuilder();
4519             sb.append("No entry in mProcessNames;");
4520         }
4521         if (!app.pendingStart) {
4522             if (sb == null) sb = new StringBuilder();
4523             sb.append("pendingStart=false;");
4524         }
4525         if (app.startSeq > expectedStartSeq) {
4526             if (sb == null) sb = new StringBuilder();
4527             sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4528         }
4529         return sb == null ? null : sb.toString();
4530     }
4531
4532     @GuardedBy("this")
4533     private boolean handleProcessStartedLocked(ProcessRecord pending,
4534             ProcessStartResult startResult, long expectedStartSeq) {
4535         // Indicates that this process start has been taken care of.
4536         if (mPendingStarts.get(expectedStartSeq) == null) {
4537             if (pending.pid == startResult.pid) {
4538                 pending.usingWrapper = startResult.usingWrapper;
4539                 // TODO: Update already existing clients of usingWrapper
4540             }
4541             return false;
4542         }
4543         return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4544                 expectedStartSeq, false);
4545     }
4546
4547     @GuardedBy("this")
4548     private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4549             long expectedStartSeq, boolean procAttached) {
4550         mPendingStarts.remove(expectedStartSeq);
4551         final String reason = isProcStartValidLocked(app, expectedStartSeq);
4552         if (reason != null) {
4553             Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4554                     + ", " + reason);
4555             app.pendingStart = false;
4556             Process.killProcessQuiet(pid);
4557             Process.killProcessGroup(app.uid, app.pid);
4558             return false;
4559         }
4560         mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4561         checkTime(app.startTime, "startProcess: done updating battery stats");
4562
4563         EventLog.writeEvent(EventLogTags.AM_PROC_START,
4564                 UserHandle.getUserId(app.startUid), pid, app.startUid,
4565                 app.processName, app.hostingType,
4566                 app.hostingNameStr != null ? app.hostingNameStr : "");
4567
4568         try {
4569             AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4570                     app.seInfo, app.info.sourceDir, pid);
4571         } catch (RemoteException ex) {
4572             // Ignore
4573         }
4574
4575         if (app.persistent) {
4576             Watchdog.getInstance().processStarted(app.processName, pid);
4577         }
4578
4579         checkTime(app.startTime, "startProcess: building log message");
4580         StringBuilder buf = mStringBuilder;
4581         buf.setLength(0);
4582         buf.append("Start proc ");
4583         buf.append(pid);
4584         buf.append(':');
4585         buf.append(app.processName);
4586         buf.append('/');
4587         UserHandle.formatUid(buf, app.startUid);
4588         if (app.isolatedEntryPoint != null) {
4589             buf.append(" [");
4590             buf.append(app.isolatedEntryPoint);
4591             buf.append("]");
4592         }
4593         buf.append(" for ");
4594         buf.append(app.hostingType);
4595         if (app.hostingNameStr != null) {
4596             buf.append(" ");
4597             buf.append(app.hostingNameStr);
4598         }
4599         reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
4600         app.setPid(pid);
4601         app.usingWrapper = usingWrapper;
4602         app.pendingStart = false;
4603         checkTime(app.startTime, "startProcess: starting to update pids map");
4604         ProcessRecord oldApp;
4605         synchronized (mPidsSelfLocked) {
4606             oldApp = mPidsSelfLocked.get(pid);
4607         }
4608         // If there is already an app occupying that pid that hasn't been cleaned up
4609         if (oldApp != null && !app.isolated) {
4610             // Clean up anything relating to this pid first
4611           Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName
4612                   + " startSeq:" + app.startSeq
4613                   + " pid:" + pid
4614                   + " belongs to another existing app:" + oldApp.processName
4615                   + " startSeq:" + oldApp.startSeq);
4616             cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4617                     true /*replacingPid*/);
4618         }
4619         synchronized (mPidsSelfLocked) {
4620             this.mPidsSelfLocked.put(pid, app);
4621             if (!procAttached) {
4622                 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4623                 msg.obj = app;
4624                 mHandler.sendMessageDelayed(msg, usingWrapper
4625                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4626             }
4627         }
4628         checkTime(app.startTime, "startProcess: done updating pids map");
4629         return true;
4630     }
4631
4632     void updateUsageStats(ActivityRecord component, boolean resumed) {
4633         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4634                 "updateUsageStats: comp=" + component + "res=" + resumed);
4635         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4636         StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4637             component.app.uid, component.realActivity.getPackageName(),
4638             component.realActivity.getShortClassName(), resumed ?
4639                         StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND :
4640                         StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND);
4641         if (resumed) {
4642             if (mUsageStatsService != null) {
4643                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4644                         UsageEvents.Event.MOVE_TO_FOREGROUND);
4645
4646             }
4647             synchronized (stats) {
4648                 stats.noteActivityResumedLocked(component.app.uid);
4649             }
4650         } else {
4651             if (mUsageStatsService != null) {
4652                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4653                         UsageEvents.Event.MOVE_TO_BACKGROUND);
4654             }
4655             synchronized (stats) {
4656                 stats.noteActivityPausedLocked(component.app.uid);
4657             }
4658         }
4659     }
4660
4661     Intent getHomeIntent() {
4662         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4663         intent.setComponent(mTopComponent);
4664         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4665         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4666             intent.addCategory(Intent.CATEGORY_HOME);
4667         }
4668         return intent;
4669     }
4670
4671     boolean startHomeActivityLocked(int userId, String reason) {
4672         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4673                 && mTopAction == null) {
4674             // We are running in factory test mode, but unable to find
4675             // the factory test app, so just sit around displaying the
4676             // error message and don't try to start anything.
4677             return false;
4678         }
4679         Intent intent = getHomeIntent();
4680         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4681         if (aInfo != null) {
4682             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4683             // Don't do this if the home app is currently being
4684             // instrumented.
4685             aInfo = new ActivityInfo(aInfo);
4686             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4687             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4688                     aInfo.applicationInfo.uid, true);
4689             if (app == null || app.instr == null) {
4690                 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4691                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4692                 // For ANR debugging to verify if the user activity is the one that actually
4693                 // launched.
4694                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4695                 mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4696             }
4697         } else {
4698             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4699         }
4700
4701         return true;
4702     }
4703
4704     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4705         ActivityInfo ai = null;
4706         ComponentName comp = intent.getComponent();
4707         try {
4708             if (comp != null) {
4709                 // Factory test.
4710                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4711             } else {
4712                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4713                         intent,
4714                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4715                         flags, userId);
4716
4717                 if (info != null) {
4718                     ai = info.activityInfo;
4719                 }
4720             }
4721         } catch (RemoteException e) {
4722             // ignore
4723         }
4724
4725         return ai;
4726     }
4727
4728     boolean getCheckedForSetup() {
4729         return mCheckedForSetup;
4730     }
4731
4732     void setCheckedForSetup(boolean checked) {
4733         mCheckedForSetup = checked;
4734     }
4735
4736     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4737         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4738     }
4739
4740     void enforceNotIsolatedCaller(String caller) {
4741         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4742             throw new SecurityException("Isolated process not allowed to call " + caller);
4743         }
4744     }
4745
4746     @Override
4747     public int getFrontActivityScreenCompatMode() {
4748         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4749         synchronized (this) {
4750             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4751         }
4752     }
4753
4754     @Override
4755     public void setFrontActivityScreenCompatMode(int mode) {
4756         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4757                 "setFrontActivityScreenCompatMode");
4758         synchronized (this) {
4759             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4760         }
4761     }
4762
4763     @Override
4764     public int getPackageScreenCompatMode(String packageName) {
4765         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4766         synchronized (this) {
4767             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4768         }
4769     }
4770
4771     @Override
4772     public void setPackageScreenCompatMode(String packageName, int mode) {
4773         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4774                 "setPackageScreenCompatMode");
4775         synchronized (this) {
4776             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4777         }
4778     }
4779
4780     @Override
4781     public boolean getPackageAskScreenCompat(String packageName) {
4782         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4783         synchronized (this) {
4784             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4785         }
4786     }
4787
4788     @Override
4789     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4790         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4791                 "setPackageAskScreenCompat");
4792         synchronized (this) {
4793             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4794         }
4795     }
4796
4797     private boolean hasUsageStatsPermission(String callingPackage) {
4798         final int mode = mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS,
4799                 Binder.getCallingUid(), callingPackage);
4800         if (mode == AppOpsManager.MODE_DEFAULT) {
4801             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4802                     == PackageManager.PERMISSION_GRANTED;
4803         }
4804         return mode == AppOpsManager.MODE_ALLOWED;
4805     }
4806
4807     @Override
4808     public int getPackageProcessState(String packageName, String callingPackage) {
4809         if (!hasUsageStatsPermission(callingPackage)) {
4810             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4811                     "getPackageProcessState");
4812         }
4813
4814         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4815         synchronized (this) {
4816             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4817                 final ProcessRecord proc = mLruProcesses.get(i);
4818                 if (procState > proc.setProcState) {
4819                     if (proc.pkgList.containsKey(packageName) ||
4820                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4821                         procState = proc.setProcState;
4822                     }
4823                 }
4824             }
4825         }
4826         return procState;
4827     }
4828
4829     @Override
4830     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4831             throws RemoteException {
4832         synchronized (this) {
4833             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4834             if (app == null) {
4835                 throw new IllegalArgumentException("Unknown process: " + process);
4836             }
4837             if (app.thread == null) {
4838                 throw new IllegalArgumentException("Process has no app thread");
4839             }
4840             if (app.trimMemoryLevel >= level) {
4841                 throw new IllegalArgumentException(
4842                         "Unable to set a higher trim level than current level");
4843             }
4844             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4845                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4846                 throw new IllegalArgumentException("Unable to set a background trim level "
4847                     + "on a foreground process");
4848             }
4849             app.thread.scheduleTrimMemory(level);
4850             app.trimMemoryLevel = level;
4851             return true;
4852         }
4853     }
4854
4855     private void dispatchProcessesChanged() {
4856         int N;
4857         synchronized (this) {
4858             N = mPendingProcessChanges.size();
4859             if (mActiveProcessChanges.length < N) {
4860                 mActiveProcessChanges = new ProcessChangeItem[N];
4861             }
4862             mPendingProcessChanges.toArray(mActiveProcessChanges);
4863             mPendingProcessChanges.clear();
4864             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4865                     "*** Delivering " + N + " process changes");
4866         }
4867
4868         int i = mProcessObservers.beginBroadcast();
4869         while (i > 0) {
4870             i--;
4871             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4872             if (observer != null) {
4873                 try {
4874                     for (int j=0; j<N; j++) {
4875                         ProcessChangeItem item = mActiveProcessChanges[j];
4876                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4877                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4878                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4879                                     + item.uid + ": " + item.foregroundActivities);
4880                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4881                                     item.foregroundActivities);
4882                         }
4883                     }
4884                 } catch (RemoteException e) {
4885                 }
4886             }
4887         }
4888         mProcessObservers.finishBroadcast();
4889
4890         synchronized (this) {
4891             for (int j=0; j<N; j++) {
4892                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4893             }
4894         }
4895     }
4896
4897     private void dispatchProcessDied(int pid, int uid) {
4898         int i = mProcessObservers.beginBroadcast();
4899         while (i > 0) {
4900             i--;
4901             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4902             if (observer != null) {
4903                 try {
4904                     observer.onProcessDied(pid, uid);
4905                 } catch (RemoteException e) {
4906                 }
4907             }
4908         }
4909         mProcessObservers.finishBroadcast();
4910     }
4911
4912     @VisibleForTesting
4913     void dispatchUidsChanged() {
4914         int N;
4915         synchronized (this) {
4916             N = mPendingUidChanges.size();
4917             if (mActiveUidChanges.length < N) {
4918                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4919             }
4920             for (int i=0; i<N; i++) {
4921                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4922                 mActiveUidChanges[i] = change;
4923                 if (change.uidRecord != null) {
4924                     change.uidRecord.pendingChange = null;
4925                     change.uidRecord = null;
4926                 }
4927             }
4928             mPendingUidChanges.clear();
4929             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4930                     "*** Delivering " + N + " uid changes");
4931         }
4932
4933         mUidChangeDispatchCount += N;
4934         int i = mUidObservers.beginBroadcast();
4935         while (i > 0) {
4936             i--;
4937             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4938                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4939         }
4940         mUidObservers.finishBroadcast();
4941
4942         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4943             for (int j = 0; j < N; ++j) {
4944                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4945                 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4946                     mValidateUids.remove(item.uid);
4947                 } else {
4948                     UidRecord validateUid = mValidateUids.get(item.uid);
4949                     if (validateUid == null) {
4950                         validateUid = new UidRecord(item.uid);
4951                         mValidateUids.put(item.uid, validateUid);
4952                     }
4953                     if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4954                         validateUid.idle = true;
4955                     } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4956                         validateUid.idle = false;
4957                     }
4958                     validateUid.curProcState = validateUid.setProcState = item.processState;
4959                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4960                 }
4961             }
4962         }
4963
4964         synchronized (this) {
4965             for (int j = 0; j < N; j++) {
4966                 mAvailUidChanges.add(mActiveUidChanges[j]);
4967             }
4968         }
4969     }
4970
4971     private void dispatchUidsChangedForObserver(IUidObserver observer,
4972             UidObserverRegistration reg, int changesSize) {
4973         if (observer == null) {
4974             return;
4975         }
4976         try {
4977             for (int j = 0; j < changesSize; j++) {
4978                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4979                 final int change = item.change;
4980                 if (change == UidRecord.CHANGE_PROCSTATE &&
4981                         (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4982                     // No-op common case: no significant change, the observer is not
4983                     // interested in all proc state changes.
4984                     continue;
4985                 }
4986                 final long start = SystemClock.uptimeMillis();
4987                 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4988                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4989                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4990                                 "UID idle uid=" + item.uid);
4991                         observer.onUidIdle(item.uid, item.ephemeral);
4992                     }
4993                 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4994                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4995                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4996                                 "UID active uid=" + item.uid);
4997                         observer.onUidActive(item.uid);
4998                     }
4999                 }
5000                 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
5001                     if ((change & UidRecord.CHANGE_CACHED) != 0) {
5002                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5003                                 "UID cached uid=" + item.uid);
5004                         observer.onUidCachedChanged(item.uid, true);
5005                     } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
5006                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5007                                 "UID active uid=" + item.uid);
5008                         observer.onUidCachedChanged(item.uid, false);
5009                     }
5010                 }
5011                 if ((change & UidRecord.CHANGE_GONE) != 0) {
5012                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
5013                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5014                                 "UID gone uid=" + item.uid);
5015                         observer.onUidGone(item.uid, item.ephemeral);
5016                     }
5017                     if (reg.lastProcStates != null) {
5018                         reg.lastProcStates.delete(item.uid);
5019                     }
5020                 } else {
5021                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
5022                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5023                                 "UID CHANGED uid=" + item.uid
5024                                         + ": " + item.processState);
5025                         boolean doReport = true;
5026                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
5027                             final int lastState = reg.lastProcStates.get(item.uid,
5028                                     ActivityManager.PROCESS_STATE_UNKNOWN);
5029                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
5030                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
5031                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
5032                                 doReport = lastAboveCut != newAboveCut;
5033                             } else {
5034                                 doReport = item.processState
5035                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
5036                             }
5037                         }
5038                         if (doReport) {
5039                             if (reg.lastProcStates != null) {
5040                                 reg.lastProcStates.put(item.uid, item.processState);
5041                             }
5042                             observer.onUidStateChanged(item.uid, item.processState,
5043                                     item.procStateSeq);
5044                         }
5045                     }
5046                 }
5047                 final int duration = (int) (SystemClock.uptimeMillis() - start);
5048                 if (reg.mMaxDispatchTime < duration) {
5049                     reg.mMaxDispatchTime = duration;
5050                 }
5051                 if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
5052                     reg.mSlowDispatchCount++;
5053                 }
5054             }
5055         } catch (RemoteException e) {
5056         }
5057     }
5058
5059     void dispatchOomAdjObserver(String msg) {
5060         OomAdjObserver observer;
5061         synchronized (this) {
5062             observer = mCurOomAdjObserver;
5063         }
5064
5065         if (observer != null) {
5066             observer.onOomAdjMessage(msg);
5067         }
5068     }
5069
5070     void setOomAdjObserver(int uid, OomAdjObserver observer) {
5071         synchronized (this) {
5072             mCurOomAdjUid = uid;
5073             mCurOomAdjObserver = observer;
5074         }
5075     }
5076
5077     void clearOomAdjObserver() {
5078         synchronized (this) {
5079             mCurOomAdjUid = -1;
5080             mCurOomAdjObserver = null;
5081         }
5082     }
5083
5084     void reportOomAdjMessageLocked(String tag, String msg) {
5085         Slog.d(tag, msg);
5086         if (mCurOomAdjObserver != null) {
5087             mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
5088         }
5089     }
5090
5091     void reportUidInfoMessageLocked(String tag, String msg, int uid) {
5092         Slog.i(TAG, msg);
5093         if (mCurOomAdjObserver != null && uid == mCurOomAdjUid) {
5094             mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
5095         }
5096
5097     }
5098
5099     @Override
5100     public final int startActivity(IApplicationThread caller, String callingPackage,
5101             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5102             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
5103         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
5104                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
5105                 UserHandle.getCallingUserId());
5106     }
5107
5108     @Override
5109     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
5110             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5111             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5112         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
5113                 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
5114                 true /*validateIncomingUser*/);
5115     }
5116
5117     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
5118             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5119             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
5120             boolean validateIncomingUser) {
5121         enforceNotIsolatedCaller("startActivity");
5122
5123         userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
5124                 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
5125
5126         // TODO: Switch to user app stacks here.
5127         return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
5128                 .setCaller(caller)
5129                 .setCallingPackage(callingPackage)
5130                 .setResolvedType(resolvedType)
5131                 .setResultTo(resultTo)
5132                 .setResultWho(resultWho)
5133                 .setRequestCode(requestCode)
5134                 .setStartFlags(startFlags)
5135                 .setProfilerInfo(profilerInfo)
5136                 .setActivityOptions(bOptions)
5137                 .setMayWait(userId)
5138                 .execute();
5139
5140     }
5141
5142     @Override
5143     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
5144             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5145             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
5146             int userId) {
5147
5148         // This is very dangerous -- it allows you to perform a start activity (including
5149         // permission grants) as any app that may launch one of your own activities.  So
5150         // we will only allow this to be done from activities that are part of the core framework,
5151         // and then only when they are running as the system.
5152         final ActivityRecord sourceRecord;
5153         final int targetUid;
5154         final String targetPackage;
5155         final boolean isResolver;
5156         synchronized (this) {
5157             if (resultTo == null) {
5158                 throw new SecurityException("Must be called from an activity");
5159             }
5160             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
5161             if (sourceRecord == null) {
5162                 throw new SecurityException("Called with bad activity token: " + resultTo);
5163             }
5164             if (!sourceRecord.info.packageName.equals("android")) {
5165                 throw new SecurityException(
5166                         "Must be called from an activity that is declared in the android package");
5167             }
5168             if (sourceRecord.app == null) {
5169                 throw new SecurityException("Called without a process attached to activity");
5170             }
5171             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
5172                 // This is still okay, as long as this activity is running under the
5173                 // uid of the original calling activity.
5174                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
5175                     throw new SecurityException(
5176                             "Calling activity in uid " + sourceRecord.app.uid
5177                                     + " must be system uid or original calling uid "
5178                                     + sourceRecord.launchedFromUid);
5179                 }
5180             }
5181             if (ignoreTargetSecurity) {
5182                 if (intent.getComponent() == null) {
5183                     throw new SecurityException(
5184                             "Component must be specified with ignoreTargetSecurity");
5185                 }
5186                 if (intent.getSelector() != null) {
5187                     throw new SecurityException(
5188                             "Selector not allowed with ignoreTargetSecurity");
5189                 }
5190             }
5191             targetUid = sourceRecord.launchedFromUid;
5192             targetPackage = sourceRecord.launchedFromPackage;
5193             isResolver = sourceRecord.isResolverOrChildActivity();
5194         }
5195
5196         if (userId == UserHandle.USER_NULL) {
5197             userId = UserHandle.getUserId(sourceRecord.app.uid);
5198         }
5199
5200         // TODO: Switch to user app stacks here.
5201         try {
5202             return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
5203                     .setCallingUid(targetUid)
5204                     .setCallingPackage(targetPackage)
5205                     .setResolvedType(resolvedType)
5206                     .setResultTo(resultTo)
5207                     .setResultWho(resultWho)
5208                     .setRequestCode(requestCode)
5209                     .setStartFlags(startFlags)
5210                     .setActivityOptions(bOptions)
5211                     .setMayWait(userId)
5212                     .setIgnoreTargetSecurity(ignoreTargetSecurity)
5213                     .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
5214                     .execute();
5215         } catch (SecurityException e) {
5216             // XXX need to figure out how to propagate to original app.
5217             // A SecurityException here is generally actually a fault of the original
5218             // calling activity (such as a fairly granting permissions), so propagate it
5219             // back to them.
5220             /*
5221             StringBuilder msg = new StringBuilder();
5222             msg.append("While launching");
5223             msg.append(intent.toString());
5224             msg.append(": ");
5225             msg.append(e.getMessage());
5226             */
5227             throw e;
5228         }
5229     }
5230
5231     @Override
5232     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
5233             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5234             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5235         enforceNotIsolatedCaller("startActivityAndWait");
5236         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5237                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
5238         WaitResult res = new WaitResult();
5239         // TODO: Switch to user app stacks here.
5240         mActivityStartController.obtainStarter(intent, "startActivityAndWait")
5241                 .setCaller(caller)
5242                 .setCallingPackage(callingPackage)
5243                 .setResolvedType(resolvedType)
5244                 .setResultTo(resultTo)
5245                 .setResultWho(resultWho)
5246                 .setRequestCode(requestCode)
5247                 .setStartFlags(startFlags)
5248                 .setActivityOptions(bOptions)
5249                 .setMayWait(userId)
5250                 .setProfilerInfo(profilerInfo)
5251                 .setWaitResult(res)
5252                 .execute();
5253         return res;
5254     }
5255
5256     @Override
5257     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
5258             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5259             int startFlags, Configuration config, Bundle bOptions, int userId) {
5260         enforceNotIsolatedCaller("startActivityWithConfig");
5261         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5262                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
5263         // TODO: Switch to user app stacks here.
5264         return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
5265                 .setCaller(caller)
5266                 .setCallingPackage(callingPackage)
5267                 .setResolvedType(resolvedType)
5268                 .setResultTo(resultTo)
5269                 .setResultWho(resultWho)
5270                 .setRequestCode(requestCode)
5271                 .setStartFlags(startFlags)
5272                 .setGlobalConfiguration(config)
5273                 .setActivityOptions(bOptions)
5274                 .setMayWait(userId)
5275                 .execute();
5276     }
5277
5278     @Override
5279     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
5280             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
5281             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
5282             throws TransactionTooLargeException {
5283         enforceNotIsolatedCaller("startActivityIntentSender");
5284         // Refuse possible leaked file descriptors
5285         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
5286             throw new IllegalArgumentException("File descriptors passed in Intent");
5287         }
5288
5289         if (!(target instanceof PendingIntentRecord)) {
5290             throw new IllegalArgumentException("Bad PendingIntent object");
5291         }
5292
5293         PendingIntentRecord pir = (PendingIntentRecord)target;
5294
5295         synchronized (this) {
5296             // If this is coming from the currently resumed activity, it is
5297             // effectively saying that app switches are allowed at this point.
5298             final ActivityStack stack = getFocusedStack();
5299             if (stack.mResumedActivity != null &&
5300                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
5301                 mAppSwitchesAllowedTime = 0;
5302             }
5303         }
5304         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
5305                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
5306         return ret;
5307     }
5308
5309     @Override
5310     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
5311             Intent intent, String resolvedType, IVoiceInteractionSession session,
5312             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
5313             Bundle bOptions, int userId) {
5314         enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
5315         if (session == null || interactor == null) {
5316             throw new NullPointerException("null session or interactor");
5317         }
5318         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5319                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
5320         // TODO: Switch to user app stacks here.
5321         return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
5322                 .setCallingUid(callingUid)
5323                 .setCallingPackage(callingPackage)
5324                 .setResolvedType(resolvedType)
5325                 .setVoiceSession(session)
5326                 .setVoiceInteractor(interactor)
5327                 .setStartFlags(startFlags)
5328                 .setProfilerInfo(profilerInfo)
5329                 .setActivityOptions(bOptions)
5330                 .setMayWait(userId)
5331                 .execute();
5332     }
5333
5334     @Override
5335     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
5336             Intent intent, String resolvedType, Bundle bOptions, int userId) {
5337         enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
5338         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5339                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
5340
5341         return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
5342                 .setCallingUid(callingUid)
5343                 .setCallingPackage(callingPackage)
5344                 .setResolvedType(resolvedType)
5345                 .setActivityOptions(bOptions)
5346                 .setMayWait(userId)
5347                 .execute();
5348     }
5349
5350     @Override
5351     public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
5352                 IRecentsAnimationRunner recentsAnimationRunner) {
5353         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
5354         final int callingPid = Binder.getCallingPid();
5355         final long origId = Binder.clearCallingIdentity();
5356         try {
5357             synchronized (this) {
5358                 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
5359                 final int recentsUid = mRecentTasks.getRecentsComponentUid();
5360
5361                 // Start a new recents animation
5362                 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
5363                         mActivityStartController, mWindowManager, mUserController, callingPid);
5364                 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
5365                         recentsUid, assistDataReceiver);
5366             }
5367         } finally {
5368             Binder.restoreCallingIdentity(origId);
5369         }
5370     }
5371
5372     @Override
5373     public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5374         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
5375         final long callingUid = Binder.getCallingUid();
5376         final long origId = Binder.clearCallingIdentity();
5377         try {
5378             synchronized (this) {
5379                 // Cancel the recents animation synchronously (do not hold the WM lock)
5380                 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
5381                         ? REORDER_MOVE_TO_ORIGINAL_POSITION
5382                         : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
5383             }
5384         } finally {
5385             Binder.restoreCallingIdentity(origId);
5386         }
5387     }
5388
5389     @Override
5390     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
5391             throws RemoteException {
5392         Slog.i(TAG, "Activity tried to startVoiceInteraction");
5393         synchronized (this) {
5394             ActivityRecord activity = getFocusedStack().getTopActivity();
5395             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
5396                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
5397             }
5398             if (mRunningVoice != null || activity.getTask().voiceSession != null
5399                     || activity.voiceSession != null) {
5400                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
5401                 return;
5402             }
5403             if (activity.pendingVoiceInteractionStart) {
5404                 Slog.w(TAG, "Pending start of voice interaction already.");
5405                 return;
5406             }
5407             activity.pendingVoiceInteractionStart = true;
5408         }
5409         LocalServices.getService(VoiceInteractionManagerInternal.class)
5410                 .startLocalVoiceInteraction(callingActivity, options);
5411     }
5412
5413     @Override
5414     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5415         LocalServices.getService(VoiceInteractionManagerInternal.class)
5416                 .stopLocalVoiceInteraction(callingActivity);
5417     }
5418
5419     @Override
5420     public boolean supportsLocalVoiceInteraction() throws RemoteException {
5421         return LocalServices.getService(VoiceInteractionManagerInternal.class)
5422                 .supportsLocalVoiceInteraction();
5423     }
5424
5425     @GuardedBy("this")
5426     void onLocalVoiceInteractionStartedLocked(IBinder activity,
5427             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5428         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
5429         if (activityToCallback == null) return;
5430         activityToCallback.setVoiceSessionLocked(voiceSession);
5431
5432         // Inform the activity
5433         try {
5434             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5435                     voiceInteractor);
5436             long token = Binder.clearCallingIdentity();
5437             try {
5438                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5439             } finally {
5440                 Binder.restoreCallingIdentity(token);
5441             }
5442             // TODO: VI Should we cache the activity so that it's easier to find later
5443             // rather than scan through all the stacks and activities?
5444         } catch (RemoteException re) {
5445             activityToCallback.clearVoiceSessionLocked();
5446             // TODO: VI Should this terminate the voice session?
5447         }
5448     }
5449
5450     @Override
5451     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5452         synchronized (this) {
5453             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5454                 if (keepAwake) {
5455                     mVoiceWakeLock.acquire();
5456                 } else {
5457                     mVoiceWakeLock.release();
5458                 }
5459             }
5460         }
5461     }
5462
5463     @Override
5464     public boolean startNextMatchingActivity(IBinder callingActivity,
5465             Intent intent, Bundle bOptions) {
5466         // Refuse possible leaked file descriptors
5467         if (intent != null && intent.hasFileDescriptors() == true) {
5468             throw new IllegalArgumentException("File descriptors passed in Intent");
5469         }
5470         SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5471
5472         synchronized (this) {
5473             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5474             if (r == null) {
5475                 SafeActivityOptions.abort(options);
5476                 return false;
5477             }
5478             if (r.app == null || r.app.thread == null) {
5479                 // The caller is not running...  d'oh!
5480                 SafeActivityOptions.abort(options);
5481                 return false;
5482             }
5483             intent = new Intent(intent);
5484             // The caller is not allowed to change the data.
5485             intent.setDataAndType(r.intent.getData(), r.intent.getType());
5486             // And we are resetting to find the next component...
5487             intent.setComponent(null);
5488
5489             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5490
5491             ActivityInfo aInfo = null;
5492             try {
5493                 List<ResolveInfo> resolves =
5494                     AppGlobals.getPackageManager().queryIntentActivities(
5495                             intent, r.resolvedType,
5496                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5497                             UserHandle.getCallingUserId()).getList();
5498
5499                 // Look for the original activity in the list...
5500                 final int N = resolves != null ? resolves.size() : 0;
5501                 for (int i=0; i<N; i++) {
5502                     ResolveInfo rInfo = resolves.get(i);
5503                     if (rInfo.activityInfo.packageName.equals(r.packageName)
5504                             && rInfo.activityInfo.name.equals(r.info.name)) {
5505                         // We found the current one...  the next matching is
5506                         // after it.
5507                         i++;
5508                         if (i<N) {
5509                             aInfo = resolves.get(i).activityInfo;
5510                         }
5511                         if (debug) {
5512                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
5513                                     + "/" + r.info.name);
5514                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5515                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
5516                         }
5517                         break;
5518                     }
5519                 }
5520             } catch (RemoteException e) {
5521             }
5522
5523             if (aInfo == null) {
5524                 // Nobody who is next!
5525                 SafeActivityOptions.abort(options);
5526                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5527                 return false;
5528             }
5529
5530             intent.setComponent(new ComponentName(
5531                     aInfo.applicationInfo.packageName, aInfo.name));
5532             intent.setFlags(intent.getFlags()&~(
5533                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5534                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
5535                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5536                     FLAG_ACTIVITY_NEW_TASK));
5537
5538             // Okay now we need to start the new activity, replacing the
5539             // currently running activity.  This is a little tricky because
5540             // we want to start the new one as if the current one is finished,
5541             // but not finish the current one first so that there is no flicker.
5542             // And thus...
5543             final boolean wasFinishing = r.finishing;
5544             r.finishing = true;
5545
5546             // Propagate reply information over to the new activity.
5547             final ActivityRecord resultTo = r.resultTo;
5548             final String resultWho = r.resultWho;
5549             final int requestCode = r.requestCode;
5550             r.resultTo = null;
5551             if (resultTo != null) {
5552                 resultTo.removeResultsLocked(r, resultWho, requestCode);
5553             }
5554
5555             final long origId = Binder.clearCallingIdentity();
5556             // TODO(b/64750076): Check if calling pid should really be -1.
5557             final int res = mActivityStartController
5558                     .obtainStarter(intent, "startNextMatchingActivity")
5559                     .setCaller(r.app.thread)
5560                     .setResolvedType(r.resolvedType)
5561                     .setActivityInfo(aInfo)
5562                     .setResultTo(resultTo != null ? resultTo.appToken : null)
5563                     .setResultWho(resultWho)
5564                     .setRequestCode(requestCode)
5565                     .setCallingPid(-1)
5566                     .setCallingUid(r.launchedFromUid)
5567                     .setCallingPackage(r.launchedFromPackage)
5568                     .setRealCallingPid(-1)
5569                     .setRealCallingUid(r.launchedFromUid)
5570                     .setActivityOptions(options)
5571                     .execute();
5572             Binder.restoreCallingIdentity(origId);
5573
5574             r.finishing = wasFinishing;
5575             if (res != ActivityManager.START_SUCCESS) {
5576                 return false;
5577             }
5578             return true;
5579         }
5580     }
5581
5582     @Override
5583     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5584         enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5585                 "startActivityFromRecents()");
5586
5587         final int callingPid = Binder.getCallingPid();
5588         final int callingUid = Binder.getCallingUid();
5589         final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
5590         final long origId = Binder.clearCallingIdentity();
5591         try {
5592             synchronized (this) {
5593                 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5594                         safeOptions);
5595             }
5596         } finally {
5597             Binder.restoreCallingIdentity(origId);
5598         }
5599     }
5600
5601     @Override
5602     public final int startActivities(IApplicationThread caller, String callingPackage,
5603             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5604             int userId) {
5605         final String reason = "startActivities";
5606         enforceNotIsolatedCaller(reason);
5607         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5608                 userId, false, ALLOW_FULL_ONLY, reason, null);
5609         // TODO: Switch to user app stacks here.
5610         int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
5611                 intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
5612                 reason, null /* originatingPendingIntent */);
5613         return ret;
5614     }
5615
5616     @Override
5617     public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5618         synchronized (this) {
5619             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5620             if (r == null) {
5621                 return;
5622             }
5623             r.reportFullyDrawnLocked(restoredFromBundle);
5624         }
5625     }
5626
5627     @Override
5628     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5629         synchronized (this) {
5630             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5631             if (r == null) {
5632                 return;
5633             }
5634             final long origId = Binder.clearCallingIdentity();
5635             try {
5636                 r.setRequestedOrientation(requestedOrientation);
5637             } finally {
5638                 Binder.restoreCallingIdentity(origId);
5639             }
5640         }
5641     }
5642
5643     @Override
5644     public int getRequestedOrientation(IBinder token) {
5645         synchronized (this) {
5646             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5647             if (r == null) {
5648                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5649             }
5650             return r.getRequestedOrientation();
5651         }
5652     }
5653
5654     /**
5655      * This is the internal entry point for handling Activity.finish().
5656      *
5657      * @param token The Binder token referencing the Activity we want to finish.
5658      * @param resultCode Result code, if any, from this Activity.
5659      * @param resultData Result data (Intent), if any, from this Activity.
5660      * @param finishTask Whether to finish the task associated with this Activity.
5661      *
5662      * @return Returns true if the activity successfully finished, or false if it is still running.
5663      */
5664     @Override
5665     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5666             int finishTask) {
5667         // Refuse possible leaked file descriptors
5668         if (resultData != null && resultData.hasFileDescriptors() == true) {
5669             throw new IllegalArgumentException("File descriptors passed in Intent");
5670         }
5671
5672         synchronized(this) {
5673             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5674             if (r == null) {
5675                 return true;
5676             }
5677             // Keep track of the root activity of the task before we finish it
5678             TaskRecord tr = r.getTask();
5679             ActivityRecord rootR = tr.getRootActivity();
5680             if (rootR == null) {
5681                 Slog.w(TAG, "Finishing task with all activities already finished");
5682             }
5683             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5684             // finish.
5685             if (mLockTaskController.activityBlockedFromFinish(r)) {
5686                 return false;
5687             }
5688
5689             if (mController != null) {
5690                 // Find the first activity that is not finishing.
5691                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5692                 if (next != null) {
5693                     // ask watcher if this is allowed
5694                     boolean resumeOK = true;
5695                     try {
5696                         resumeOK = mController.activityResuming(next.packageName);
5697                     } catch (RemoteException e) {
5698                         mController = null;
5699                         Watchdog.getInstance().setActivityController(null);
5700                     }
5701
5702                     if (!resumeOK) {
5703                         Slog.i(TAG, "Not finishing activity because controller resumed");
5704                         return false;
5705                     }
5706                 }
5707             }
5708             final long origId = Binder.clearCallingIdentity();
5709             try {
5710                 boolean res;
5711                 final boolean finishWithRootActivity =
5712                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5713                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5714                         || (finishWithRootActivity && r == rootR)) {
5715                     // If requested, remove the task that is associated to this activity only if it
5716                     // was the root activity in the task. The result code and data is ignored
5717                     // because we don't support returning them across task boundaries. Also, to
5718                     // keep backwards compatibility we remove the task from recents when finishing
5719                     // task with root activity.
5720                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5721                             finishWithRootActivity, "finish-activity");
5722                     if (!res) {
5723                         Slog.i(TAG, "Removing task failed to finish activity");
5724                     }
5725                 } else {
5726                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5727                             resultData, "app-request", true);
5728                     if (!res) {
5729                         Slog.i(TAG, "Failed to finish by app-request");
5730                     }
5731                 }
5732                 return res;
5733             } finally {
5734                 Binder.restoreCallingIdentity(origId);
5735             }
5736         }
5737     }
5738
5739     @Override
5740     public final void finishHeavyWeightApp() {
5741         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5742                 != PackageManager.PERMISSION_GRANTED) {
5743             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5744                     + Binder.getCallingPid()
5745                     + ", uid=" + Binder.getCallingUid()
5746                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5747             Slog.w(TAG, msg);
5748             throw new SecurityException(msg);
5749         }
5750
5751         synchronized(this) {
5752             final ProcessRecord proc = mHeavyWeightProcess;
5753             if (proc == null) {
5754                 return;
5755             }
5756
5757             ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5758             for (int i = 0; i < activities.size(); i++) {
5759                 ActivityRecord r = activities.get(i);
5760                 if (!r.finishing && r.isInStackLocked()) {
5761                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5762                             null, "finish-heavy", true);
5763                 }
5764             }
5765
5766             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5767                     proc.userId, 0));
5768             mHeavyWeightProcess = null;
5769         }
5770     }
5771
5772     @Override
5773     public void crashApplication(int uid, int initialPid, String packageName, int userId,
5774             String message) {
5775         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5776                 != PackageManager.PERMISSION_GRANTED) {
5777             String msg = "Permission Denial: crashApplication() from pid="
5778                     + Binder.getCallingPid()
5779                     + ", uid=" + Binder.getCallingUid()
5780                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5781             Slog.w(TAG, msg);
5782             throw new SecurityException(msg);
5783         }
5784
5785         synchronized(this) {
5786             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5787         }
5788     }
5789
5790     @Override
5791     public final void finishSubActivity(IBinder token, String resultWho,
5792             int requestCode) {
5793         synchronized(this) {
5794             final long origId = Binder.clearCallingIdentity();
5795             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5796             if (r != null) {
5797                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5798             }
5799             Binder.restoreCallingIdentity(origId);
5800         }
5801     }
5802
5803     @Override
5804     public boolean finishActivityAffinity(IBinder token) {
5805         synchronized(this) {
5806             final long origId = Binder.clearCallingIdentity();
5807             try {
5808                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5809                 if (r == null) {
5810                     return false;
5811                 }
5812
5813                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5814                 // can finish.
5815                 final TaskRecord task = r.getTask();
5816                 if (mLockTaskController.activityBlockedFromFinish(r)) {
5817                     return false;
5818                 }
5819                 return task.getStack().finishActivityAffinityLocked(r);
5820             } finally {
5821                 Binder.restoreCallingIdentity(origId);
5822             }
5823         }
5824     }
5825
5826     @Override
5827     public void finishVoiceTask(IVoiceInteractionSession session) {
5828         synchronized (this) {
5829             final long origId = Binder.clearCallingIdentity();
5830             try {
5831                 // TODO: VI Consider treating local voice interactions and voice tasks
5832                 // differently here
5833                 mStackSupervisor.finishVoiceTask(session);
5834             } finally {
5835                 Binder.restoreCallingIdentity(origId);
5836             }
5837         }
5838
5839     }
5840
5841     @Override
5842     public boolean releaseActivityInstance(IBinder token) {
5843         synchronized(this) {
5844             final long origId = Binder.clearCallingIdentity();
5845             try {
5846                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5847                 if (r == null) {
5848                     return false;
5849                 }
5850                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5851             } finally {
5852                 Binder.restoreCallingIdentity(origId);
5853             }
5854         }
5855     }
5856
5857     @Override
5858     public void releaseSomeActivities(IApplicationThread appInt) {
5859         synchronized(this) {
5860             final long origId = Binder.clearCallingIdentity();
5861             try {
5862                 ProcessRecord app = getRecordForAppLocked(appInt);
5863                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5864             } finally {
5865                 Binder.restoreCallingIdentity(origId);
5866             }
5867         }
5868     }
5869
5870     @Override
5871     public boolean willActivityBeVisible(IBinder token) {
5872         synchronized(this) {
5873             ActivityStack stack = ActivityRecord.getStackLocked(token);
5874             if (stack != null) {
5875                 return stack.willActivityBeVisibleLocked(token);
5876             }
5877             return false;
5878         }
5879     }
5880
5881     @Override
5882     public void overridePendingTransition(IBinder token, String packageName,
5883             int enterAnim, int exitAnim) {
5884         synchronized(this) {
5885             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5886             if (self == null) {
5887                 return;
5888             }
5889
5890             final long origId = Binder.clearCallingIdentity();
5891
5892             if (self.isState(ActivityState.RESUMED, ActivityState.PAUSING)) {
5893                 mWindowManager.overridePendingAppTransition(packageName,
5894                         enterAnim, exitAnim, null);
5895             }
5896
5897             Binder.restoreCallingIdentity(origId);
5898         }
5899     }
5900
5901     /**
5902      * Main function for removing an existing process from the activity manager
5903      * as a result of that process going away.  Clears out all connections
5904      * to the process.
5905      */
5906     @GuardedBy("this")
5907     private final void handleAppDiedLocked(ProcessRecord app,
5908             boolean restarting, boolean allowRestart) {
5909         int pid = app.pid;
5910         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5911                 false /*replacingPid*/);
5912         if (!kept && !restarting) {
5913             removeLruProcessLocked(app);
5914             if (pid > 0) {
5915                 ProcessList.remove(pid);
5916             }
5917         }
5918
5919         if (mProfileProc == app) {
5920             clearProfilerLocked();
5921         }
5922
5923         // Remove this application's activities from active lists.
5924         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5925
5926         app.clearRecentTasks();
5927
5928         app.activities.clear();
5929
5930         if (app.instr != null) {
5931             Slog.w(TAG, "Crash of app " + app.processName
5932                   + " running instrumentation " + app.instr.mClass);
5933             Bundle info = new Bundle();
5934             info.putString("shortMsg", "Process crashed.");
5935             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5936         }
5937
5938         mWindowManager.deferSurfaceLayout();
5939         try {
5940             if (!restarting && hasVisibleActivities
5941                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5942                 // If there was nothing to resume, and we are not already restarting this process, but
5943                 // there is a visible activity that is hosted by the process...  then make sure all
5944                 // visible activities are running, taking care of restarting this process.
5945                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5946             }
5947         } finally {
5948             mWindowManager.continueSurfaceLayout();
5949         }
5950
5951     }
5952
5953     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5954         final IBinder threadBinder = thread.asBinder();
5955         // Find the application record.
5956         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5957             final ProcessRecord rec = mLruProcesses.get(i);
5958             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5959                 return i;
5960             }
5961         }
5962         return -1;
5963     }
5964
5965     ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5966         if (thread == null) {
5967             return null;
5968         }
5969
5970         int appIndex = getLRURecordIndexForAppLocked(thread);
5971         if (appIndex >= 0) {
5972             return mLruProcesses.get(appIndex);
5973         }
5974
5975         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5976         // double-check that.
5977         final IBinder threadBinder = thread.asBinder();
5978         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5979         for (int i = pmap.size()-1; i >= 0; i--) {
5980             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5981             for (int j = procs.size()-1; j >= 0; j--) {
5982                 final ProcessRecord proc = procs.valueAt(j);
5983                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5984                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5985                             + proc);
5986                     return proc;
5987                 }
5988             }
5989         }
5990
5991         return null;
5992     }
5993
5994     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5995         // If there are no longer any background processes running,
5996         // and the app that died was not running instrumentation,
5997         // then tell everyone we are now low on memory.
5998         boolean haveBg = false;
5999         for (int i=mLruProcesses.size()-1; i>=0; i--) {
6000             ProcessRecord rec = mLruProcesses.get(i);
6001             if (rec.thread != null
6002                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
6003                 haveBg = true;
6004                 break;
6005             }
6006         }
6007
6008         if (!haveBg) {
6009             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6010             if (doReport) {
6011                 long now = SystemClock.uptimeMillis();
6012                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
6013                     doReport = false;
6014                 } else {
6015                     mLastMemUsageReportTime = now;
6016                 }
6017             }
6018             final ArrayList<ProcessMemInfo> memInfos
6019                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
6020             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
6021             long now = SystemClock.uptimeMillis();
6022             for (int i=mLruProcesses.size()-1; i>=0; i--) {
6023                 ProcessRecord rec = mLruProcesses.get(i);
6024                 if (rec == dyingProc || rec.thread == null) {
6025                     continue;
6026                 }
6027                 if (doReport) {
6028                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
6029                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
6030                 }
6031                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
6032                     // The low memory report is overriding any current
6033                     // state for a GC request.  Make sure to do
6034                     // heavy/important/visible/foreground processes first.
6035                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
6036                         rec.lastRequestedGc = 0;
6037                     } else {
6038                         rec.lastRequestedGc = rec.lastLowMemory;
6039                     }
6040                     rec.reportLowMemory = true;
6041                     rec.lastLowMemory = now;
6042                     mProcessesToGc.remove(rec);
6043                     addProcessToGcListLocked(rec);
6044                 }
6045             }
6046             if (doReport) {
6047                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
6048                 mHandler.sendMessage(msg);
6049             }
6050             scheduleAppGcsLocked();
6051         }
6052     }
6053
6054     @GuardedBy("this")
6055     final void appDiedLocked(ProcessRecord app) {
6056        appDiedLocked(app, app.pid, app.thread, false);
6057     }
6058
6059     @GuardedBy("this")
6060     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
6061             boolean fromBinderDied) {
6062         // First check if this ProcessRecord is actually active for the pid.
6063         synchronized (mPidsSelfLocked) {
6064             ProcessRecord curProc = mPidsSelfLocked.get(pid);
6065             if (curProc != app) {
6066                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
6067                 return;
6068             }
6069         }
6070
6071         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6072         synchronized (stats) {
6073             stats.noteProcessDiedLocked(app.info.uid, pid);
6074         }
6075
6076         if (!app.killed) {
6077             if (!fromBinderDied) {
6078                 killProcessQuiet(pid);
6079             }
6080             killProcessGroup(app.uid, pid);
6081             app.killed = true;
6082         }
6083
6084         // Clean up already done if the process has been re-started.
6085         if (app.pid == pid && app.thread != null &&
6086                 app.thread.asBinder() == thread.asBinder()) {
6087             boolean doLowMem = app.instr == null;
6088             boolean doOomAdj = doLowMem;
6089             if (!app.killedByAm) {
6090                 reportUidInfoMessageLocked(TAG,
6091                         "Process " + app.processName + " (pid " + pid + ") has died: "
6092                                 + ProcessList.makeOomAdjString(app.setAdj)
6093                                 + ProcessList.makeProcStateString(app.setProcState), app.info.uid);
6094                 mAllowLowerMemLevel = true;
6095             } else {
6096                 // Note that we always want to do oom adj to update our state with the
6097                 // new number of procs.
6098                 mAllowLowerMemLevel = false;
6099                 doLowMem = false;
6100             }
6101             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
6102                     app.setAdj, app.setProcState);
6103             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
6104                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
6105             handleAppDiedLocked(app, false, true);
6106
6107             if (doOomAdj) {
6108                 updateOomAdjLocked();
6109             }
6110             if (doLowMem) {
6111                 doLowMemReportIfNeededLocked(app);
6112             }
6113         } else if (app.pid != pid) {
6114             // A new process has already been started.
6115             reportUidInfoMessageLocked(TAG,
6116                     "Process " + app.processName + " (pid " + pid
6117                             + ") has died and restarted (pid " + app.pid + ").", app.info.uid);
6118             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
6119         } else if (DEBUG_PROCESSES) {
6120             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
6121                     + thread.asBinder());
6122         }
6123
6124         // On the device which doesn't have Cgroup, log LmkStateChanged which is used as a signal
6125         // for pulling memory stats of other running processes when this process died.
6126         if (!hasMemcg()) {
6127             StatsLog.write(StatsLog.APP_DIED, SystemClock.elapsedRealtime());
6128         }
6129     }
6130
6131     /**
6132      * If a stack trace dump file is configured, dump process stack traces.
6133      * @param clearTraces causes the dump file to be erased prior to the new
6134      *    traces being written, if true; when false, the new traces will be
6135      *    appended to any existing file content.
6136      * @param firstPids of dalvik VM processes to dump stack traces for first
6137      * @param lastPids of dalvik VM processes to dump stack traces for last
6138      * @param nativePids optional list of native pids to dump stack crawls
6139      */
6140     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
6141             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
6142             ArrayList<Integer> nativePids) {
6143         ArrayList<Integer> extraPids = null;
6144
6145         // Measure CPU usage as soon as we're called in order to get a realistic sampling
6146         // of the top users at the time of the request.
6147         if (processCpuTracker != null) {
6148             processCpuTracker.init();
6149             try {
6150                 Thread.sleep(200);
6151             } catch (InterruptedException ignored) {
6152             }
6153
6154             processCpuTracker.update();
6155
6156             // We'll take the stack crawls of just the top apps using CPU.
6157             final int N = processCpuTracker.countWorkingStats();
6158             extraPids = new ArrayList<>();
6159             for (int i = 0; i < N && extraPids.size() < 5; i++) {
6160                 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
6161                 if (lastPids.indexOfKey(stats.pid) >= 0) {
6162                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
6163
6164                     extraPids.add(stats.pid);
6165                 } else if (DEBUG_ANR) {
6166                     Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
6167                             + stats.pid);
6168                 }
6169             }
6170         }
6171
6172         boolean useTombstonedForJavaTraces = false;
6173         File tracesFile;
6174
6175         final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
6176         if (tracesDirProp.isEmpty()) {
6177             // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
6178             // dumping scheme. All traces are written to a global trace file (usually
6179             // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
6180             // the file if requested.
6181             //
6182             // This mode of operation will be removed in the near future.
6183
6184
6185             String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6186             if (globalTracesPath.isEmpty()) {
6187                 Slog.w(TAG, "dumpStackTraces: no trace path configured");
6188                 return null;
6189             }
6190
6191             tracesFile = new File(globalTracesPath);
6192             try {
6193                 if (clearTraces && tracesFile.exists()) {
6194                     tracesFile.delete();
6195                 }
6196
6197                 tracesFile.createNewFile();
6198                 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
6199             } catch (IOException e) {
6200                 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
6201                 return null;
6202             }
6203         } else {
6204             File tracesDir = new File(tracesDirProp);
6205             // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
6206             // Each set of ANR traces is written to a separate file and dumpstate will process
6207             // all such files and add them to a captured bug report if they're recent enough.
6208             maybePruneOldTraces(tracesDir);
6209
6210             // NOTE: We should consider creating the file in native code atomically once we've
6211             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
6212             // can be removed.
6213             tracesFile = createAnrDumpFile(tracesDir);
6214             if (tracesFile == null) {
6215                 return null;
6216             }
6217
6218             useTombstonedForJavaTraces = true;
6219         }
6220
6221         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
6222                 useTombstonedForJavaTraces);
6223         return tracesFile;
6224     }
6225
6226     @GuardedBy("ActivityManagerService.class")
6227     private static SimpleDateFormat sAnrFileDateFormat;
6228
6229     private static synchronized File createAnrDumpFile(File tracesDir) {
6230         if (sAnrFileDateFormat == null) {
6231             sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
6232         }
6233
6234         final String formattedDate = sAnrFileDateFormat.format(new Date());
6235         final File anrFile = new File(tracesDir, "anr_" + formattedDate);
6236
6237         try {
6238             if (anrFile.createNewFile()) {
6239                 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
6240                 return anrFile;
6241             } else {
6242                 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
6243             }
6244         } catch (IOException ioe) {
6245             Slog.w(TAG, "Exception creating ANR dump file:", ioe);
6246         }
6247
6248         return null;
6249     }
6250
6251     /**
6252      * Prune all trace files that are more than a day old.
6253      *
6254      * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
6255      * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
6256      * since it's the system_server that creates trace files for most ANRs.
6257      */
6258     private static void maybePruneOldTraces(File tracesDir) {
6259         final long now = System.currentTimeMillis();
6260         final File[] traceFiles = tracesDir.listFiles();
6261
6262         if (traceFiles != null) {
6263             for (File file : traceFiles) {
6264                 if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
6265                     if (!file.delete()) {
6266                         Slog.w(TAG, "Unable to prune stale trace file: " + file);
6267                     }
6268                 }
6269             }
6270         }
6271     }
6272
6273     /**
6274      * Legacy code, do not use. Existing users will be deleted.
6275      *
6276      * @deprecated
6277      */
6278     @Deprecated
6279     public static class DumpStackFileObserver extends FileObserver {
6280         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
6281         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
6282
6283         private final String mTracesPath;
6284         private boolean mClosed;
6285
6286         public DumpStackFileObserver(String tracesPath) {
6287             super(tracesPath, FileObserver.CLOSE_WRITE);
6288             mTracesPath = tracesPath;
6289         }
6290
6291         @Override
6292         public synchronized void onEvent(int event, String path) {
6293             mClosed = true;
6294             notify();
6295         }
6296
6297         public long dumpWithTimeout(int pid, long timeout) {
6298             sendSignal(pid, SIGNAL_QUIT);
6299             final long start = SystemClock.elapsedRealtime();
6300
6301             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
6302             synchronized (this) {
6303                 try {
6304                     wait(waitTime); // Wait for traces file to be closed.
6305                 } catch (InterruptedException e) {
6306                     Slog.wtf(TAG, e);
6307                 }
6308             }
6309
6310             // This avoids a corner case of passing a negative time to the native
6311             // trace in case we've already hit the overall timeout.
6312             final long timeWaited = SystemClock.elapsedRealtime() - start;
6313             if (timeWaited >= timeout) {
6314                 return timeWaited;
6315             }
6316
6317             if (!mClosed) {
6318                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
6319                        ". Attempting native stack collection.");
6320
6321                 final long nativeDumpTimeoutMs = Math.min(
6322                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
6323
6324                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
6325                         (int) (nativeDumpTimeoutMs / 1000));
6326             }
6327
6328             final long end = SystemClock.elapsedRealtime();
6329             mClosed = false;
6330
6331             return (end - start);
6332         }
6333     }
6334
6335     /**
6336      * Dump java traces for process {@code pid} to the specified file. If java trace dumping
6337      * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
6338      * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
6339      * attempting to obtain native traces in the case of a failure. Returns the total time spent
6340      * capturing traces.
6341      */
6342     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
6343         final long timeStart = SystemClock.elapsedRealtime();
6344         if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
6345             Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
6346                     (NATIVE_DUMP_TIMEOUT_MS / 1000));
6347         }
6348
6349         return SystemClock.elapsedRealtime() - timeStart;
6350     }
6351
6352     private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6353             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6354             boolean useTombstonedForJavaTraces) {
6355
6356         // We don't need any sort of inotify based monitoring when we're dumping traces via
6357         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
6358         // control of all writes to the file in question.
6359         final DumpStackFileObserver observer;
6360         if (useTombstonedForJavaTraces) {
6361             observer = null;
6362         } else {
6363             // Use a FileObserver to detect when traces finish writing.
6364             // The order of traces is considered important to maintain for legibility.
6365             observer = new DumpStackFileObserver(tracesFile);
6366         }
6367
6368         // We must complete all stack dumps within 20 seconds.
6369         long remainingTime = 20 * 1000;
6370         try {
6371             if (observer != null) {
6372                 observer.startWatching();
6373             }
6374
6375             // First collect all of the stacks of the most important pids.
6376             if (firstPids != null) {
6377                 int num = firstPids.size();
6378                 for (int i = 0; i < num; i++) {
6379                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
6380                             + firstPids.get(i));
6381                     final long timeTaken;
6382                     if (useTombstonedForJavaTraces) {
6383                         timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
6384                     } else {
6385                         timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6386                     }
6387
6388                     remainingTime -= timeTaken;
6389                     if (remainingTime <= 0) {
6390                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6391                             "); deadline exceeded.");
6392                         return;
6393                     }
6394
6395                     if (DEBUG_ANR) {
6396                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
6397                     }
6398                 }
6399             }
6400
6401             // Next collect the stacks of the native pids
6402             if (nativePids != null) {
6403                 for (int pid : nativePids) {
6404                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
6405                     final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
6406
6407                     final long start = SystemClock.elapsedRealtime();
6408                     Debug.dumpNativeBacktraceToFileTimeout(
6409                             pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6410                     final long timeTaken = SystemClock.elapsedRealtime() - start;
6411
6412                     remainingTime -= timeTaken;
6413                     if (remainingTime <= 0) {
6414                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6415                             "); deadline exceeded.");
6416                         return;
6417                     }
6418
6419                     if (DEBUG_ANR) {
6420                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
6421                     }
6422                 }
6423             }
6424
6425             // Lastly, dump stacks for all extra PIDs from the CPU tracker.
6426             if (extraPids != null) {
6427                 for (int pid : extraPids) {
6428                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6429
6430                     final long timeTaken;
6431                     if (useTombstonedForJavaTraces) {
6432                         timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6433                     } else {
6434                         timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6435                     }
6436
6437                     remainingTime -= timeTaken;
6438                     if (remainingTime <= 0) {
6439                         Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6440                                 "); deadline exceeded.");
6441                         return;
6442                     }
6443
6444                     if (DEBUG_ANR) {
6445                         Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6446                     }
6447                 }
6448             }
6449         } finally {
6450             if (observer != null) {
6451                 observer.stopWatching();
6452             }
6453         }
6454     }
6455
6456     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6457         if (true || Build.IS_USER) {
6458             return;
6459         }
6460         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6461         if (tracesPath == null || tracesPath.length() == 0) {
6462             return;
6463         }
6464
6465         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6466         StrictMode.allowThreadDiskWrites();
6467         try {
6468             final File tracesFile = new File(tracesPath);
6469             final File tracesDir = tracesFile.getParentFile();
6470             final File tracesTmp = new File(tracesDir, "__tmp__");
6471             try {
6472                 if (tracesFile.exists()) {
6473                     tracesTmp.delete();
6474                     tracesFile.renameTo(tracesTmp);
6475                 }
6476                 StringBuilder sb = new StringBuilder();
6477                 Time tobj = new Time();
6478                 tobj.set(System.currentTimeMillis());
6479                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6480                 sb.append(": ");
6481                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6482                 sb.append(" since ");
6483                 sb.append(msg);
6484                 FileOutputStream fos = new FileOutputStream(tracesFile);
6485                 fos.write(sb.toString().getBytes());
6486                 if (app == null) {
6487                     fos.write("\n*** No application process!".getBytes());
6488                 }
6489                 fos.close();
6490                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6491             } catch (IOException e) {
6492                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6493                 return;
6494             }
6495
6496             if (app != null && app.pid > 0) {
6497                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
6498                 firstPids.add(app.pid);
6499                 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6500             }
6501
6502             File lastTracesFile = null;
6503             File curTracesFile = null;
6504             for (int i=9; i>=0; i--) {
6505                 String name = String.format(Locale.US, "slow%02d.txt", i);
6506                 curTracesFile = new File(tracesDir, name);
6507                 if (curTracesFile.exists()) {
6508                     if (lastTracesFile != null) {
6509                         curTracesFile.renameTo(lastTracesFile);
6510                     } else {
6511                         curTracesFile.delete();
6512                     }
6513                 }
6514                 lastTracesFile = curTracesFile;
6515             }
6516             tracesFile.renameTo(curTracesFile);
6517             if (tracesTmp.exists()) {
6518                 tracesTmp.renameTo(tracesFile);
6519             }
6520         } finally {
6521             StrictMode.setThreadPolicy(oldPolicy);
6522         }
6523     }
6524
6525     @GuardedBy("this")
6526     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6527         if (!mLaunchWarningShown) {
6528             mLaunchWarningShown = true;
6529             mUiHandler.post(new Runnable() {
6530                 @Override
6531                 public void run() {
6532                     synchronized (ActivityManagerService.this) {
6533                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6534                         d.show();
6535                         mUiHandler.postDelayed(new Runnable() {
6536                             @Override
6537                             public void run() {
6538                                 synchronized (ActivityManagerService.this) {
6539                                     d.dismiss();
6540                                     mLaunchWarningShown = false;
6541                                 }
6542                             }
6543                         }, 4000);
6544                     }
6545                 }
6546             });
6547         }
6548     }
6549
6550     @Override
6551     public boolean clearApplicationUserData(final String packageName, boolean keepState,
6552             final IPackageDataObserver observer, int userId) {
6553         enforceNotIsolatedCaller("clearApplicationUserData");
6554         int uid = Binder.getCallingUid();
6555         int pid = Binder.getCallingPid();
6556         final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6557                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6558
6559         final ApplicationInfo appInfo;
6560         final boolean isInstantApp;
6561
6562         long callingId = Binder.clearCallingIdentity();
6563         try {
6564             IPackageManager pm = AppGlobals.getPackageManager();
6565             synchronized(this) {
6566                 // Instant packages are not protected
6567                 if (getPackageManagerInternalLocked().isPackageDataProtected(
6568                         resolvedUserId, packageName)) {
6569                     throw new SecurityException(
6570                             "Cannot clear data for a protected package: " + packageName);
6571                 }
6572
6573                 ApplicationInfo applicationInfo = null;
6574                 try {
6575                     applicationInfo = pm.getApplicationInfo(packageName,
6576                             MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6577                 } catch (RemoteException e) {
6578                     /* ignore */
6579                 }
6580                 appInfo = applicationInfo;
6581
6582                 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6583
6584                 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6585                         pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6586                     throw new SecurityException("PID " + pid + " does not have permission "
6587                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6588                             + " of package " + packageName);
6589                 }
6590
6591                 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6592                         .hasInstantApplicationMetadata(packageName, resolvedUserId);
6593                 final boolean isUninstalledAppWithoutInstantMetadata =
6594                         (appInfo == null && !hasInstantMetadata);
6595                 isInstantApp = (appInfo != null && appInfo.isInstantApp())
6596                         || hasInstantMetadata;
6597                 final boolean canAccessInstantApps = checkComponentPermission(
6598                         permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6599                         == PackageManager.PERMISSION_GRANTED;
6600
6601                 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6602                         && !canAccessInstantApps)) {
6603                     Slog.w(TAG, "Invalid packageName: " + packageName);
6604                     if (observer != null) {
6605                         try {
6606                             observer.onRemoveCompleted(packageName, false);
6607                         } catch (RemoteException e) {
6608                             Slog.i(TAG, "Observer no longer exists.");
6609                         }
6610                     }
6611                     return false;
6612                 }
6613
6614                 if (appInfo != null) {
6615                     forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6616                     mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6617                 }
6618             }
6619
6620             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6621                 @Override
6622                 public void onRemoveCompleted(String packageName, boolean succeeded)
6623                         throws RemoteException {
6624                     if (appInfo != null) {
6625                         synchronized (ActivityManagerService.this) {
6626                             finishForceStopPackageLocked(packageName, appInfo.uid);
6627                         }
6628                     }
6629                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6630                             Uri.fromParts("package", packageName, null));
6631                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6632                     intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6633                     intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6634                     if (isInstantApp) {
6635                         intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6636                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6637                                 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6638                                 resolvedUserId);
6639                     } else {
6640                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6641                                 null, null, null, null, false, false, resolvedUserId);
6642                     }
6643
6644                     if (observer != null) {
6645                         observer.onRemoveCompleted(packageName, succeeded);
6646                     }
6647                 }
6648             };
6649
6650             try {
6651                 // Clear application user data
6652                 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6653
6654                 if (appInfo != null) {
6655                     // Restore already established notification state and permission grants,
6656                     // so it told us to keep those intact -- it's about to emplace app data
6657                     // that is appropriate for those bits of system state.
6658                     if (!keepState) {
6659                         synchronized (this) {
6660                             // Remove all permissions granted from/to this package
6661                             removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
6662                                     false);
6663                         }
6664
6665                         // Reset notification state
6666                         INotificationManager inm = NotificationManager.getService();
6667                         inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6668                     }
6669
6670                     // Clear its scheduled jobs
6671                     JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6672                     js.cancelJobsForUid(appInfo.uid, "clear data");
6673
6674                     // Clear its pending alarms
6675                     AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6676                     ami.removeAlarmsForUid(appInfo.uid);
6677                 }
6678             } catch (RemoteException e) {
6679             }
6680         } finally {
6681             Binder.restoreCallingIdentity(callingId);
6682         }
6683         return true;
6684     }
6685
6686     @Override
6687     public void killBackgroundProcesses(final String packageName, int userId) {
6688         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6689                 != PackageManager.PERMISSION_GRANTED &&
6690                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6691                         != PackageManager.PERMISSION_GRANTED) {
6692             String msg = "Permission Denial: killBackgroundProcesses() from pid="
6693                     + Binder.getCallingPid()
6694                     + ", uid=" + Binder.getCallingUid()
6695                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6696             Slog.w(TAG, msg);
6697             throw new SecurityException(msg);
6698         }
6699
6700         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6701                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6702         final int[] userIds = mUserController.expandUserId(userId);
6703
6704         long callingId = Binder.clearCallingIdentity();
6705         try {
6706             IPackageManager pm = AppGlobals.getPackageManager();
6707             for (int targetUserId : userIds) {
6708                 int appId = -1;
6709                 try {
6710                     appId = UserHandle.getAppId(
6711                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6712                                     targetUserId));
6713                 } catch (RemoteException e) {
6714                 }
6715                 if (appId == -1) {
6716                     Slog.w(TAG, "Invalid packageName: " + packageName);
6717                     return;
6718                 }
6719                 synchronized (this) {
6720                     killPackageProcessesLocked(packageName, appId, targetUserId,
6721                             ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6722                 }
6723             }
6724         } finally {
6725             Binder.restoreCallingIdentity(callingId);
6726         }
6727     }
6728
6729     @Override
6730     public void killAllBackgroundProcesses() {
6731         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6732                 != PackageManager.PERMISSION_GRANTED) {
6733             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6734                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6735                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6736             Slog.w(TAG, msg);
6737             throw new SecurityException(msg);
6738         }
6739
6740         final long callingId = Binder.clearCallingIdentity();
6741         try {
6742             synchronized (this) {
6743                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6744                 final int NP = mProcessNames.getMap().size();
6745                 for (int ip = 0; ip < NP; ip++) {
6746                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6747                     final int NA = apps.size();
6748                     for (int ia = 0; ia < NA; ia++) {
6749                         final ProcessRecord app = apps.valueAt(ia);
6750                         if (app.persistent) {
6751                             // We don't kill persistent processes.
6752                             continue;
6753                         }
6754                         if (app.removed) {
6755                             procs.add(app);
6756                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6757                             app.removed = true;
6758                             procs.add(app);
6759                         }
6760                     }
6761                 }
6762
6763                 final int N = procs.size();
6764                 for (int i = 0; i < N; i++) {
6765                     removeProcessLocked(procs.get(i), false, true, "kill all background");
6766                 }
6767
6768                 mAllowLowerMemLevel = true;
6769
6770                 updateOomAdjLocked();
6771                 doLowMemReportIfNeededLocked(null);
6772             }
6773         } finally {
6774             Binder.restoreCallingIdentity(callingId);
6775         }
6776     }
6777
6778     /**
6779      * Kills all background processes, except those matching any of the
6780      * specified properties.
6781      *
6782      * @param minTargetSdk the target SDK version at or above which to preserve
6783      *                     processes, or {@code -1} to ignore the target SDK
6784      * @param maxProcState the process state at or below which to preserve
6785      *                     processes, or {@code -1} to ignore the process state
6786      */
6787     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6788         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6789                 != PackageManager.PERMISSION_GRANTED) {
6790             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6791                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6792                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6793             Slog.w(TAG, msg);
6794             throw new SecurityException(msg);
6795         }
6796
6797         final long callingId = Binder.clearCallingIdentity();
6798         try {
6799             synchronized (this) {
6800                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6801                 final int NP = mProcessNames.getMap().size();
6802                 for (int ip = 0; ip < NP; ip++) {
6803                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6804                     final int NA = apps.size();
6805                     for (int ia = 0; ia < NA; ia++) {
6806                         final ProcessRecord app = apps.valueAt(ia);
6807                         if (app.removed) {
6808                             procs.add(app);
6809                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6810                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6811                             app.removed = true;
6812                             procs.add(app);
6813                         }
6814                     }
6815                 }
6816
6817                 final int N = procs.size();
6818                 for (int i = 0; i < N; i++) {
6819                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
6820                 }
6821             }
6822         } finally {
6823             Binder.restoreCallingIdentity(callingId);
6824         }
6825     }
6826
6827     @Override
6828     public void forceStopPackage(final String packageName, int userId) {
6829         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6830                 != PackageManager.PERMISSION_GRANTED) {
6831             String msg = "Permission Denial: forceStopPackage() from pid="
6832                     + Binder.getCallingPid()
6833                     + ", uid=" + Binder.getCallingUid()
6834                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6835             Slog.w(TAG, msg);
6836             throw new SecurityException(msg);
6837         }
6838         final int callingPid = Binder.getCallingPid();
6839         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6840                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6841         long callingId = Binder.clearCallingIdentity();
6842         try {
6843             IPackageManager pm = AppGlobals.getPackageManager();
6844             synchronized(this) {
6845                 int[] users = userId == UserHandle.USER_ALL
6846                         ? mUserController.getUsers() : new int[] { userId };
6847                 for (int user : users) {
6848                     if (getPackageManagerInternalLocked().isPackageStateProtected(
6849                             packageName, user)) {
6850                         Slog.w(TAG, "Ignoring request to force stop protected package "
6851                                 + packageName + " u" + user);
6852                         return;
6853                     }
6854
6855                     int pkgUid = -1;
6856                     try {
6857                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6858                                 user);
6859                     } catch (RemoteException e) {
6860                     }
6861                     if (pkgUid == -1) {
6862                         Slog.w(TAG, "Invalid packageName: " + packageName);
6863                         continue;
6864                     }
6865                     try {
6866                         pm.setPackageStoppedState(packageName, true, user);
6867                     } catch (RemoteException e) {
6868                     } catch (IllegalArgumentException e) {
6869                         Slog.w(TAG, "Failed trying to unstop package "
6870                                 + packageName + ": " + e);
6871                     }
6872                     if (mUserController.isUserRunning(user, 0)) {
6873                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6874                         finishForceStopPackageLocked(packageName, pkgUid);
6875                     }
6876                 }
6877             }
6878         } finally {
6879             Binder.restoreCallingIdentity(callingId);
6880         }
6881     }
6882
6883     @Override
6884     public void addPackageDependency(String packageName) {
6885         synchronized (this) {
6886             int callingPid = Binder.getCallingPid();
6887             if (callingPid == myPid()) {
6888                 //  Yeah, um, no.
6889                 return;
6890             }
6891             ProcessRecord proc;
6892             synchronized (mPidsSelfLocked) {
6893                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6894             }
6895             if (proc != null) {
6896                 if (proc.pkgDeps == null) {
6897                     proc.pkgDeps = new ArraySet<String>(1);
6898                 }
6899                 proc.pkgDeps.add(packageName);
6900             }
6901         }
6902     }
6903
6904     /*
6905      * The pkg name and app id have to be specified.
6906      */
6907     @Override
6908     public void killApplication(String pkg, int appId, int userId, String reason) {
6909         if (pkg == null) {
6910             return;
6911         }
6912         // Make sure the uid is valid.
6913         if (appId < 0) {
6914             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6915             return;
6916         }
6917         int callerUid = Binder.getCallingUid();
6918         // Only the system server can kill an application
6919         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6920             // Post an aysnc message to kill the application
6921             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6922             msg.arg1 = appId;
6923             msg.arg2 = userId;
6924             Bundle bundle = new Bundle();
6925             bundle.putString("pkg", pkg);
6926             bundle.putString("reason", reason);
6927             msg.obj = bundle;
6928             mHandler.sendMessage(msg);
6929         } else {
6930             throw new SecurityException(callerUid + " cannot kill pkg: " +
6931                     pkg);
6932         }
6933     }
6934
6935     @Override
6936     public void closeSystemDialogs(String reason) {
6937         enforceNotIsolatedCaller("closeSystemDialogs");
6938
6939         final int pid = Binder.getCallingPid();
6940         final int uid = Binder.getCallingUid();
6941         final long origId = Binder.clearCallingIdentity();
6942         try {
6943             synchronized (this) {
6944                 // Only allow this from foreground processes, so that background
6945                 // applications can't abuse it to prevent system UI from being shown.
6946                 if (uid >= FIRST_APPLICATION_UID) {
6947                     ProcessRecord proc;
6948                     synchronized (mPidsSelfLocked) {
6949                         proc = mPidsSelfLocked.get(pid);
6950                     }
6951                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6952                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6953                                 + " from background process " + proc);
6954                         return;
6955                     }
6956                 }
6957                 closeSystemDialogsLocked(reason);
6958             }
6959         } finally {
6960             Binder.restoreCallingIdentity(origId);
6961         }
6962     }
6963
6964     @GuardedBy("this")
6965     void closeSystemDialogsLocked(String reason) {
6966         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6967         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6968                 | Intent.FLAG_RECEIVER_FOREGROUND);
6969         if (reason != null) {
6970             intent.putExtra("reason", reason);
6971         }
6972         mWindowManager.closeSystemDialogs(reason);
6973
6974         mStackSupervisor.closeSystemDialogsLocked();
6975
6976         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6977                 OP_NONE, null, false, false,
6978                 -1, SYSTEM_UID, UserHandle.USER_ALL);
6979     }
6980
6981     @Override
6982     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6983         enforceNotIsolatedCaller("getProcessMemoryInfo");
6984         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6985         for (int i=pids.length-1; i>=0; i--) {
6986             ProcessRecord proc;
6987             int oomAdj;
6988             synchronized (this) {
6989                 synchronized (mPidsSelfLocked) {
6990                     proc = mPidsSelfLocked.get(pids[i]);
6991                     oomAdj = proc != null ? proc.setAdj : 0;
6992                 }
6993             }
6994             infos[i] = new Debug.MemoryInfo();
6995             long startTime = SystemClock.currentThreadTimeMillis();
6996             Debug.getMemoryInfo(pids[i], infos[i]);
6997             long endTime = SystemClock.currentThreadTimeMillis();
6998             if (proc != null) {
6999                 synchronized (this) {
7000                     if (proc.thread != null && proc.setAdj == oomAdj) {
7001                         // Record this for posterity if the process has been stable.
7002                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
7003                                 infos[i].getTotalUss(), infos[i].getTotalRss(), false,
7004                                 ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
7005                                 proc.pkgList);
7006                     }
7007                 }
7008             }
7009         }
7010         return infos;
7011     }
7012
7013     @Override
7014     public long[] getProcessPss(int[] pids) {
7015         enforceNotIsolatedCaller("getProcessPss");
7016         long[] pss = new long[pids.length];
7017         for (int i=pids.length-1; i>=0; i--) {
7018             ProcessRecord proc;
7019             int oomAdj;
7020             synchronized (this) {
7021                 synchronized (mPidsSelfLocked) {
7022                     proc = mPidsSelfLocked.get(pids[i]);
7023                     oomAdj = proc != null ? proc.setAdj : 0;
7024                 }
7025             }
7026             long[] tmpUss = new long[3];
7027             long startTime = SystemClock.currentThreadTimeMillis();
7028             pss[i] = Debug.getPss(pids[i], tmpUss, null);
7029             long endTime = SystemClock.currentThreadTimeMillis();
7030             if (proc != null) {
7031                 synchronized (this) {
7032                     if (proc.thread != null && proc.setAdj == oomAdj) {
7033                         // Record this for posterity if the process has been stable.
7034                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
7035                                 ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
7036                     }
7037                 }
7038             }
7039         }
7040         return pss;
7041     }
7042
7043     @Override
7044     public void killApplicationProcess(String processName, int uid) {
7045         if (processName == null) {
7046             return;
7047         }
7048
7049         int callerUid = Binder.getCallingUid();
7050         // Only the system server can kill an application
7051         if (callerUid == SYSTEM_UID) {
7052             synchronized (this) {
7053                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
7054                 if (app != null && app.thread != null) {
7055                     try {
7056                         app.thread.scheduleSuicide();
7057                     } catch (RemoteException e) {
7058                         // If the other end already died, then our work here is done.
7059                     }
7060                 } else {
7061                     Slog.w(TAG, "Process/uid not found attempting kill of "
7062                             + processName + " / " + uid);
7063                 }
7064             }
7065         } else {
7066             throw new SecurityException(callerUid + " cannot kill app process: " +
7067                     processName);
7068         }
7069     }
7070
7071     @GuardedBy("this")
7072     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
7073         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
7074                 false, true, false, false, UserHandle.getUserId(uid), reason);
7075     }
7076
7077     @GuardedBy("this")
7078     private void finishForceStopPackageLocked(final String packageName, int uid) {
7079         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
7080                 Uri.fromParts("package", packageName, null));
7081         if (!mProcessesReady) {
7082             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7083                     | Intent.FLAG_RECEIVER_FOREGROUND);
7084         }
7085         intent.putExtra(Intent.EXTRA_UID, uid);
7086         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
7087         broadcastIntentLocked(null, null, intent,
7088                 null, null, 0, null, null, null, OP_NONE,
7089                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
7090     }
7091
7092
7093     @GuardedBy("this")
7094     private final boolean killPackageProcessesLocked(String packageName, int appId,
7095             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
7096             boolean doit, boolean evenPersistent, String reason) {
7097         ArrayList<ProcessRecord> procs = new ArrayList<>();
7098
7099         // Remove all processes this package may have touched: all with the
7100         // same UID (except for the system or root user), and all whose name
7101         // matches the package name.
7102         final int NP = mProcessNames.getMap().size();
7103         for (int ip=0; ip<NP; ip++) {
7104             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
7105             final int NA = apps.size();
7106             for (int ia=0; ia<NA; ia++) {
7107                 ProcessRecord app = apps.valueAt(ia);
7108                 if (app.persistent && !evenPersistent) {
7109                     // we don't kill persistent processes
7110                     continue;
7111                 }
7112                 if (app.removed) {
7113                     if (doit) {
7114                         procs.add(app);
7115                     }
7116                     continue;
7117                 }
7118
7119                 // Skip process if it doesn't meet our oom adj requirement.
7120                 if (app.setAdj < minOomAdj) {
7121                     continue;
7122                 }
7123
7124                 // If no package is specified, we call all processes under the
7125                 // give user id.
7126                 if (packageName == null) {
7127                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
7128                         continue;
7129                     }
7130                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
7131                         continue;
7132                     }
7133                 // Package has been specified, we want to hit all processes
7134                 // that match it.  We need to qualify this by the processes
7135                 // that are running under the specified app and user ID.
7136                 } else {
7137                     final boolean isDep = app.pkgDeps != null
7138                             && app.pkgDeps.contains(packageName);
7139                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
7140                         continue;
7141                     }
7142                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
7143                         continue;
7144                     }
7145                     if (!app.pkgList.containsKey(packageName) && !isDep) {
7146                         continue;
7147                     }
7148                 }
7149
7150                 // Process has passed all conditions, kill it!
7151                 if (!doit) {
7152                     return true;
7153                 }
7154                 app.removed = true;
7155                 procs.add(app);
7156             }
7157         }
7158
7159         int N = procs.size();
7160         for (int i=0; i<N; i++) {
7161             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
7162         }
7163         updateOomAdjLocked();
7164         return N > 0;
7165     }
7166
7167     private void cleanupDisabledPackageComponentsLocked(
7168             String packageName, int userId, boolean killProcess, String[] changedClasses) {
7169
7170         Set<String> disabledClasses = null;
7171         boolean packageDisabled = false;
7172         IPackageManager pm = AppGlobals.getPackageManager();
7173
7174         if (changedClasses == null) {
7175             // Nothing changed...
7176             return;
7177         }
7178
7179         // Determine enable/disable state of the package and its components.
7180         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
7181         for (int i = changedClasses.length - 1; i >= 0; i--) {
7182             final String changedClass = changedClasses[i];
7183
7184             if (changedClass.equals(packageName)) {
7185                 try {
7186                     // Entire package setting changed
7187                     enabled = pm.getApplicationEnabledSetting(packageName,
7188                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7189                 } catch (Exception e) {
7190                     // No such package/component; probably racing with uninstall.  In any
7191                     // event it means we have nothing further to do here.
7192                     return;
7193                 }
7194                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7195                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
7196                 if (packageDisabled) {
7197                     // Entire package is disabled.
7198                     // No need to continue to check component states.
7199                     disabledClasses = null;
7200                     break;
7201                 }
7202             } else {
7203                 try {
7204                     enabled = pm.getComponentEnabledSetting(
7205                             new ComponentName(packageName, changedClass),
7206                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7207                 } catch (Exception e) {
7208                     // As above, probably racing with uninstall.
7209                     return;
7210                 }
7211                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7212                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
7213                     if (disabledClasses == null) {
7214                         disabledClasses = new ArraySet<>(changedClasses.length);
7215                     }
7216                     disabledClasses.add(changedClass);
7217                 }
7218             }
7219         }
7220
7221         if (!packageDisabled && disabledClasses == null) {
7222             // Nothing to do here...
7223             return;
7224         }
7225
7226         // Clean-up disabled activities.
7227         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7228                 packageName, disabledClasses, true, false, userId) && mBooted) {
7229             mStackSupervisor.resumeFocusedStackTopActivityLocked();
7230             mStackSupervisor.scheduleIdleLocked();
7231         }
7232
7233         // Clean-up disabled tasks
7234         mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
7235
7236         // Clean-up disabled services.
7237         mServices.bringDownDisabledPackageServicesLocked(
7238                 packageName, disabledClasses, userId, false, killProcess, true);
7239
7240         // Clean-up disabled providers.
7241         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7242         mProviderMap.collectPackageProvidersLocked(
7243                 packageName, disabledClasses, true, false, userId, providers);
7244         for (int i = providers.size() - 1; i >= 0; i--) {
7245             removeDyingProviderLocked(null, providers.get(i), true);
7246         }
7247
7248         // Clean-up disabled broadcast receivers.
7249         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7250             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7251                     packageName, disabledClasses, userId, true);
7252         }
7253
7254     }
7255
7256     final boolean clearBroadcastQueueForUserLocked(int userId) {
7257         boolean didSomething = false;
7258         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7259             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7260                     null, null, userId, true);
7261         }
7262         return didSomething;
7263     }
7264
7265     @GuardedBy("this")
7266     final boolean forceStopPackageLocked(String packageName, int appId,
7267             boolean callerWillRestart, boolean purgeCache, boolean doit,
7268             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
7269         int i;
7270
7271         if (userId == UserHandle.USER_ALL && packageName == null) {
7272             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
7273         }
7274
7275         if (appId < 0 && packageName != null) {
7276             try {
7277                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
7278                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
7279             } catch (RemoteException e) {
7280             }
7281         }
7282
7283         if (doit) {
7284             if (packageName != null) {
7285                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
7286                         + " user=" + userId + ": " + reason);
7287             } else {
7288                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
7289             }
7290
7291             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
7292         }
7293
7294         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
7295                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
7296                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
7297
7298         didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
7299
7300         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7301                 packageName, null, doit, evenPersistent, userId)) {
7302             if (!doit) {
7303                 return true;
7304             }
7305             didSomething = true;
7306         }
7307
7308         if (mServices.bringDownDisabledPackageServicesLocked(
7309                 packageName, null, userId, evenPersistent, true, doit)) {
7310             if (!doit) {
7311                 return true;
7312             }
7313             didSomething = true;
7314         }
7315
7316         if (packageName == null) {
7317             // Remove all sticky broadcasts from this user.
7318             mStickyBroadcasts.remove(userId);
7319         }
7320
7321         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7322         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
7323                 userId, providers)) {
7324             if (!doit) {
7325                 return true;
7326             }
7327             didSomething = true;
7328         }
7329         for (i = providers.size() - 1; i >= 0; i--) {
7330             removeDyingProviderLocked(null, providers.get(i), true);
7331         }
7332
7333         // Remove transient permissions granted from/to this package/user
7334         removeUriPermissionsForPackageLocked(packageName, userId, false, false);
7335
7336         if (doit) {
7337             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
7338                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7339                         packageName, null, userId, doit);
7340             }
7341         }
7342
7343         if (packageName == null || uninstalling) {
7344             // Remove pending intents.  For now we only do this when force
7345             // stopping users, because we have some problems when doing this
7346             // for packages -- app widgets are not currently cleaned up for
7347             // such packages, so they can be left with bad pending intents.
7348             if (mIntentSenderRecords.size() > 0) {
7349                 Iterator<WeakReference<PendingIntentRecord>> it
7350                         = mIntentSenderRecords.values().iterator();
7351                 while (it.hasNext()) {
7352                     WeakReference<PendingIntentRecord> wpir = it.next();
7353                     if (wpir == null) {
7354                         it.remove();
7355                         continue;
7356                     }
7357                     PendingIntentRecord pir = wpir.get();
7358                     if (pir == null) {
7359                         it.remove();
7360                         continue;
7361                     }
7362                     if (packageName == null) {
7363                         // Stopping user, remove all objects for the user.
7364                         if (pir.key.userId != userId) {
7365                             // Not the same user, skip it.
7366                             continue;
7367                         }
7368                     } else {
7369                         if (UserHandle.getAppId(pir.uid) != appId) {
7370                             // Different app id, skip it.
7371                             continue;
7372                         }
7373                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7374                             // Different user, skip it.
7375                             continue;
7376                         }
7377                         if (!pir.key.packageName.equals(packageName)) {
7378                             // Different package, skip it.
7379                             continue;
7380                         }
7381                     }
7382                     if (!doit) {
7383                         return true;
7384                     }
7385                     didSomething = true;
7386                     it.remove();
7387                     makeIntentSenderCanceledLocked(pir);
7388                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7389                         pir.key.activity.pendingResults.remove(pir.ref);
7390                     }
7391                 }
7392             }
7393         }
7394
7395         if (doit) {
7396             if (purgeCache && packageName != null) {
7397                 AttributeCache ac = AttributeCache.instance();
7398                 if (ac != null) {
7399                     ac.removePackage(packageName);
7400                 }
7401             }
7402             if (mBooted) {
7403                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
7404                 mStackSupervisor.scheduleIdleLocked();
7405             }
7406         }
7407
7408         return didSomething;
7409     }
7410
7411     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7412         return removeProcessNameLocked(name, uid, null);
7413     }
7414
7415     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
7416             final ProcessRecord expecting) {
7417         ProcessRecord old = mProcessNames.get(name, uid);
7418         // Only actually remove when the currently recorded value matches the
7419         // record that we expected; if it doesn't match then we raced with a
7420         // newly created process and we don't want to destroy the new one.
7421         if ((expecting == null) || (old == expecting)) {
7422             mProcessNames.remove(name, uid);
7423         }
7424         if (old != null && old.uidRecord != null) {
7425             old.uidRecord.numProcs--;
7426             if (old.uidRecord.numProcs == 0) {
7427                 // No more processes using this uid, tell clients it is gone.
7428                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7429                         "No more processes in " + old.uidRecord);
7430                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
7431                 EventLogTags.writeAmUidStopped(uid);
7432                 mActiveUids.remove(uid);
7433                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
7434             }
7435             old.uidRecord = null;
7436         }
7437         mIsolatedProcesses.remove(uid);
7438         return old;
7439     }
7440
7441     private final void addProcessNameLocked(ProcessRecord proc) {
7442         // We shouldn't already have a process under this name, but just in case we
7443         // need to clean up whatever may be there now.
7444         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
7445         if (old == proc && proc.persistent) {
7446             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
7447             Slog.w(TAG, "Re-adding persistent process " + proc);
7448         } else if (old != null) {
7449             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7450         }
7451         UidRecord uidRec = mActiveUids.get(proc.uid);
7452         if (uidRec == null) {
7453             uidRec = new UidRecord(proc.uid);
7454             // This is the first appearance of the uid, report it now!
7455             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7456                     "Creating new process uid: " + uidRec);
7457             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7458                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7459                 uidRec.setWhitelist = uidRec.curWhitelist = true;
7460             }
7461             uidRec.updateHasInternetPermission();
7462             mActiveUids.put(proc.uid, uidRec);
7463             EventLogTags.writeAmUidRunning(uidRec.uid);
7464             noteUidProcessState(uidRec.uid, uidRec.curProcState);
7465         }
7466         proc.uidRecord = uidRec;
7467
7468         // Reset render thread tid if it was already set, so new process can set it again.
7469         proc.renderThreadTid = 0;
7470         uidRec.numProcs++;
7471         mProcessNames.put(proc.processName, proc.uid, proc);
7472         if (proc.isolated) {
7473             mIsolatedProcesses.put(proc.uid, proc);
7474         }
7475     }
7476
7477     @GuardedBy("this")
7478     boolean removeProcessLocked(ProcessRecord app,
7479             boolean callerWillRestart, boolean allowRestart, String reason) {
7480         final String name = app.processName;
7481         final int uid = app.uid;
7482         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7483             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7484
7485         ProcessRecord old = mProcessNames.get(name, uid);
7486         if (old != app) {
7487             // This process is no longer active, so nothing to do.
7488             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7489             return false;
7490         }
7491         removeProcessNameLocked(name, uid);
7492         if (mHeavyWeightProcess == app) {
7493             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7494                     mHeavyWeightProcess.userId, 0));
7495             mHeavyWeightProcess = null;
7496         }
7497         boolean needRestart = false;
7498         if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7499             int pid = app.pid;
7500             if (pid > 0) {
7501                 synchronized (mPidsSelfLocked) {
7502                     mPidsSelfLocked.remove(pid);
7503                     mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7504                 }
7505                 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7506                 if (app.isolated) {
7507                     mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7508                     getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7509                 }
7510             }
7511             boolean willRestart = false;
7512             if (app.persistent && !app.isolated) {
7513                 if (!callerWillRestart) {
7514                     willRestart = true;
7515                 } else {
7516                     needRestart = true;
7517                 }
7518             }
7519             app.kill(reason, true);
7520             handleAppDiedLocked(app, willRestart, allowRestart);
7521             if (willRestart) {
7522                 removeLruProcessLocked(app);
7523                 addAppLocked(app.info, null, false, null /* ABI override */);
7524             }
7525         } else {
7526             mRemovedProcesses.add(app);
7527         }
7528
7529         return needRestart;
7530     }
7531
7532     @GuardedBy("this")
7533     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7534         cleanupAppInLaunchingProvidersLocked(app, true);
7535         removeProcessLocked(app, false, true, "timeout publishing content providers");
7536     }
7537
7538     private final void processStartTimedOutLocked(ProcessRecord app) {
7539         final int pid = app.pid;
7540         boolean gone = false;
7541         synchronized (mPidsSelfLocked) {
7542             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7543             if (knownApp != null && knownApp.thread == null) {
7544                 mPidsSelfLocked.remove(pid);
7545                 gone = true;
7546             }
7547         }
7548
7549         if (gone) {
7550             Slog.w(TAG, "Process " + app + " failed to attach");
7551             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7552                     pid, app.uid, app.processName);
7553             removeProcessNameLocked(app.processName, app.uid);
7554             if (mHeavyWeightProcess == app) {
7555                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7556                         mHeavyWeightProcess.userId, 0));
7557                 mHeavyWeightProcess = null;
7558             }
7559             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7560             // Take care of any launching providers waiting for this process.
7561             cleanupAppInLaunchingProvidersLocked(app, true);
7562             // Take care of any services that are waiting for the process.
7563             mServices.processStartTimedOutLocked(app);
7564             app.kill("start timeout", true);
7565             if (app.isolated) {
7566                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7567             }
7568             removeLruProcessLocked(app);
7569             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7570                 Slog.w(TAG, "Unattached app died before backup, skipping");
7571                 mHandler.post(new Runnable() {
7572                 @Override
7573                     public void run(){
7574                         try {
7575                             IBackupManager bm = IBackupManager.Stub.asInterface(
7576                                     ServiceManager.getService(Context.BACKUP_SERVICE));
7577                             bm.agentDisconnected(app.info.packageName);
7578                         } catch (RemoteException e) {
7579                             // Can't happen; the backup manager is local
7580                         }
7581                     }
7582                 });
7583             }
7584             if (isPendingBroadcastProcessLocked(pid)) {
7585                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7586                 skipPendingBroadcastLocked(pid);
7587             }
7588         } else {
7589             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7590         }
7591     }
7592
7593     @GuardedBy("this")
7594     private final boolean attachApplicationLocked(IApplicationThread thread,
7595             int pid, int callingUid, long startSeq) {
7596
7597         // Find the application record that is being attached...  either via
7598         // the pid if we are running in multiple processes, or just pull the
7599         // next app record if we are emulating process with anonymous threads.
7600         ProcessRecord app;
7601         long startTime = SystemClock.uptimeMillis();
7602         if (pid != MY_PID && pid >= 0) {
7603             synchronized (mPidsSelfLocked) {
7604                 app = mPidsSelfLocked.get(pid);
7605             }
7606             if (app != null && (app.startUid != callingUid || app.startSeq != startSeq)) {
7607                 String processName = null;
7608                 final ProcessRecord pending = mPendingStarts.get(startSeq);
7609                 if (pending != null) {
7610                     processName = pending.processName;
7611                 }
7612                 final String msg = "attachApplicationLocked process:" + processName
7613                       + " startSeq:" + startSeq
7614                       + " pid:" + pid
7615                       + " belongs to another existing app:" + app.processName
7616                       + " startSeq:" + app.startSeq;
7617                 Slog.wtf(TAG, msg);
7618                 // SafetyNet logging for b/131105245.
7619                 EventLog.writeEvent(0x534e4554, "131105245", app.startUid, msg);
7620                 // If there is already an app occupying that pid that hasn't been cleaned up
7621                 cleanUpApplicationRecordLocked(app, false, false, -1,
7622                     true /*replacingPid*/);
7623                 mPidsSelfLocked.remove(pid);
7624                 app = null;
7625             }
7626         } else {
7627             app = null;
7628         }
7629
7630         // It's possible that process called attachApplication before we got a chance to
7631         // update the internal state.
7632         if (app == null && startSeq > 0) {
7633             final ProcessRecord pending = mPendingStarts.get(startSeq);
7634             if (pending != null && pending.startUid == callingUid && pending.startSeq == startSeq
7635                     && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7636                             startSeq, true)) {
7637                 app = pending;
7638             }
7639         }
7640
7641         if (app == null) {
7642             Slog.w(TAG, "No pending application record for pid " + pid
7643                     + " (IApplicationThread " + thread + "); dropping process");
7644             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7645             if (pid > 0 && pid != MY_PID) {
7646                 killProcessQuiet(pid);
7647                 //TODO: killProcessGroup(app.info.uid, pid);
7648             } else {
7649                 try {
7650                     thread.scheduleExit();
7651                 } catch (Exception e) {
7652                     // Ignore exceptions.
7653                 }
7654             }
7655             return false;
7656         }
7657
7658         // If this application record is still attached to a previous
7659         // process, clean it up now.
7660         if (app.thread != null) {
7661             handleAppDiedLocked(app, true, true);
7662         }
7663
7664         // Tell the process all about itself.
7665
7666         if (DEBUG_ALL) Slog.v(
7667                 TAG, "Binding process pid " + pid + " to record " + app);
7668
7669         final String processName = app.processName;
7670         try {
7671             AppDeathRecipient adr = new AppDeathRecipient(
7672                     app, pid, thread);
7673             thread.asBinder().linkToDeath(adr, 0);
7674             app.deathRecipient = adr;
7675         } catch (RemoteException e) {
7676             app.resetPackageList(mProcessStats);
7677             startProcessLocked(app, "link fail", processName);
7678             return false;
7679         }
7680
7681         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7682
7683         app.makeActive(thread, mProcessStats);
7684         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7685         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7686         app.forcingToImportant = null;
7687         updateProcessForegroundLocked(app, false, false);
7688         app.hasShownUi = false;
7689         app.debugging = false;
7690         app.cached = false;
7691         app.killedByAm = false;
7692         app.killed = false;
7693
7694
7695         // We carefully use the same state that PackageManager uses for
7696         // filtering, since we use this flag to decide if we need to install
7697         // providers when user is unlocked later
7698         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7699
7700         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7701
7702         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7703         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7704
7705         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7706             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7707             msg.obj = app;
7708             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7709         }
7710
7711         checkTime(startTime, "attachApplicationLocked: before bindApplication");
7712
7713         if (!normalMode) {
7714             Slog.i(TAG, "Launching preboot mode app: " + app);
7715         }
7716
7717         if (DEBUG_ALL) Slog.v(
7718             TAG, "New app record " + app
7719             + " thread=" + thread.asBinder() + " pid=" + pid);
7720         try {
7721             int testMode = ApplicationThreadConstants.DEBUG_OFF;
7722             if (mDebugApp != null && mDebugApp.equals(processName)) {
7723                 testMode = mWaitForDebugger
7724                     ? ApplicationThreadConstants.DEBUG_WAIT
7725                     : ApplicationThreadConstants.DEBUG_ON;
7726                 app.debugging = true;
7727                 if (mDebugTransient) {
7728                     mDebugApp = mOrigDebugApp;
7729                     mWaitForDebugger = mOrigWaitForDebugger;
7730                 }
7731             }
7732
7733             boolean enableTrackAllocation = false;
7734             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7735                 enableTrackAllocation = true;
7736                 mTrackAllocationApp = null;
7737             }
7738
7739             // If the app is being launched for restore or full backup, set it up specially
7740             boolean isRestrictedBackupMode = false;
7741             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7742                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7743                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7744                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7745                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7746             }
7747
7748             if (app.instr != null) {
7749                 notifyPackageUse(app.instr.mClass.getPackageName(),
7750                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7751             }
7752             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7753                     + processName + " with config " + getGlobalConfiguration());
7754             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7755             app.compat = compatibilityInfoForPackageLocked(appInfo);
7756
7757             ProfilerInfo profilerInfo = null;
7758             String preBindAgent = null;
7759             if (mProfileApp != null && mProfileApp.equals(processName)) {
7760                 mProfileProc = app;
7761                 if (mProfilerInfo != null) {
7762                     // Send a profiler info object to the app if either a file is given, or
7763                     // an agent should be loaded at bind-time.
7764                     boolean needsInfo = mProfilerInfo.profileFile != null
7765                             || mProfilerInfo.attachAgentDuringBind;
7766                     profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7767                     if (mProfilerInfo.agent != null) {
7768                         preBindAgent = mProfilerInfo.agent;
7769                     }
7770                 }
7771             } else if (app.instr != null && app.instr.mProfileFile != null) {
7772                 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7773                         null, false);
7774             }
7775             if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7776                 // We need to do a debuggable check here. See setAgentApp for why the check is
7777                 // postponed to here.
7778                 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7779                     String agent = mAppAgentMap.get(processName);
7780                     // Do not overwrite already requested agent.
7781                     if (profilerInfo == null) {
7782                         profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7783                                 mAppAgentMap.get(processName), true);
7784                     } else if (profilerInfo.agent == null) {
7785                         profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7786                     }
7787                 }
7788             }
7789
7790             if (profilerInfo != null && profilerInfo.profileFd != null) {
7791                 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7792                 if (TextUtils.equals(mProfileApp, processName) && mProfilerInfo != null) {
7793                     clearProfilerLocked();
7794                 }
7795             }
7796
7797             // We deprecated Build.SERIAL and it is not accessible to
7798             // apps that target the v2 security sandbox and to apps that
7799             // target APIs higher than O MR1. Since access to the serial
7800             // is now behind a permission we push down the value.
7801             final String buildSerial = (appInfo.targetSandboxVersion < 2
7802                     && appInfo.targetSdkVersion < Build.VERSION_CODES.P)
7803                             ? sTheRealBuildSerial : Build.UNKNOWN;
7804
7805             // Check if this is a secondary process that should be incorporated into some
7806             // currently active instrumentation.  (Note we do this AFTER all of the profiling
7807             // stuff above because profiling can currently happen only in the primary
7808             // instrumentation process.)
7809             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7810                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7811                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7812                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7813                         if (aInstr.mTargetProcesses.length == 0) {
7814                             // This is the wildcard mode, where every process brought up for
7815                             // the target instrumentation should be included.
7816                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7817                                 app.instr = aInstr;
7818                                 aInstr.mRunningProcesses.add(app);
7819                             }
7820                         } else {
7821                             for (String proc : aInstr.mTargetProcesses) {
7822                                 if (proc.equals(app.processName)) {
7823                                     app.instr = aInstr;
7824                                     aInstr.mRunningProcesses.add(app);
7825                                     break;
7826                                 }
7827                             }
7828                         }
7829                     }
7830                 }
7831             }
7832
7833             // If we were asked to attach an agent on startup, do so now, before we're binding
7834             // application code.
7835             if (preBindAgent != null) {
7836                 thread.attachAgent(preBindAgent);
7837             }
7838
7839
7840             // Figure out whether the app needs to run in autofill compat mode.
7841             boolean isAutofillCompatEnabled = false;
7842             if (UserHandle.getAppId(app.info.uid) >= Process.FIRST_APPLICATION_UID) {
7843                 final AutofillManagerInternal afm = LocalServices.getService(
7844                         AutofillManagerInternal.class);
7845                 if (afm != null) {
7846                     isAutofillCompatEnabled = afm.isCompatibilityModeRequested(
7847                             app.info.packageName, app.info.versionCode, app.userId);
7848                 }
7849             }
7850
7851             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7852             mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7853             if (app.isolatedEntryPoint != null) {
7854                 // This is an isolated process which should just call an entry point instead of
7855                 // being bound to an application.
7856                 thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7857             } else if (app.instr != null) {
7858                 thread.bindApplication(processName, appInfo, providers,
7859                         app.instr.mClass,
7860                         profilerInfo, app.instr.mArguments,
7861                         app.instr.mWatcher,
7862                         app.instr.mUiAutomationConnection, testMode,
7863                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7864                         isRestrictedBackupMode || !normalMode, app.persistent,
7865                         new Configuration(getGlobalConfiguration()), app.compat,
7866                         getCommonServicesLocked(app.isolated),
7867                         mCoreSettingsObserver.getCoreSettingsLocked(),
7868                         buildSerial, isAutofillCompatEnabled);
7869             } else {
7870                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7871                         null, null, null, testMode,
7872                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7873                         isRestrictedBackupMode || !normalMode, app.persistent,
7874                         new Configuration(getGlobalConfiguration()), app.compat,
7875                         getCommonServicesLocked(app.isolated),
7876                         mCoreSettingsObserver.getCoreSettingsLocked(),
7877                         buildSerial, isAutofillCompatEnabled);
7878             }
7879             if (profilerInfo != null) {
7880                 profilerInfo.closeFd();
7881                 profilerInfo = null;
7882             }
7883             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7884             updateLruProcessLocked(app, false, null);
7885             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7886             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7887         } catch (Exception e) {
7888             // todo: Yikes!  What should we do?  For now we will try to
7889             // start another process, but that could easily get us in
7890             // an infinite loop of restarting processes...
7891             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7892
7893             app.resetPackageList(mProcessStats);
7894             app.unlinkDeathRecipient();
7895             startProcessLocked(app, "bind fail", processName);
7896             return false;
7897         }
7898
7899         // Remove this record from the list of starting applications.
7900         mPersistentStartingProcesses.remove(app);
7901         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7902                 "Attach application locked removing on hold: " + app);
7903         mProcessesOnHold.remove(app);
7904
7905         boolean badApp = false;
7906         boolean didSomething = false;
7907
7908         // See if the top visible activity is waiting to run in this process...
7909         if (normalMode) {
7910             try {
7911                 if (mStackSupervisor.attachApplicationLocked(app)) {
7912                     didSomething = true;
7913                 }
7914             } catch (Exception e) {
7915                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7916                 badApp = true;
7917             }
7918         }
7919
7920         // Find any services that should be running in this process...
7921         if (!badApp) {
7922             try {
7923                 didSomething |= mServices.attachApplicationLocked(app, processName);
7924                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7925             } catch (Exception e) {
7926                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7927                 badApp = true;
7928             }
7929         }
7930
7931         // Check if a next-broadcast receiver is in this process...
7932         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7933             try {
7934                 didSomething |= sendPendingBroadcastsLocked(app);
7935                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7936             } catch (Exception e) {
7937                 // If the app died trying to launch the receiver we declare it 'bad'
7938                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7939                 badApp = true;
7940             }
7941         }
7942
7943         // Check whether the next backup agent is in this process...
7944         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7945             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7946                     "New app is backup target, launching agent for " + app);
7947             notifyPackageUse(mBackupTarget.appInfo.packageName,
7948                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7949             try {
7950                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7951                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7952                         mBackupTarget.backupMode);
7953             } catch (Exception e) {
7954                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7955                 badApp = true;
7956             }
7957         }
7958
7959         if (badApp) {
7960             app.kill("error during init", true);
7961             handleAppDiedLocked(app, false, true);
7962             return false;
7963         }
7964
7965         if (!didSomething) {
7966             updateOomAdjLocked();
7967             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7968         }
7969
7970         return true;
7971     }
7972
7973     @Override
7974     public final void attachApplication(IApplicationThread thread, long startSeq) {
7975         synchronized (this) {
7976             int callingPid = Binder.getCallingPid();
7977             final int callingUid = Binder.getCallingUid();
7978             final long origId = Binder.clearCallingIdentity();
7979             attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7980             Binder.restoreCallingIdentity(origId);
7981         }
7982     }
7983
7984     @Override
7985     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7986         final long origId = Binder.clearCallingIdentity();
7987         synchronized (this) {
7988             ActivityStack stack = ActivityRecord.getStackLocked(token);
7989             if (stack != null) {
7990                 ActivityRecord r =
7991                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7992                                 false /* processPausingActivities */, config);
7993                 if (stopProfiling) {
7994                     if ((mProfileProc == r.app) && mProfilerInfo != null) {
7995                         clearProfilerLocked();
7996                     }
7997                 }
7998             }
7999         }
8000         Binder.restoreCallingIdentity(origId);
8001     }
8002
8003     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
8004         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
8005                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
8006     }
8007
8008     void enableScreenAfterBoot() {
8009         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
8010                 SystemClock.uptimeMillis());
8011         mWindowManager.enableScreenAfterBoot();
8012
8013         synchronized (this) {
8014             updateEventDispatchingLocked();
8015         }
8016     }
8017
8018     @Override
8019     public void showBootMessage(final CharSequence msg, final boolean always) {
8020         if (Binder.getCallingUid() != myUid()) {
8021             throw new SecurityException();
8022         }
8023         mWindowManager.showBootMessage(msg, always);
8024     }
8025
8026     @Override
8027     public void keyguardGoingAway(int flags) {
8028         enforceNotIsolatedCaller("keyguardGoingAway");
8029         final long token = Binder.clearCallingIdentity();
8030         try {
8031             synchronized (this) {
8032                 mKeyguardController.keyguardGoingAway(flags);
8033             }
8034         } finally {
8035             Binder.restoreCallingIdentity(token);
8036         }
8037     }
8038
8039     /**
8040      * @return whther the keyguard is currently locked.
8041      */
8042     boolean isKeyguardLocked() {
8043         return mKeyguardController.isKeyguardLocked();
8044     }
8045
8046     final void finishBooting() {
8047         synchronized (this) {
8048             if (!mBootAnimationComplete) {
8049                 mCallFinishBooting = true;
8050                 return;
8051             }
8052             mCallFinishBooting = false;
8053         }
8054
8055         ArraySet<String> completedIsas = new ArraySet<String>();
8056         for (String abi : Build.SUPPORTED_ABIS) {
8057             zygoteProcess.establishZygoteConnectionForAbi(abi);
8058             final String instructionSet = VMRuntime.getInstructionSet(abi);
8059             if (!completedIsas.contains(instructionSet)) {
8060                 try {
8061                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
8062                 } catch (InstallerException e) {
8063                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
8064                             e.getMessage() +")");
8065                 }
8066                 completedIsas.add(instructionSet);
8067             }
8068         }
8069
8070         IntentFilter pkgFilter = new IntentFilter();
8071         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
8072         pkgFilter.addDataScheme("package");
8073         mContext.registerReceiver(new BroadcastReceiver() {
8074             @Override
8075             public void onReceive(Context context, Intent intent) {
8076                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
8077                 if (pkgs != null) {
8078                     for (String pkg : pkgs) {
8079                         synchronized (ActivityManagerService.this) {
8080                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
8081                                     0, "query restart")) {
8082                                 setResultCode(Activity.RESULT_OK);
8083                                 return;
8084                             }
8085                         }
8086                     }
8087                 }
8088             }
8089         }, pkgFilter);
8090
8091         IntentFilter dumpheapFilter = new IntentFilter();
8092         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
8093         mContext.registerReceiver(new BroadcastReceiver() {
8094             @Override
8095             public void onReceive(Context context, Intent intent) {
8096                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
8097                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
8098                 } else {
8099                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
8100                 }
8101             }
8102         }, dumpheapFilter);
8103
8104         // Let system services know.
8105         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
8106
8107         synchronized (this) {
8108             // Ensure that any processes we had put on hold are now started
8109             // up.
8110             final int NP = mProcessesOnHold.size();
8111             if (NP > 0) {
8112                 ArrayList<ProcessRecord> procs =
8113                     new ArrayList<ProcessRecord>(mProcessesOnHold);
8114                 for (int ip=0; ip<NP; ip++) {
8115                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
8116                             + procs.get(ip));
8117                     startProcessLocked(procs.get(ip), "on-hold", null);
8118                 }
8119             }
8120             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
8121                 return;
8122             }
8123             // Start looking for apps that are abusing wake locks.
8124             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
8125             mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
8126             // Tell anyone interested that we are done booting!
8127             SystemProperties.set("sys.boot_completed", "1");
8128
8129             // And trigger dev.bootcomplete if we are not showing encryption progress
8130             if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
8131                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
8132                 SystemProperties.set("dev.bootcomplete", "1");
8133             }
8134             mUserController.sendBootCompleted(
8135                     new IIntentReceiver.Stub() {
8136                         @Override
8137                         public void performReceive(Intent intent, int resultCode,
8138                                 String data, Bundle extras, boolean ordered,
8139                                 boolean sticky, int sendingUser) {
8140                             synchronized (ActivityManagerService.this) {
8141                                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
8142                             }
8143                         }
8144                     });
8145             mUserController.scheduleStartProfiles();
8146         }
8147     }
8148
8149     @Override
8150     public void bootAnimationComplete() {
8151         final boolean callFinishBooting;
8152         synchronized (this) {
8153             callFinishBooting = mCallFinishBooting;
8154             mBootAnimationComplete = true;
8155         }
8156         if (callFinishBooting) {
8157             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8158             finishBooting();
8159             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8160         }
8161     }
8162
8163     final void ensureBootCompleted() {
8164         boolean booting;
8165         boolean enableScreen;
8166         synchronized (this) {
8167             booting = mBooting;
8168             mBooting = false;
8169             enableScreen = !mBooted;
8170             mBooted = true;
8171         }
8172
8173         if (booting) {
8174             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8175             finishBooting();
8176             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8177         }
8178
8179         if (enableScreen) {
8180             enableScreenAfterBoot();
8181         }
8182     }
8183
8184     @Override
8185     public final void activityResumed(IBinder token) {
8186         final long origId = Binder.clearCallingIdentity();
8187         synchronized(this) {
8188             ActivityRecord.activityResumedLocked(token);
8189             mWindowManager.notifyAppResumedFinished(token);
8190         }
8191         Binder.restoreCallingIdentity(origId);
8192     }
8193
8194     @Override
8195     public final void activityPaused(IBinder token) {
8196         final long origId = Binder.clearCallingIdentity();
8197         synchronized(this) {
8198             ActivityStack stack = ActivityRecord.getStackLocked(token);
8199             if (stack != null) {
8200                 stack.activityPausedLocked(token, false);
8201             }
8202         }
8203         Binder.restoreCallingIdentity(origId);
8204     }
8205
8206     @Override
8207     public final void activityStopped(IBinder token, Bundle icicle,
8208             PersistableBundle persistentState, CharSequence description) {
8209         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
8210
8211         // Refuse possible leaked file descriptors
8212         if (icicle != null && icicle.hasFileDescriptors()) {
8213             throw new IllegalArgumentException("File descriptors passed in Bundle");
8214         }
8215
8216         final long origId = Binder.clearCallingIdentity();
8217
8218         synchronized (this) {
8219             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8220             if (r != null) {
8221                 r.activityStoppedLocked(icicle, persistentState, description);
8222             }
8223         }
8224
8225         trimApplications();
8226
8227         Binder.restoreCallingIdentity(origId);
8228     }
8229
8230     @Override
8231     public final void activityDestroyed(IBinder token) {
8232         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
8233         synchronized (this) {
8234             ActivityStack stack = ActivityRecord.getStackLocked(token);
8235             if (stack != null) {
8236                 stack.activityDestroyedLocked(token, "activityDestroyed");
8237             }
8238         }
8239     }
8240
8241     @Override
8242     public final void activityRelaunched(IBinder token) {
8243         final long origId = Binder.clearCallingIdentity();
8244         synchronized (this) {
8245             mStackSupervisor.activityRelaunchedLocked(token);
8246         }
8247         Binder.restoreCallingIdentity(origId);
8248     }
8249
8250     @Override
8251     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
8252             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
8253         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
8254                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
8255         synchronized (this) {
8256             ActivityRecord record = ActivityRecord.isInStackLocked(token);
8257             if (record == null) {
8258                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
8259                         + "found for: " + token);
8260             }
8261             record.setSizeConfigurations(horizontalSizeConfiguration,
8262                     verticalSizeConfigurations, smallestSizeConfigurations);
8263         }
8264     }
8265
8266     @Override
8267     public final void notifyLaunchTaskBehindComplete(IBinder token) {
8268         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
8269     }
8270
8271     @Override
8272     public final void notifyEnterAnimationComplete(IBinder token) {
8273         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
8274     }
8275
8276     @Override
8277     public String getCallingPackage(IBinder token) {
8278         synchronized (this) {
8279             ActivityRecord r = getCallingRecordLocked(token);
8280             return r != null ? r.info.packageName : null;
8281         }
8282     }
8283
8284     @Override
8285     public ComponentName getCallingActivity(IBinder token) {
8286         synchronized (this) {
8287             ActivityRecord r = getCallingRecordLocked(token);
8288             return r != null ? r.intent.getComponent() : null;
8289         }
8290     }
8291
8292     private ActivityRecord getCallingRecordLocked(IBinder token) {
8293         ActivityRecord r = ActivityRecord.isInStackLocked(token);
8294         if (r == null) {
8295             return null;
8296         }
8297         return r.resultTo;
8298     }
8299
8300     @Override
8301     public ComponentName getActivityClassForToken(IBinder token) {
8302         synchronized(this) {
8303             ActivityRecord r = ActivityRecord.isInStackLocked(token);
8304             if (r == null) {
8305                 return null;
8306             }
8307             return r.intent.getComponent();
8308         }
8309     }
8310
8311     @Override
8312     public String getPackageForToken(IBinder token) {
8313         synchronized(this) {
8314             ActivityRecord r = ActivityRecord.isInStackLocked(token);
8315             if (r == null) {
8316                 return null;
8317             }
8318             return r.packageName;
8319         }
8320     }
8321
8322     @Override
8323     public boolean isRootVoiceInteraction(IBinder token) {
8324         synchronized(this) {
8325             ActivityRecord r = ActivityRecord.isInStackLocked(token);
8326             if (r == null) {
8327                 return false;
8328             }
8329             return r.rootVoiceInteraction;
8330         }
8331     }
8332
8333     @Override
8334     public IIntentSender getIntentSender(int type,
8335             String packageName, IBinder token, String resultWho,
8336             int requestCode, Intent[] intents, String[] resolvedTypes,
8337             int flags, Bundle bOptions, int userId) {
8338         enforceNotIsolatedCaller("getIntentSender");
8339         // Refuse possible leaked file descriptors
8340         if (intents != null) {
8341             if (intents.length < 1) {
8342                 throw new IllegalArgumentException("Intents array length must be >= 1");
8343             }
8344             for (int i=0; i<intents.length; i++) {
8345                 Intent intent = intents[i];
8346                 if (intent != null) {
8347                     if (intent.hasFileDescriptors()) {
8348                         throw new IllegalArgumentException("File descriptors passed in Intent");
8349                     }
8350                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
8351                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
8352                         throw new IllegalArgumentException(
8353                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
8354                     }
8355                     intents[i] = new Intent(intent);
8356                 }
8357             }
8358             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
8359                 throw new IllegalArgumentException(
8360                         "Intent array length does not match resolvedTypes length");
8361             }
8362         }
8363         if (bOptions != null) {
8364             if (bOptions.hasFileDescriptors()) {
8365                 throw new IllegalArgumentException("File descriptors passed in options");
8366             }
8367         }
8368
8369         synchronized(this) {
8370             int callingUid = Binder.getCallingUid();
8371             int origUserId = userId;
8372             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8373                     type == ActivityManager.INTENT_SENDER_BROADCAST,
8374                     ALLOW_NON_FULL, "getIntentSender", null);
8375             if (origUserId == UserHandle.USER_CURRENT) {
8376                 // We don't want to evaluate this until the pending intent is
8377                 // actually executed.  However, we do want to always do the
8378                 // security checking for it above.
8379                 userId = UserHandle.USER_CURRENT;
8380             }
8381             try {
8382                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
8383                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
8384                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
8385                     if (!UserHandle.isSameApp(callingUid, uid)) {
8386                         String msg = "Permission Denial: getIntentSender() from pid="
8387                             + Binder.getCallingPid()
8388                             + ", uid=" + Binder.getCallingUid()
8389                             + ", (need uid=" + uid + ")"
8390                             + " is not allowed to send as package " + packageName;
8391                         Slog.w(TAG, msg);
8392                         throw new SecurityException(msg);
8393                     }
8394                 }
8395
8396                 return getIntentSenderLocked(type, packageName, callingUid, userId,
8397                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
8398
8399             } catch (RemoteException e) {
8400                 throw new SecurityException(e);
8401             }
8402         }
8403     }
8404
8405     IIntentSender getIntentSenderLocked(int type, String packageName,
8406             int callingUid, int userId, IBinder token, String resultWho,
8407             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
8408             Bundle bOptions) {
8409         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
8410         ActivityRecord activity = null;
8411         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8412             activity = ActivityRecord.isInStackLocked(token);
8413             if (activity == null) {
8414                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
8415                 return null;
8416             }
8417             if (activity.finishing) {
8418                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
8419                 return null;
8420             }
8421         }
8422
8423         // We're going to be splicing together extras before sending, so we're
8424         // okay poking into any contained extras.
8425         if (intents != null) {
8426             for (int i = 0; i < intents.length; i++) {
8427                 intents[i].setDefusable(true);
8428             }
8429         }
8430         Bundle.setDefusable(bOptions, true);
8431
8432         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
8433         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
8434         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
8435         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
8436                 |PendingIntent.FLAG_UPDATE_CURRENT);
8437
8438         PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
8439                 resultWho, requestCode, intents, resolvedTypes, flags,
8440                 SafeActivityOptions.fromBundle(bOptions), userId);
8441         WeakReference<PendingIntentRecord> ref;
8442         ref = mIntentSenderRecords.get(key);
8443         PendingIntentRecord rec = ref != null ? ref.get() : null;
8444         if (rec != null) {
8445             if (!cancelCurrent) {
8446                 if (updateCurrent) {
8447                     if (rec.key.requestIntent != null) {
8448                         rec.key.requestIntent.replaceExtras(intents != null ?
8449                                 intents[intents.length - 1] : null);
8450                     }
8451                     if (intents != null) {
8452                         intents[intents.length-1] = rec.key.requestIntent;
8453                         rec.key.allIntents = intents;
8454                         rec.key.allResolvedTypes = resolvedTypes;
8455                     } else {
8456                         rec.key.allIntents = null;
8457                         rec.key.allResolvedTypes = null;
8458                     }
8459                 }
8460                 return rec;
8461             }
8462             makeIntentSenderCanceledLocked(rec);
8463             mIntentSenderRecords.remove(key);
8464         }
8465         if (noCreate) {
8466             return rec;
8467         }
8468         rec = new PendingIntentRecord(this, key, callingUid);
8469         mIntentSenderRecords.put(key, rec.ref);
8470         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8471             if (activity.pendingResults == null) {
8472                 activity.pendingResults
8473                         = new HashSet<WeakReference<PendingIntentRecord>>();
8474             }
8475             activity.pendingResults.add(rec.ref);
8476         }
8477         return rec;
8478     }
8479
8480     @Override
8481     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
8482             Intent intent, String resolvedType,
8483             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
8484         if (target instanceof PendingIntentRecord) {
8485             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
8486                     whitelistToken, finishedReceiver, requiredPermission, options);
8487         } else {
8488             if (intent == null) {
8489                 // Weird case: someone has given us their own custom IIntentSender, and now
8490                 // they have someone else trying to send to it but of course this isn't
8491                 // really a PendingIntent, so there is no base Intent, and the caller isn't
8492                 // supplying an Intent... but we never want to dispatch a null Intent to
8493                 // a receiver, so um...  let's make something up.
8494                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
8495                 intent = new Intent(Intent.ACTION_MAIN);
8496             }
8497             try {
8498                 target.send(code, intent, resolvedType, whitelistToken, null,
8499                         requiredPermission, options);
8500             } catch (RemoteException e) {
8501             }
8502             // Platform code can rely on getting a result back when the send is done, but if
8503             // this intent sender is from outside of the system we can't rely on it doing that.
8504             // So instead we don't give it the result receiver, and instead just directly
8505             // report the finish immediately.
8506             if (finishedReceiver != null) {
8507                 try {
8508                     finishedReceiver.performReceive(intent, 0,
8509                             null, null, false, false, UserHandle.getCallingUserId());
8510                 } catch (RemoteException e) {
8511                 }
8512             }
8513             return 0;
8514         }
8515     }
8516
8517     @Override
8518     public void cancelIntentSender(IIntentSender sender) {
8519         if (!(sender instanceof PendingIntentRecord)) {
8520             return;
8521         }
8522         synchronized(this) {
8523             PendingIntentRecord rec = (PendingIntentRecord)sender;
8524             try {
8525                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8526                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8527                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8528                     String msg = "Permission Denial: cancelIntentSender() from pid="
8529                         + Binder.getCallingPid()
8530                         + ", uid=" + Binder.getCallingUid()
8531                         + " is not allowed to cancel package "
8532                         + rec.key.packageName;
8533                     Slog.w(TAG, msg);
8534                     throw new SecurityException(msg);
8535                 }
8536             } catch (RemoteException e) {
8537                 throw new SecurityException(e);
8538             }
8539             cancelIntentSenderLocked(rec, true);
8540         }
8541     }
8542
8543     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8544         makeIntentSenderCanceledLocked(rec);
8545         mIntentSenderRecords.remove(rec.key);
8546         if (cleanActivity && rec.key.activity != null) {
8547             rec.key.activity.pendingResults.remove(rec.ref);
8548         }
8549     }
8550
8551     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8552         rec.canceled = true;
8553         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8554         if (callbacks != null) {
8555             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8556         }
8557     }
8558
8559     @Override
8560     public String getPackageForIntentSender(IIntentSender pendingResult) {
8561         if (!(pendingResult instanceof PendingIntentRecord)) {
8562             return null;
8563         }
8564         try {
8565             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8566             return res.key.packageName;
8567         } catch (ClassCastException e) {
8568         }
8569         return null;
8570     }
8571
8572     @Override
8573     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8574         if (!(sender instanceof PendingIntentRecord)) {
8575             return;
8576         }
8577         boolean isCancelled;
8578         synchronized(this) {
8579             PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
8580             isCancelled = pendingIntent.canceled;
8581             if (!isCancelled) {
8582                 pendingIntent.registerCancelListenerLocked(receiver);
8583             }
8584         }
8585         if (isCancelled) {
8586             try {
8587                 receiver.send(Activity.RESULT_CANCELED, null);
8588             } catch (RemoteException e) {
8589             }
8590         }
8591     }
8592
8593     @Override
8594     public void unregisterIntentSenderCancelListener(IIntentSender sender,
8595             IResultReceiver receiver) {
8596         if (!(sender instanceof PendingIntentRecord)) {
8597             return;
8598         }
8599         synchronized(this) {
8600             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8601         }
8602     }
8603
8604     @Override
8605     public int getUidForIntentSender(IIntentSender sender) {
8606         if (sender instanceof PendingIntentRecord) {
8607             try {
8608                 PendingIntentRecord res = (PendingIntentRecord)sender;
8609                 return res.uid;
8610             } catch (ClassCastException e) {
8611             }
8612         }
8613         return -1;
8614     }
8615
8616     @Override
8617     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8618         if (!(pendingResult instanceof PendingIntentRecord)) {
8619             return false;
8620         }
8621         try {
8622             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8623             if (res.key.allIntents == null) {
8624                 return false;
8625             }
8626             for (int i=0; i<res.key.allIntents.length; i++) {
8627                 Intent intent = res.key.allIntents[i];
8628                 if (intent.getPackage() != null && intent.getComponent() != null) {
8629                     return false;
8630                 }
8631             }
8632             return true;
8633         } catch (ClassCastException e) {
8634         }
8635         return false;
8636     }
8637
8638     @Override
8639     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8640         if (!(pendingResult instanceof PendingIntentRecord)) {
8641             return false;
8642         }
8643         try {
8644             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8645             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8646                 return true;
8647             }
8648             return false;
8649         } catch (ClassCastException e) {
8650         }
8651         return false;
8652     }
8653
8654     @Override
8655     public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8656         if (pendingResult instanceof PendingIntentRecord) {
8657             final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8658             return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8659         }
8660         return false;
8661     }
8662
8663     @Override
8664     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8665         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8666                 "getIntentForIntentSender()");
8667         if (!(pendingResult instanceof PendingIntentRecord)) {
8668             return null;
8669         }
8670         try {
8671             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8672             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8673         } catch (ClassCastException e) {
8674         }
8675         return null;
8676     }
8677
8678     @Override
8679     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8680         if (!(pendingResult instanceof PendingIntentRecord)) {
8681             return null;
8682         }
8683         try {
8684             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8685             synchronized (this) {
8686                 return getTagForIntentSenderLocked(res, prefix);
8687             }
8688         } catch (ClassCastException e) {
8689         }
8690         return null;
8691     }
8692
8693     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8694         final Intent intent = res.key.requestIntent;
8695         if (intent != null) {
8696             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8697                     || res.lastTagPrefix.equals(prefix))) {
8698                 return res.lastTag;
8699             }
8700             res.lastTagPrefix = prefix;
8701             final StringBuilder sb = new StringBuilder(128);
8702             if (prefix != null) {
8703                 sb.append(prefix);
8704             }
8705             if (intent.getAction() != null) {
8706                 sb.append(intent.getAction());
8707             } else if (intent.getComponent() != null) {
8708                 intent.getComponent().appendShortString(sb);
8709             } else {
8710                 sb.append("?");
8711             }
8712             return res.lastTag = sb.toString();
8713         }
8714         return null;
8715     }
8716
8717     @Override
8718     public void setProcessLimit(int max) {
8719         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8720                 "setProcessLimit()");
8721         synchronized (this) {
8722             mConstants.setOverrideMaxCachedProcesses(max);
8723         }
8724         trimApplications();
8725     }
8726
8727     @Override
8728     public int getProcessLimit() {
8729         synchronized (this) {
8730             return mConstants.getOverrideMaxCachedProcesses();
8731         }
8732     }
8733
8734     void importanceTokenDied(ImportanceToken token) {
8735         synchronized (ActivityManagerService.this) {
8736             synchronized (mPidsSelfLocked) {
8737                 ImportanceToken cur
8738                     = mImportantProcesses.get(token.pid);
8739                 if (cur != token) {
8740                     return;
8741                 }
8742                 mImportantProcesses.remove(token.pid);
8743                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8744                 if (pr == null) {
8745                     return;
8746                 }
8747                 pr.forcingToImportant = null;
8748                 updateProcessForegroundLocked(pr, false, false);
8749             }
8750             updateOomAdjLocked();
8751         }
8752     }
8753
8754     @Override
8755     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8756         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8757                 "setProcessImportant()");
8758         synchronized(this) {
8759             boolean changed = false;
8760
8761             synchronized (mPidsSelfLocked) {
8762                 ProcessRecord pr = mPidsSelfLocked.get(pid);
8763                 if (pr == null && isForeground) {
8764                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8765                     return;
8766                 }
8767                 ImportanceToken oldToken = mImportantProcesses.get(pid);
8768                 if (oldToken != null) {
8769                     oldToken.token.unlinkToDeath(oldToken, 0);
8770                     mImportantProcesses.remove(pid);
8771                     if (pr != null) {
8772                         pr.forcingToImportant = null;
8773                     }
8774                     changed = true;
8775                 }
8776                 if (isForeground && token != null) {
8777                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8778                         @Override
8779                         public void binderDied() {
8780                             importanceTokenDied(this);
8781                         }
8782                     };
8783                     try {
8784                         token.linkToDeath(newToken, 0);
8785                         mImportantProcesses.put(pid, newToken);
8786                         pr.forcingToImportant = newToken;
8787                         changed = true;
8788                     } catch (RemoteException e) {
8789                         // If the process died while doing this, we will later
8790                         // do the cleanup with the process death link.
8791                     }
8792                 }
8793             }
8794
8795             if (changed) {
8796                 updateOomAdjLocked();
8797             }
8798         }
8799     }
8800
8801     @Override
8802     public boolean isAppForeground(int uid) {
8803         int callerUid = Binder.getCallingUid();
8804         if (UserHandle.isCore(callerUid) || callerUid == uid) {
8805             return isAppForegroundInternal(uid);
8806         }
8807         return false;
8808     }
8809
8810     private boolean isAppForegroundInternal(int uid) {
8811         synchronized (this) {
8812             UidRecord uidRec = mActiveUids.get(uid);
8813             if (uidRec == null || uidRec.idle) {
8814                 return false;
8815             }
8816             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8817         }
8818     }
8819
8820     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8821     // be guarded by permission checking.
8822     int getUidState(int uid) {
8823         synchronized (this) {
8824             return getUidStateLocked(uid);
8825         }
8826     }
8827
8828     int getUidStateLocked(int uid) {
8829         UidRecord uidRec = mActiveUids.get(uid);
8830         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8831     }
8832
8833     @Override
8834     public boolean isInMultiWindowMode(IBinder token) {
8835         final long origId = Binder.clearCallingIdentity();
8836         try {
8837             synchronized(this) {
8838                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8839                 if (r == null) {
8840                     return false;
8841                 }
8842                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8843                 return r.inMultiWindowMode();
8844             }
8845         } finally {
8846             Binder.restoreCallingIdentity(origId);
8847         }
8848     }
8849
8850     @Override
8851     public boolean isInPictureInPictureMode(IBinder token) {
8852         final long origId = Binder.clearCallingIdentity();
8853         try {
8854             synchronized(this) {
8855                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8856             }
8857         } finally {
8858             Binder.restoreCallingIdentity(origId);
8859         }
8860     }
8861
8862     private boolean isInPictureInPictureMode(ActivityRecord r) {
8863         if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8864                 || r.getStack().isInStackLocked(r) == null) {
8865             return false;
8866         }
8867
8868         // If we are animating to fullscreen then we have already dispatched the PIP mode
8869         // changed, so we should reflect that check here as well.
8870         final PinnedActivityStack stack = r.getStack();
8871         final PinnedStackWindowController windowController = stack.getWindowContainerController();
8872         return !windowController.isAnimatingBoundsToFullscreen();
8873     }
8874
8875     @Override
8876     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8877         final long origId = Binder.clearCallingIdentity();
8878         try {
8879             synchronized(this) {
8880                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8881                         "enterPictureInPictureMode", token, params);
8882
8883                 // If the activity is already in picture in picture mode, then just return early
8884                 if (isInPictureInPictureMode(r)) {
8885                     return true;
8886                 }
8887
8888                 // Activity supports picture-in-picture, now check that we can enter PiP at this
8889                 // point, if it is
8890                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8891                         false /* beforeStopping */)) {
8892                     return false;
8893                 }
8894
8895                 final Runnable enterPipRunnable = () -> {
8896                     // Only update the saved args from the args that are set
8897                     r.pictureInPictureArgs.copyOnlySet(params);
8898                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8899                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8900                     // Adjust the source bounds by the insets for the transition down
8901                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8902                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8903                             "enterPictureInPictureMode");
8904                     final PinnedActivityStack stack = r.getStack();
8905                     stack.setPictureInPictureAspectRatio(aspectRatio);
8906                     stack.setPictureInPictureActions(actions);
8907                     MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
8908                             r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
8909                     logPictureInPictureArgs(params);
8910                 };
8911
8912                 if (isKeyguardLocked()) {
8913                     // If the keyguard is showing or occluded, then try and dismiss it before
8914                     // entering picture-in-picture (this will prompt the user to authenticate if the
8915                     // device is currently locked).
8916                     try {
8917                         dismissKeyguard(token, new KeyguardDismissCallback() {
8918                             @Override
8919                             public void onDismissSucceeded() throws RemoteException {
8920                                 mHandler.post(enterPipRunnable);
8921                             }
8922                         }, null /* message */);
8923                     } catch (RemoteException e) {
8924                         // Local call
8925                     }
8926                 } else {
8927                     // Enter picture in picture immediately otherwise
8928                     enterPipRunnable.run();
8929                 }
8930                 return true;
8931             }
8932         } finally {
8933             Binder.restoreCallingIdentity(origId);
8934         }
8935     }
8936
8937     @Override
8938     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8939         final long origId = Binder.clearCallingIdentity();
8940         try {
8941             synchronized(this) {
8942                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8943                         "setPictureInPictureParams", token, params);
8944
8945                 // Only update the saved args from the args that are set
8946                 r.pictureInPictureArgs.copyOnlySet(params);
8947                 if (r.inPinnedWindowingMode()) {
8948                     // If the activity is already in picture-in-picture, update the pinned stack now
8949                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
8950                     // be used the next time the activity enters PiP
8951                     final PinnedActivityStack stack = r.getStack();
8952                     if (!stack.isAnimatingBoundsToFullscreen()) {
8953                         stack.setPictureInPictureAspectRatio(
8954                                 r.pictureInPictureArgs.getAspectRatio());
8955                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8956                     }
8957                 }
8958                 logPictureInPictureArgs(params);
8959             }
8960         } finally {
8961             Binder.restoreCallingIdentity(origId);
8962         }
8963     }
8964
8965     @Override
8966     public int getMaxNumPictureInPictureActions(IBinder token) {
8967         // Currently, this is a static constant, but later, we may change this to be dependent on
8968         // the context of the activity
8969         return 3;
8970     }
8971
8972     private void logPictureInPictureArgs(PictureInPictureParams params) {
8973         if (params.hasSetActions()) {
8974             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8975                     params.getActions().size());
8976         }
8977         if (params.hasSetAspectRatio()) {
8978             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8979             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8980             MetricsLogger.action(lm);
8981         }
8982     }
8983
8984     /**
8985      * Checks the state of the system and the activity associated with the given {@param token} to
8986      * verify that picture-in-picture is supported for that activity.
8987      *
8988      * @return the activity record for the given {@param token} if all the checks pass.
8989      */
8990     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8991             IBinder token, PictureInPictureParams params) {
8992         if (!mSupportsPictureInPicture) {
8993             throw new IllegalStateException(caller
8994                     + ": Device doesn't support picture-in-picture mode.");
8995         }
8996
8997         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8998         if (r == null) {
8999             throw new IllegalStateException(caller
9000                     + ": Can't find activity for token=" + token);
9001         }
9002
9003         if (!r.supportsPictureInPicture()) {
9004             throw new IllegalStateException(caller
9005                     + ": Current activity does not support picture-in-picture.");
9006         }
9007
9008         if (params.hasSetAspectRatio()
9009                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
9010                         params.getAspectRatio())) {
9011             final float minAspectRatio = mContext.getResources().getFloat(
9012                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
9013             final float maxAspectRatio = mContext.getResources().getFloat(
9014                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
9015             throw new IllegalArgumentException(String.format(caller
9016                     + ": Aspect ratio is too extreme (must be between %f and %f).",
9017                             minAspectRatio, maxAspectRatio));
9018         }
9019
9020         // Truncate the number of actions if necessary
9021         params.truncateActions(getMaxNumPictureInPictureActions(token));
9022
9023         return r;
9024     }
9025
9026     // =========================================================
9027     // PROCESS INFO
9028     // =========================================================
9029
9030     static class ProcessInfoService extends IProcessInfoService.Stub {
9031         final ActivityManagerService mActivityManagerService;
9032         ProcessInfoService(ActivityManagerService activityManagerService) {
9033             mActivityManagerService = activityManagerService;
9034         }
9035
9036         @Override
9037         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
9038             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
9039                     /*in*/ pids, /*out*/ states, null);
9040         }
9041
9042         @Override
9043         public void getProcessStatesAndOomScoresFromPids(
9044                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
9045             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
9046                     /*in*/ pids, /*out*/ states, /*out*/ scores);
9047         }
9048     }
9049
9050     /**
9051      * For each PID in the given input array, write the current process state
9052      * for that process into the states array, or -1 to indicate that no
9053      * process with the given PID exists. If scores array is provided, write
9054      * the oom score for the process into the scores array, with INVALID_ADJ
9055      * indicating the PID doesn't exist.
9056      */
9057     public void getProcessStatesAndOomScoresForPIDs(
9058             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
9059         if (scores != null) {
9060             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
9061                     "getProcessStatesAndOomScoresForPIDs()");
9062         }
9063
9064         if (pids == null) {
9065             throw new NullPointerException("pids");
9066         } else if (states == null) {
9067             throw new NullPointerException("states");
9068         } else if (pids.length != states.length) {
9069             throw new IllegalArgumentException("pids and states arrays have different lengths!");
9070         } else if (scores != null && pids.length != scores.length) {
9071             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
9072         }
9073
9074         synchronized (mPidsSelfLocked) {
9075             for (int i = 0; i < pids.length; i++) {
9076                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
9077                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
9078                         pr.curProcState;
9079                 if (scores != null) {
9080                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
9081                 }
9082             }
9083         }
9084     }
9085
9086     // =========================================================
9087     // PERMISSIONS
9088     // =========================================================
9089
9090     static class PermissionController extends IPermissionController.Stub {
9091         ActivityManagerService mActivityManagerService;
9092         PermissionController(ActivityManagerService activityManagerService) {
9093             mActivityManagerService = activityManagerService;
9094         }
9095
9096         @Override
9097         public boolean checkPermission(String permission, int pid, int uid) {
9098             return mActivityManagerService.checkPermission(permission, pid,
9099                     uid) == PackageManager.PERMISSION_GRANTED;
9100         }
9101
9102         @Override
9103         public int noteOp(String op, int uid, String packageName) {
9104             return mActivityManagerService.mAppOpsService
9105                     .noteOperation(AppOpsManager.strOpToOp(op), uid, packageName);
9106         }
9107
9108         @Override
9109         public String[] getPackagesForUid(int uid) {
9110             return mActivityManagerService.mContext.getPackageManager()
9111                     .getPackagesForUid(uid);
9112         }
9113
9114         @Override
9115         public boolean isRuntimePermission(String permission) {
9116             try {
9117                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
9118                         .getPermissionInfo(permission, 0);
9119                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
9120                         == PermissionInfo.PROTECTION_DANGEROUS;
9121             } catch (NameNotFoundException nnfe) {
9122                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
9123             }
9124             return false;
9125         }
9126
9127         @Override
9128         public int getPackageUid(String packageName, int flags) {
9129             try {
9130                 return mActivityManagerService.mContext.getPackageManager()
9131                         .getPackageUid(packageName, flags);
9132             } catch (NameNotFoundException nnfe) {
9133                 return -1;
9134             }
9135         }
9136     }
9137
9138     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
9139         @Override
9140         public int checkComponentPermission(String permission, int pid, int uid,
9141                 int owningUid, boolean exported) {
9142             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
9143                     owningUid, exported);
9144         }
9145
9146         @Override
9147         public Object getAMSLock() {
9148             return ActivityManagerService.this;
9149         }
9150     }
9151
9152     int checkComponentPermission(String permission, int pid, int uid,
9153             int owningUid, boolean exported) {
9154         if (pid == MY_PID) {
9155             return PackageManager.PERMISSION_GRANTED;
9156         }
9157         return ActivityManager.checkComponentPermission(permission, uid,
9158                 owningUid, exported);
9159     }
9160
9161     /**
9162      * As the only public entry point for permissions checking, this method
9163      * can enforce the semantic that requesting a check on a null global
9164      * permission is automatically denied.  (Internally a null permission
9165      * string is used when calling {@link #checkComponentPermission} in cases
9166      * when only uid-based security is needed.)
9167      *
9168      * This can be called with or without the global lock held.
9169      */
9170     @Override
9171     public int checkPermission(String permission, int pid, int uid) {
9172         if (permission == null) {
9173             return PackageManager.PERMISSION_DENIED;
9174         }
9175         return checkComponentPermission(permission, pid, uid, -1, true);
9176     }
9177
9178     @Override
9179     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
9180         if (permission == null) {
9181             return PackageManager.PERMISSION_DENIED;
9182         }
9183
9184         // We might be performing an operation on behalf of an indirect binder
9185         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
9186         // client identity accordingly before proceeding.
9187         Identity tlsIdentity = sCallerIdentity.get();
9188         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9189             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
9190                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
9191             uid = tlsIdentity.uid;
9192             pid = tlsIdentity.pid;
9193         }
9194
9195         return checkComponentPermission(permission, pid, uid, -1, true);
9196     }
9197
9198     /**
9199      * Binder IPC calls go through the public entry point.
9200      * This can be called with or without the global lock held.
9201      */
9202     int checkCallingPermission(String permission) {
9203         return checkPermission(permission,
9204                 Binder.getCallingPid(),
9205                 UserHandle.getAppId(Binder.getCallingUid()));
9206     }
9207
9208     /**
9209      * This can be called with or without the global lock held.
9210      */
9211     void enforceCallingPermission(String permission, String func) {
9212         if (checkCallingPermission(permission)
9213                 == PackageManager.PERMISSION_GRANTED) {
9214             return;
9215         }
9216
9217         String msg = "Permission Denial: " + func + " from pid="
9218                 + Binder.getCallingPid()
9219                 + ", uid=" + Binder.getCallingUid()
9220                 + " requires " + permission;
9221         Slog.w(TAG, msg);
9222         throw new SecurityException(msg);
9223     }
9224
9225     /**
9226      * This can be called with or without the global lock held.
9227      */
9228     void enforcePermission(String permission, int pid, int uid, String func) {
9229         if (checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) {
9230             return;
9231         }
9232
9233         String msg = "Permission Denial: " + func + " from pid=" + pid + ", uid=" + uid
9234                 + " requires " + permission;
9235         Slog.w(TAG, msg);
9236         throw new SecurityException(msg);
9237     }
9238
9239     /**
9240      * This can be called with or without the global lock held.
9241      */
9242     void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
9243         if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
9244             enforceCallingPermission(permission, func);
9245         }
9246     }
9247
9248     /**
9249      * Determine if UID is holding permissions required to access {@link Uri} in
9250      * the given {@link ProviderInfo}. Final permission checking is always done
9251      * in {@link ContentProvider}.
9252      */
9253     private final boolean checkHoldingPermissionsLocked(
9254             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
9255         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9256                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
9257         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
9258             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
9259                     != PERMISSION_GRANTED) {
9260                 return false;
9261             }
9262         }
9263         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
9264     }
9265
9266     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
9267             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
9268         if (pi.applicationInfo.uid == uid) {
9269             return true;
9270         } else if (!pi.exported) {
9271             return false;
9272         }
9273
9274         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
9275         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
9276         try {
9277             // check if target holds top-level <provider> permissions
9278             if (!readMet && pi.readPermission != null && considerUidPermissions
9279                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
9280                 readMet = true;
9281             }
9282             if (!writeMet && pi.writePermission != null && considerUidPermissions
9283                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
9284                 writeMet = true;
9285             }
9286
9287             // track if unprotected read/write is allowed; any denied
9288             // <path-permission> below removes this ability
9289             boolean allowDefaultRead = pi.readPermission == null;
9290             boolean allowDefaultWrite = pi.writePermission == null;
9291
9292             // check if target holds any <path-permission> that match uri
9293             final PathPermission[] pps = pi.pathPermissions;
9294             if (pps != null) {
9295                 final String path = grantUri.uri.getPath();
9296                 int i = pps.length;
9297                 while (i > 0 && (!readMet || !writeMet)) {
9298                     i--;
9299                     PathPermission pp = pps[i];
9300                     if (pp.match(path)) {
9301                         if (!readMet) {
9302                             final String pprperm = pp.getReadPermission();
9303                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9304                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
9305                                     + ": match=" + pp.match(path)
9306                                     + " check=" + pm.checkUidPermission(pprperm, uid));
9307                             if (pprperm != null) {
9308                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
9309                                         == PERMISSION_GRANTED) {
9310                                     readMet = true;
9311                                 } else {
9312                                     allowDefaultRead = false;
9313                                 }
9314                             }
9315                         }
9316                         if (!writeMet) {
9317                             final String ppwperm = pp.getWritePermission();
9318                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9319                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
9320                                     + ": match=" + pp.match(path)
9321                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
9322                             if (ppwperm != null) {
9323                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
9324                                         == PERMISSION_GRANTED) {
9325                                     writeMet = true;
9326                                 } else {
9327                                     allowDefaultWrite = false;
9328                                 }
9329                             }
9330                         }
9331                     }
9332                 }
9333             }
9334
9335             // grant unprotected <provider> read/write, if not blocked by
9336             // <path-permission> above
9337             if (allowDefaultRead) readMet = true;
9338             if (allowDefaultWrite) writeMet = true;
9339
9340         } catch (RemoteException e) {
9341             return false;
9342         }
9343
9344         return readMet && writeMet;
9345     }
9346
9347     public boolean isAppStartModeDisabled(int uid, String packageName) {
9348         synchronized (this) {
9349             return getAppStartModeLocked(uid, packageName, 0, -1, false, true, false)
9350                     == ActivityManager.APP_START_MODE_DISABLED;
9351         }
9352     }
9353
9354     // Unified app-op and target sdk check
9355     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9356         // Apps that target O+ are always subject to background check
9357         if (packageTargetSdk >= Build.VERSION_CODES.O) {
9358             if (DEBUG_BACKGROUND_CHECK) {
9359                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
9360             }
9361             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9362         }
9363         // ...and legacy apps get an AppOp check
9364         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
9365                 uid, packageName);
9366         if (DEBUG_BACKGROUND_CHECK) {
9367             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
9368         }
9369         switch (appop) {
9370             case AppOpsManager.MODE_ALLOWED:
9371                 // If force-background-check is enabled, restrict all apps that aren't whitelisted.
9372                 if (mForceBackgroundCheck &&
9373                         !UserHandle.isCore(uid) &&
9374                         !isOnDeviceIdleWhitelistLocked(uid, /*allowExceptIdleToo=*/ true)) {
9375                     if (DEBUG_BACKGROUND_CHECK) {
9376                         Slog.i(TAG, "Force background check: " +
9377                                 uid + "/" + packageName + " restricted");
9378                     }
9379                     return ActivityManager.APP_START_MODE_DELAYED;
9380                 }
9381                 return ActivityManager.APP_START_MODE_NORMAL;
9382             case AppOpsManager.MODE_IGNORED:
9383                 return ActivityManager.APP_START_MODE_DELAYED;
9384             default:
9385                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9386         }
9387     }
9388
9389     // Service launch is available to apps with run-in-background exemptions but
9390     // some other background operations are not.  If we're doing a check
9391     // of service-launch policy, allow those callers to proceed unrestricted.
9392     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9393         // Persistent app?
9394         if (mPackageManagerInt.isPackagePersistent(packageName)) {
9395             if (DEBUG_BACKGROUND_CHECK) {
9396                 Slog.i(TAG, "App " + uid + "/" + packageName
9397                         + " is persistent; not restricted in background");
9398             }
9399             return ActivityManager.APP_START_MODE_NORMAL;
9400         }
9401
9402         // Non-persistent but background whitelisted?
9403         if (uidOnBackgroundWhitelist(uid)) {
9404             if (DEBUG_BACKGROUND_CHECK) {
9405                 Slog.i(TAG, "App " + uid + "/" + packageName
9406                         + " on background whitelist; not restricted in background");
9407             }
9408             return ActivityManager.APP_START_MODE_NORMAL;
9409         }
9410
9411         // Is this app on the battery whitelist?
9412         if (isOnDeviceIdleWhitelistLocked(uid, /*allowExceptIdleToo=*/ false)) {
9413             if (DEBUG_BACKGROUND_CHECK) {
9414                 Slog.i(TAG, "App " + uid + "/" + packageName
9415                         + " on idle whitelist; not restricted in background");
9416             }
9417             return ActivityManager.APP_START_MODE_NORMAL;
9418         }
9419
9420         // None of the service-policy criteria apply, so we apply the common criteria
9421         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
9422     }
9423
9424     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
9425             int callingPid, boolean alwaysRestrict, boolean disabledOnly, boolean forcedStandby) {
9426         UidRecord uidRec = mActiveUids.get(uid);
9427         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
9428                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
9429                 + (uidRec != null ? uidRec.idle : false));
9430         if (uidRec == null || alwaysRestrict || forcedStandby || uidRec.idle) {
9431             boolean ephemeral;
9432             if (uidRec == null) {
9433                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
9434                         UserHandle.getUserId(uid), packageName);
9435             } else {
9436                 ephemeral = uidRec.ephemeral;
9437             }
9438
9439             if (ephemeral) {
9440                 // We are hard-core about ephemeral apps not running in the background.
9441                 return ActivityManager.APP_START_MODE_DISABLED;
9442             } else {
9443                 if (disabledOnly) {
9444                     // The caller is only interested in whether app starts are completely
9445                     // disabled for the given package (that is, it is an instant app).  So
9446                     // we don't need to go further, which is all just seeing if we should
9447                     // apply a "delayed" mode for a regular app.
9448                     return ActivityManager.APP_START_MODE_NORMAL;
9449                 }
9450                 final int startMode = (alwaysRestrict)
9451                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
9452                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
9453                                 packageTargetSdk);
9454                 if (DEBUG_BACKGROUND_CHECK) {
9455                     Slog.d(TAG, "checkAllowBackground: uid=" + uid
9456                             + " pkg=" + packageName + " startMode=" + startMode
9457                             + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid, false)
9458                             + " onwhitelist(ei)=" + isOnDeviceIdleWhitelistLocked(uid, true));
9459                 }
9460                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
9461                     // This is an old app that has been forced into a "compatible as possible"
9462                     // mode of background check.  To increase compatibility, we will allow other
9463                     // foreground apps to cause its services to start.
9464                     if (callingPid >= 0) {
9465                         ProcessRecord proc;
9466                         synchronized (mPidsSelfLocked) {
9467                             proc = mPidsSelfLocked.get(callingPid);
9468                         }
9469                         if (proc != null &&
9470                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
9471                             // Whoever is instigating this is in the foreground, so we will allow it
9472                             // to go through.
9473                             return ActivityManager.APP_START_MODE_NORMAL;
9474                         }
9475                     }
9476                 }
9477                 return startMode;
9478             }
9479         }
9480         return ActivityManager.APP_START_MODE_NORMAL;
9481     }
9482
9483     /**
9484      * @return whether a UID is in the system, user or temp doze whitelist.
9485      */
9486     boolean isOnDeviceIdleWhitelistLocked(int uid, boolean allowExceptIdleToo) {
9487         final int appId = UserHandle.getAppId(uid);
9488
9489         final int[] whitelist = allowExceptIdleToo
9490                 ? mDeviceIdleExceptIdleWhitelist
9491                 : mDeviceIdleWhitelist;
9492
9493         return Arrays.binarySearch(whitelist, appId) >= 0
9494                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9495                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9496     }
9497
9498     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9499         ProviderInfo pi = null;
9500         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9501         if (cpr != null) {
9502             pi = cpr.info;
9503         } else {
9504             try {
9505                 pi = AppGlobals.getPackageManager().resolveContentProvider(
9506                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9507                         userHandle);
9508             } catch (RemoteException ex) {
9509             }
9510         }
9511         return pi;
9512     }
9513
9514     void grantEphemeralAccessLocked(int userId, Intent intent,
9515             int targetAppId, int ephemeralAppId) {
9516         getPackageManagerInternalLocked().
9517                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
9518     }
9519
9520     @GuardedBy("this")
9521     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
9522         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9523         if (targetUris != null) {
9524             return targetUris.get(grantUri);
9525         }
9526         return null;
9527     }
9528
9529     @GuardedBy("this")
9530     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
9531             String targetPkg, int targetUid, GrantUri grantUri) {
9532         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9533         if (targetUris == null) {
9534             targetUris = Maps.newArrayMap();
9535             mGrantedUriPermissions.put(targetUid, targetUris);
9536         }
9537
9538         UriPermission perm = targetUris.get(grantUri);
9539         if (perm == null) {
9540             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9541             targetUris.put(grantUri, perm);
9542         }
9543
9544         return perm;
9545     }
9546
9547     @GuardedBy("this")
9548     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
9549             final int modeFlags) {
9550         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
9551         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9552                 : UriPermission.STRENGTH_OWNED;
9553
9554         // Root gets to do everything.
9555         if (uid == 0) {
9556             return true;
9557         }
9558
9559         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9560         if (perms == null) return false;
9561
9562         // First look for exact match
9563         final UriPermission exactPerm = perms.get(grantUri);
9564         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9565             return true;
9566         }
9567
9568         // No exact match, look for prefixes
9569         final int N = perms.size();
9570         for (int i = 0; i < N; i++) {
9571             final UriPermission perm = perms.valueAt(i);
9572             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9573                     && perm.getStrength(modeFlags) >= minStrength) {
9574                 return true;
9575             }
9576         }
9577
9578         return false;
9579     }
9580
9581     /**
9582      * @param uri This uri must NOT contain an embedded userId.
9583      * @param userId The userId in which the uri is to be resolved.
9584      */
9585     @Override
9586     public int checkUriPermission(Uri uri, int pid, int uid,
9587             final int modeFlags, int userId, IBinder callerToken) {
9588         enforceNotIsolatedCaller("checkUriPermission");
9589
9590         // Another redirected-binder-call permissions check as in
9591         // {@link checkPermissionWithToken}.
9592         Identity tlsIdentity = sCallerIdentity.get();
9593         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9594             uid = tlsIdentity.uid;
9595             pid = tlsIdentity.pid;
9596         }
9597
9598         // Our own process gets to do everything.
9599         if (pid == MY_PID) {
9600             return PackageManager.PERMISSION_GRANTED;
9601         }
9602         synchronized (this) {
9603             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9604                     ? PackageManager.PERMISSION_GRANTED
9605                     : PackageManager.PERMISSION_DENIED;
9606         }
9607     }
9608
9609     /**
9610      * Check if the targetPkg can be granted permission to access uri by
9611      * the callingUid using the given modeFlags.  Throws a security exception
9612      * if callingUid is not allowed to do this.  Returns the uid of the target
9613      * if the URI permission grant should be performed; returns -1 if it is not
9614      * needed (for example targetPkg already has permission to access the URI).
9615      * If you already know the uid of the target, you can supply it in
9616      * lastTargetUid else set that to -1.
9617      */
9618     @GuardedBy("this")
9619     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9620             final int modeFlags, int lastTargetUid) {
9621         if (!Intent.isAccessUriMode(modeFlags)) {
9622             return -1;
9623         }
9624
9625         if (targetPkg != null) {
9626             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9627                     "Checking grant " + targetPkg + " permission to " + grantUri);
9628         }
9629
9630         final IPackageManager pm = AppGlobals.getPackageManager();
9631
9632         // If this is not a content: uri, we can't do anything with it.
9633         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9634             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9635                     "Can't grant URI permission for non-content URI: " + grantUri);
9636             return -1;
9637         }
9638
9639         // Bail early if system is trying to hand out permissions directly; it
9640         // must always grant permissions on behalf of someone explicit.
9641         final int callingAppId = UserHandle.getAppId(callingUid);
9642         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9643             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9644                 // Exempted authority for
9645                 // 1. cropping user photos and sharing a generated license html
9646                 //    file in Settings app
9647                 // 2. sharing a generated license html file in TvSettings app
9648             } else {
9649                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9650                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9651                 return -1;
9652             }
9653         }
9654
9655         final String authority = grantUri.uri.getAuthority();
9656         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9657                 MATCH_DEBUG_TRIAGED_MISSING);
9658         if (pi == null) {
9659             Slog.w(TAG, "No content provider found for permission check: " +
9660                     grantUri.uri.toSafeString());
9661             return -1;
9662         }
9663
9664         int targetUid = lastTargetUid;
9665         if (targetUid < 0 && targetPkg != null) {
9666             try {
9667                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9668                         UserHandle.getUserId(callingUid));
9669                 if (targetUid < 0) {
9670                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9671                             "Can't grant URI permission no uid for: " + targetPkg);
9672                     return -1;
9673                 }
9674             } catch (RemoteException ex) {
9675                 return -1;
9676             }
9677         }
9678
9679         // Figure out the value returned when access is allowed
9680         final int allowedResult;
9681         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9682             // If we're extending a persistable grant, then we need to return
9683             // "targetUid" so that we always create a grant data structure to
9684             // support take/release APIs
9685             allowedResult = targetUid;
9686         } else {
9687             // Otherwise, we can return "-1" to indicate that no grant data
9688             // structures need to be created
9689             allowedResult = -1;
9690         }
9691
9692         if (targetUid >= 0) {
9693             // First...  does the target actually need this permission?
9694             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9695                 // No need to grant the target this permission.
9696                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9697                         "Target " + targetPkg + " already has full permission to " + grantUri);
9698                 return allowedResult;
9699             }
9700         } else {
9701             // First...  there is no target package, so can anyone access it?
9702             boolean allowed = pi.exported;
9703             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9704                 if (pi.readPermission != null) {
9705                     allowed = false;
9706                 }
9707             }
9708             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9709                 if (pi.writePermission != null) {
9710                     allowed = false;
9711                 }
9712             }
9713             if (pi.pathPermissions != null) {
9714                 final int N = pi.pathPermissions.length;
9715                 for (int i=0; i<N; i++) {
9716                     if (pi.pathPermissions[i] != null
9717                             && pi.pathPermissions[i].match(grantUri.uri.getPath())) {
9718                         if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9719                             if (pi.pathPermissions[i].getReadPermission() != null) {
9720                                 allowed = false;
9721                             }
9722                         }
9723                         if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9724                             if (pi.pathPermissions[i].getWritePermission() != null) {
9725                                 allowed = false;
9726                             }
9727                         }
9728                         break;
9729                     }
9730                 }
9731             }
9732             if (allowed) {
9733                 return allowedResult;
9734             }
9735         }
9736
9737         /* There is a special cross user grant if:
9738          * - The target is on another user.
9739          * - Apps on the current user can access the uri without any uid permissions.
9740          * In this case, we grant a uri permission, even if the ContentProvider does not normally
9741          * grant uri permissions.
9742          */
9743         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9744                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9745                 modeFlags, false /*without considering the uid permissions*/);
9746
9747         // Second...  is the provider allowing granting of URI permissions?
9748         if (!specialCrossUserGrant) {
9749             if (!pi.grantUriPermissions) {
9750                 throw new SecurityException("Provider " + pi.packageName
9751                         + "/" + pi.name
9752                         + " does not allow granting of Uri permissions (uri "
9753                         + grantUri + ")");
9754             }
9755             if (pi.uriPermissionPatterns != null) {
9756                 final int N = pi.uriPermissionPatterns.length;
9757                 boolean allowed = false;
9758                 for (int i=0; i<N; i++) {
9759                     if (pi.uriPermissionPatterns[i] != null
9760                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9761                         allowed = true;
9762                         break;
9763                     }
9764                 }
9765                 if (!allowed) {
9766                     throw new SecurityException("Provider " + pi.packageName
9767                             + "/" + pi.name
9768                             + " does not allow granting of permission to path of Uri "
9769                             + grantUri);
9770                 }
9771             }
9772         }
9773
9774         // Third...  does the caller itself have permission to access
9775         // this uri?
9776         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9777             // Require they hold a strong enough Uri permission
9778             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9779                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9780                     throw new SecurityException(
9781                             "UID " + callingUid + " does not have permission to " + grantUri
9782                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9783                                     + "or related APIs");
9784                 } else {
9785                     throw new SecurityException(
9786                             "UID " + callingUid + " does not have permission to " + grantUri);
9787                 }
9788             }
9789         }
9790         return targetUid;
9791     }
9792
9793     /**
9794      * @param uri This uri must NOT contain an embedded userId.
9795      * @param userId The userId in which the uri is to be resolved.
9796      */
9797     @Override
9798     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9799             final int modeFlags, int userId) {
9800         enforceNotIsolatedCaller("checkGrantUriPermission");
9801         synchronized(this) {
9802             return checkGrantUriPermissionLocked(callingUid, targetPkg,
9803                     new GrantUri(userId, uri, false), modeFlags, -1);
9804         }
9805     }
9806
9807     @GuardedBy("this")
9808     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9809             final int modeFlags, UriPermissionOwner owner) {
9810         if (!Intent.isAccessUriMode(modeFlags)) {
9811             return;
9812         }
9813
9814         // So here we are: the caller has the assumed permission
9815         // to the uri, and the target doesn't.  Let's now give this to
9816         // the target.
9817
9818         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9819                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9820
9821         final String authority = grantUri.uri.getAuthority();
9822         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9823                 MATCH_DEBUG_TRIAGED_MISSING);
9824         if (pi == null) {
9825             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9826             return;
9827         }
9828
9829         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9830             grantUri.prefix = true;
9831         }
9832         final UriPermission perm = findOrCreateUriPermissionLocked(
9833                 pi.packageName, targetPkg, targetUid, grantUri);
9834         perm.grantModes(modeFlags, owner);
9835     }
9836
9837     @GuardedBy("this")
9838     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9839             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9840         if (targetPkg == null) {
9841             throw new NullPointerException("targetPkg");
9842         }
9843         int targetUid;
9844         final IPackageManager pm = AppGlobals.getPackageManager();
9845         try {
9846             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9847         } catch (RemoteException ex) {
9848             return;
9849         }
9850
9851         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9852                 targetUid);
9853         if (targetUid < 0) {
9854             return;
9855         }
9856
9857         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9858                 owner);
9859     }
9860
9861     static class NeededUriGrants extends ArrayList<GrantUri> {
9862         final String targetPkg;
9863         final int targetUid;
9864         final int flags;
9865
9866         NeededUriGrants(String targetPkg, int targetUid, int flags) {
9867             this.targetPkg = targetPkg;
9868             this.targetUid = targetUid;
9869             this.flags = flags;
9870         }
9871
9872         void writeToProto(ProtoOutputStream proto, long fieldId) {
9873             long token = proto.start(fieldId);
9874             proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9875             proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9876             proto.write(NeededUriGrantsProto.FLAGS, flags);
9877
9878             final int N = this.size();
9879             for (int i=0; i<N; i++) {
9880                 this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9881             }
9882             proto.end(token);
9883         }
9884     }
9885
9886     /**
9887      * Like checkGrantUriPermissionLocked, but takes an Intent.
9888      */
9889     @GuardedBy("this")
9890     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9891             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9892         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9893                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9894                 + " clip=" + (intent != null ? intent.getClipData() : null)
9895                 + " from " + intent + "; flags=0x"
9896                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9897
9898         if (targetPkg == null) {
9899             throw new NullPointerException("targetPkg");
9900         }
9901
9902         if (intent == null) {
9903             return null;
9904         }
9905         Uri data = intent.getData();
9906         ClipData clip = intent.getClipData();
9907         if (data == null && clip == null) {
9908             return null;
9909         }
9910         // Default userId for uris in the intent (if they don't specify it themselves)
9911         int contentUserHint = intent.getContentUserHint();
9912         if (contentUserHint == UserHandle.USER_CURRENT) {
9913             contentUserHint = UserHandle.getUserId(callingUid);
9914         }
9915         final IPackageManager pm = AppGlobals.getPackageManager();
9916         int targetUid;
9917         if (needed != null) {
9918             targetUid = needed.targetUid;
9919         } else {
9920             try {
9921                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9922                         targetUserId);
9923             } catch (RemoteException ex) {
9924                 return null;
9925             }
9926             if (targetUid < 0) {
9927                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9928                         "Can't grant URI permission no uid for: " + targetPkg
9929                         + " on user " + targetUserId);
9930                 return null;
9931             }
9932         }
9933         if (data != null) {
9934             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9935             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9936                     targetUid);
9937             if (targetUid > 0) {
9938                 if (needed == null) {
9939                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
9940                 }
9941                 needed.add(grantUri);
9942             }
9943         }
9944         if (clip != null) {
9945             for (int i=0; i<clip.getItemCount(); i++) {
9946                 Uri uri = clip.getItemAt(i).getUri();
9947                 if (uri != null) {
9948                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9949                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9950                             targetUid);
9951                     if (targetUid > 0) {
9952                         if (needed == null) {
9953                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
9954                         }
9955                         needed.add(grantUri);
9956                     }
9957                 } else {
9958                     Intent clipIntent = clip.getItemAt(i).getIntent();
9959                     if (clipIntent != null) {
9960                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9961                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9962                         if (newNeeded != null) {
9963                             needed = newNeeded;
9964                         }
9965                     }
9966                 }
9967             }
9968         }
9969
9970         return needed;
9971     }
9972
9973     /**
9974      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9975      */
9976     @GuardedBy("this")
9977     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9978             UriPermissionOwner owner) {
9979         if (needed != null) {
9980             for (int i=0; i<needed.size(); i++) {
9981                 GrantUri grantUri = needed.get(i);
9982                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9983                         grantUri, needed.flags, owner);
9984             }
9985         }
9986     }
9987
9988     @GuardedBy("this")
9989     void grantUriPermissionFromIntentLocked(int callingUid,
9990             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9991         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9992                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9993         if (needed == null) {
9994             return;
9995         }
9996
9997         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9998     }
9999
10000     /**
10001      * @param uri This uri must NOT contain an embedded userId.
10002      * @param userId The userId in which the uri is to be resolved.
10003      */
10004     @Override
10005     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
10006             final int modeFlags, int userId) {
10007         enforceNotIsolatedCaller("grantUriPermission");
10008         GrantUri grantUri = new GrantUri(userId, uri, false);
10009         synchronized(this) {
10010             final ProcessRecord r = getRecordForAppLocked(caller);
10011             if (r == null) {
10012                 throw new SecurityException("Unable to find app for caller "
10013                         + caller
10014                         + " when granting permission to uri " + grantUri);
10015             }
10016             if (targetPkg == null) {
10017                 throw new IllegalArgumentException("null target");
10018             }
10019             if (grantUri == null) {
10020                 throw new IllegalArgumentException("null uri");
10021             }
10022
10023             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
10024                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
10025                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
10026                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
10027
10028             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
10029                     UserHandle.getUserId(r.uid));
10030         }
10031     }
10032
10033     @GuardedBy("this")
10034     void removeUriPermissionIfNeededLocked(UriPermission perm) {
10035         if (perm.modeFlags == 0) {
10036             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10037                     perm.targetUid);
10038             if (perms != null) {
10039                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10040                         "Removing " + perm.targetUid + " permission to " + perm.uri);
10041
10042                 perms.remove(perm.uri);
10043                 if (perms.isEmpty()) {
10044                     mGrantedUriPermissions.remove(perm.targetUid);
10045                 }
10046             }
10047         }
10048     }
10049
10050     @GuardedBy("this")
10051     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
10052             final int modeFlags) {
10053         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10054                 "Revoking all granted permissions to " + grantUri);
10055
10056         final IPackageManager pm = AppGlobals.getPackageManager();
10057         final String authority = grantUri.uri.getAuthority();
10058         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
10059                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
10060         if (pi == null) {
10061             Slog.w(TAG, "No content provider found for permission revoke: "
10062                     + grantUri.toSafeString());
10063             return;
10064         }
10065
10066         // Does the caller have this permission on the URI?
10067         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
10068             // If they don't have direct access to the URI, then revoke any
10069             // ownerless URI permissions that have been granted to them.
10070             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10071             if (perms != null) {
10072                 boolean persistChanged = false;
10073                 for (int i = perms.size()-1; i >= 0; i--) {
10074                     final UriPermission perm = perms.valueAt(i);
10075                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
10076                         continue;
10077                     }
10078                     if (perm.uri.sourceUserId == grantUri.sourceUserId
10079                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
10080                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10081                                 "Revoking non-owned " + perm.targetUid
10082                                 + " permission to " + perm.uri);
10083                         persistChanged |= perm.revokeModes(
10084                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
10085                         if (perm.modeFlags == 0) {
10086                             perms.removeAt(i);
10087                         }
10088                     }
10089                 }
10090                 if (perms.isEmpty()) {
10091                     mGrantedUriPermissions.remove(callingUid);
10092                 }
10093                 if (persistChanged) {
10094                     schedulePersistUriGrants();
10095                 }
10096             }
10097             return;
10098         }
10099
10100         boolean persistChanged = false;
10101
10102         // Go through all of the permissions and remove any that match.
10103         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
10104             final int targetUid = mGrantedUriPermissions.keyAt(i);
10105             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10106
10107             for (int j = perms.size()-1; j >= 0; j--) {
10108                 final UriPermission perm = perms.valueAt(j);
10109                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
10110                     continue;
10111                 }
10112                 if (perm.uri.sourceUserId == grantUri.sourceUserId
10113                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
10114                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10115                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
10116                     persistChanged |= perm.revokeModes(
10117                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
10118                             targetPackage == null);
10119                     if (perm.modeFlags == 0) {
10120                         perms.removeAt(j);
10121                     }
10122                 }
10123             }
10124
10125             if (perms.isEmpty()) {
10126                 mGrantedUriPermissions.removeAt(i);
10127             }
10128         }
10129
10130         if (persistChanged) {
10131             schedulePersistUriGrants();
10132         }
10133     }
10134
10135     /**
10136      * @param uri This uri must NOT contain an embedded userId.
10137      * @param userId The userId in which the uri is to be resolved.
10138      */
10139     @Override
10140     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
10141             final int modeFlags, int userId) {
10142         enforceNotIsolatedCaller("revokeUriPermission");
10143         synchronized(this) {
10144             final ProcessRecord r = getRecordForAppLocked(caller);
10145             if (r == null) {
10146                 throw new SecurityException("Unable to find app for caller "
10147                         + caller
10148                         + " when revoking permission to uri " + uri);
10149             }
10150             if (uri == null) {
10151                 Slog.w(TAG, "revokeUriPermission: null uri");
10152                 return;
10153             }
10154
10155             if (!Intent.isAccessUriMode(modeFlags)) {
10156                 return;
10157             }
10158
10159             final String authority = uri.getAuthority();
10160             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
10161                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
10162             if (pi == null) {
10163                 Slog.w(TAG, "No content provider found for permission revoke: "
10164                         + uri.toSafeString());
10165                 return;
10166             }
10167
10168             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
10169                     modeFlags);
10170         }
10171     }
10172
10173     /**
10174      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
10175      * given package.
10176      *
10177      * @param packageName Package name to match, or {@code null} to apply to all
10178      *            packages.
10179      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
10180      *            to all users.
10181      * @param persistable If persistable grants should be removed.
10182      * @param targetOnly When {@code true}, only remove permissions where the app is the target,
10183      * not source.
10184      */
10185     @GuardedBy("this")
10186     private void removeUriPermissionsForPackageLocked(
10187             String packageName, int userHandle, boolean persistable, boolean targetOnly) {
10188         if (userHandle == UserHandle.USER_ALL && packageName == null) {
10189             throw new IllegalArgumentException("Must narrow by either package or user");
10190         }
10191
10192         boolean persistChanged = false;
10193
10194         int N = mGrantedUriPermissions.size();
10195         for (int i = 0; i < N; i++) {
10196             final int targetUid = mGrantedUriPermissions.keyAt(i);
10197             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10198
10199             // Only inspect grants matching user
10200             if (userHandle == UserHandle.USER_ALL
10201                     || userHandle == UserHandle.getUserId(targetUid)) {
10202                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
10203                     final UriPermission perm = it.next();
10204
10205                     // Only inspect grants matching package
10206                     if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
10207                             || perm.targetPkg.equals(packageName)) {
10208                         // Hacky solution as part of fixing a security bug; ignore
10209                         // grants associated with DownloadManager so we don't have
10210                         // to immediately launch it to regrant the permissions
10211                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
10212                                 && !persistable) continue;
10213
10214                         persistChanged |= perm.revokeModes(persistable
10215                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
10216
10217                         // Only remove when no modes remain; any persisted grants
10218                         // will keep this alive.
10219                         if (perm.modeFlags == 0) {
10220                             it.remove();
10221                         }
10222                     }
10223                 }
10224
10225                 if (perms.isEmpty()) {
10226                     mGrantedUriPermissions.remove(targetUid);
10227                     N--;
10228                     i--;
10229                 }
10230             }
10231         }
10232
10233         if (persistChanged) {
10234             schedulePersistUriGrants();
10235         }
10236     }
10237
10238     @Override
10239     public IBinder newUriPermissionOwner(String name) {
10240         enforceNotIsolatedCaller("newUriPermissionOwner");
10241         synchronized(this) {
10242             UriPermissionOwner owner = new UriPermissionOwner(this, name);
10243             return owner.getExternalTokenLocked();
10244         }
10245     }
10246
10247     @Override
10248     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
10249         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
10250         synchronized(this) {
10251             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10252             if (r == null) {
10253                 throw new IllegalArgumentException("Activity does not exist; token="
10254                         + activityToken);
10255             }
10256             return r.getUriPermissionsLocked().getExternalTokenLocked();
10257         }
10258     }
10259     /**
10260      * @param uri This uri must NOT contain an embedded userId.
10261      * @param sourceUserId The userId in which the uri is to be resolved.
10262      * @param targetUserId The userId of the app that receives the grant.
10263      */
10264     @Override
10265     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
10266             final int modeFlags, int sourceUserId, int targetUserId) {
10267         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
10268                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
10269                 "grantUriPermissionFromOwner", null);
10270         synchronized(this) {
10271             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10272             if (owner == null) {
10273                 throw new IllegalArgumentException("Unknown owner: " + token);
10274             }
10275             if (fromUid != Binder.getCallingUid()) {
10276                 if (Binder.getCallingUid() != myUid()) {
10277                     // Only system code can grant URI permissions on behalf
10278                     // of other users.
10279                     throw new SecurityException("nice try");
10280                 }
10281             }
10282             if (targetPkg == null) {
10283                 throw new IllegalArgumentException("null target");
10284             }
10285             if (uri == null) {
10286                 throw new IllegalArgumentException("null uri");
10287             }
10288
10289             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
10290                     modeFlags, owner, targetUserId);
10291         }
10292     }
10293
10294     /**
10295      * @param uri This uri must NOT contain an embedded userId.
10296      * @param userId The userId in which the uri is to be resolved.
10297      */
10298     @Override
10299     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
10300         synchronized(this) {
10301             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10302             if (owner == null) {
10303                 throw new IllegalArgumentException("Unknown owner: " + token);
10304             }
10305
10306             if (uri == null) {
10307                 owner.removeUriPermissionsLocked(mode);
10308             } else {
10309                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
10310                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
10311             }
10312         }
10313     }
10314
10315     private void schedulePersistUriGrants() {
10316         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
10317             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
10318                     10 * DateUtils.SECOND_IN_MILLIS);
10319         }
10320     }
10321
10322     private void writeGrantedUriPermissions() {
10323         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
10324
10325         final long startTime = SystemClock.uptimeMillis();
10326
10327         // Snapshot permissions so we can persist without lock
10328         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
10329         synchronized (this) {
10330             final int size = mGrantedUriPermissions.size();
10331             for (int i = 0; i < size; i++) {
10332                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10333                 for (UriPermission perm : perms.values()) {
10334                     if (perm.persistedModeFlags != 0) {
10335                         persist.add(perm.snapshot());
10336                     }
10337                 }
10338             }
10339         }
10340
10341         FileOutputStream fos = null;
10342         try {
10343             fos = mGrantFile.startWrite(startTime);
10344
10345             XmlSerializer out = new FastXmlSerializer();
10346             out.setOutput(fos, StandardCharsets.UTF_8.name());
10347             out.startDocument(null, true);
10348             out.startTag(null, TAG_URI_GRANTS);
10349             for (UriPermission.Snapshot perm : persist) {
10350                 out.startTag(null, TAG_URI_GRANT);
10351                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
10352                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
10353                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
10354                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
10355                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
10356                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
10357                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
10358                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
10359                 out.endTag(null, TAG_URI_GRANT);
10360             }
10361             out.endTag(null, TAG_URI_GRANTS);
10362             out.endDocument();
10363
10364             mGrantFile.finishWrite(fos);
10365         } catch (IOException e) {
10366             if (fos != null) {
10367                 mGrantFile.failWrite(fos);
10368             }
10369         }
10370     }
10371
10372     @GuardedBy("this")
10373     private void readGrantedUriPermissionsLocked() {
10374         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
10375
10376         final long now = System.currentTimeMillis();
10377
10378         FileInputStream fis = null;
10379         try {
10380             fis = mGrantFile.openRead();
10381             final XmlPullParser in = Xml.newPullParser();
10382             in.setInput(fis, StandardCharsets.UTF_8.name());
10383
10384             int type;
10385             while ((type = in.next()) != END_DOCUMENT) {
10386                 final String tag = in.getName();
10387                 if (type == START_TAG) {
10388                     if (TAG_URI_GRANT.equals(tag)) {
10389                         final int sourceUserId;
10390                         final int targetUserId;
10391                         final int userHandle = readIntAttribute(in,
10392                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
10393                         if (userHandle != UserHandle.USER_NULL) {
10394                             // For backwards compatibility.
10395                             sourceUserId = userHandle;
10396                             targetUserId = userHandle;
10397                         } else {
10398                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
10399                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
10400                         }
10401                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
10402                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
10403                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
10404                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
10405                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
10406                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
10407
10408                         // Sanity check that provider still belongs to source package
10409                         // Both direct boot aware and unaware packages are fine as we
10410                         // will do filtering at query time to avoid multiple parsing.
10411                         final ProviderInfo pi = getProviderInfoLocked(
10412                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
10413                                         | MATCH_DIRECT_BOOT_UNAWARE);
10414                         if (pi != null && sourcePkg.equals(pi.packageName)) {
10415                             int targetUid = -1;
10416                             try {
10417                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
10418                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
10419                             } catch (RemoteException e) {
10420                             }
10421                             if (targetUid != -1) {
10422                                 final UriPermission perm = findOrCreateUriPermissionLocked(
10423                                         sourcePkg, targetPkg, targetUid,
10424                                         new GrantUri(sourceUserId, uri, prefix));
10425                                 perm.initPersistedModes(modeFlags, createdTime);
10426                             }
10427                         } else {
10428                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
10429                                     + " but instead found " + pi);
10430                         }
10431                     }
10432                 }
10433             }
10434         } catch (FileNotFoundException e) {
10435             // Missing grants is okay
10436         } catch (IOException e) {
10437             Slog.wtf(TAG, "Failed reading Uri grants", e);
10438         } catch (XmlPullParserException e) {
10439             Slog.wtf(TAG, "Failed reading Uri grants", e);
10440         } finally {
10441             IoUtils.closeQuietly(fis);
10442         }
10443     }
10444
10445     /**
10446      * @param uri This uri must NOT contain an embedded userId.
10447      * @param toPackage Name of package whose uri is being granted to (if {@code null}, uses
10448      * calling uid)
10449      * @param userId The userId in which the uri is to be resolved.
10450      */
10451     @Override
10452     public void takePersistableUriPermission(Uri uri, final int modeFlags,
10453             @Nullable String toPackage, int userId) {
10454         final int uid;
10455         if (toPackage != null) {
10456             enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10457                     "takePersistableUriPermission");
10458             uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10459         } else {
10460             enforceNotIsolatedCaller("takePersistableUriPermission");
10461             uid = Binder.getCallingUid();
10462         }
10463
10464         Preconditions.checkFlagsArgument(modeFlags,
10465                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10466
10467         synchronized (this) {
10468             boolean persistChanged = false;
10469             GrantUri grantUri = new GrantUri(userId, uri, false);
10470
10471             UriPermission exactPerm = findUriPermissionLocked(uid, grantUri);
10472             UriPermission prefixPerm = findUriPermissionLocked(uid,
10473                     new GrantUri(userId, uri, true));
10474
10475             final boolean exactValid = (exactPerm != null)
10476                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
10477             final boolean prefixValid = (prefixPerm != null)
10478                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
10479
10480             if (!(exactValid || prefixValid)) {
10481                 throw new SecurityException("No persistable permission grants found for UID "
10482                         + uid + " and Uri " + grantUri.toSafeString());
10483             }
10484
10485             if (exactValid) {
10486                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
10487             }
10488             if (prefixValid) {
10489                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
10490             }
10491
10492             persistChanged |= maybePrunePersistedUriGrantsLocked(uid);
10493
10494             if (persistChanged) {
10495                 schedulePersistUriGrants();
10496             }
10497         }
10498     }
10499
10500     /**
10501      * @param uri This uri must NOT contain an embedded userId.
10502      * @param toPackage Name of the target package whose uri is being released (if {@code null},
10503      * uses calling uid)
10504      * @param userId The userId in which the uri is to be resolved.
10505      */
10506     @Override
10507     public void releasePersistableUriPermission(Uri uri, final int modeFlags,
10508             @Nullable String toPackage, int userId) {
10509
10510         final int uid;
10511         if (toPackage != null) {
10512             enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10513                     "releasePersistableUriPermission");
10514             uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10515         } else {
10516             enforceNotIsolatedCaller("releasePersistableUriPermission");
10517             uid = Binder.getCallingUid();
10518         }
10519
10520         Preconditions.checkFlagsArgument(modeFlags,
10521                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10522
10523         synchronized (this) {
10524             boolean persistChanged = false;
10525
10526             UriPermission exactPerm = findUriPermissionLocked(uid,
10527                     new GrantUri(userId, uri, false));
10528             UriPermission prefixPerm = findUriPermissionLocked(uid,
10529                     new GrantUri(userId, uri, true));
10530             if (exactPerm == null && prefixPerm == null && toPackage == null) {
10531                 throw new SecurityException("No permission grants found for UID " + uid
10532                         + " and Uri " + uri.toSafeString());
10533             }
10534
10535             if (exactPerm != null) {
10536                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10537                 removeUriPermissionIfNeededLocked(exactPerm);
10538             }
10539             if (prefixPerm != null) {
10540                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10541                 removeUriPermissionIfNeededLocked(prefixPerm);
10542             }
10543
10544             if (persistChanged) {
10545                 schedulePersistUriGrants();
10546             }
10547         }
10548     }
10549
10550     /**
10551      * Prune any older {@link UriPermission} for the given UID until outstanding
10552      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10553      *
10554      * @return if any mutations occured that require persisting.
10555      */
10556     @GuardedBy("this")
10557     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
10558         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
10559         if (perms == null) return false;
10560         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
10561
10562         final ArrayList<UriPermission> persisted = Lists.newArrayList();
10563         for (UriPermission perm : perms.values()) {
10564             if (perm.persistedModeFlags != 0) {
10565                 persisted.add(perm);
10566             }
10567         }
10568
10569         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10570         if (trimCount <= 0) return false;
10571
10572         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10573         for (int i = 0; i < trimCount; i++) {
10574             final UriPermission perm = persisted.get(i);
10575
10576             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10577                     "Trimming grant created at " + perm.persistedCreateTime);
10578
10579             perm.releasePersistableModes(~0);
10580             removeUriPermissionIfNeededLocked(perm);
10581         }
10582
10583         return true;
10584     }
10585
10586     @Override
10587     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10588             String packageName, boolean incoming) {
10589         enforceNotIsolatedCaller("getPersistedUriPermissions");
10590         Preconditions.checkNotNull(packageName, "packageName");
10591
10592         final int callingUid = Binder.getCallingUid();
10593         final int callingUserId = UserHandle.getUserId(callingUid);
10594         final IPackageManager pm = AppGlobals.getPackageManager();
10595         try {
10596             final int packageUid = pm.getPackageUid(packageName,
10597                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
10598             if (packageUid != callingUid) {
10599                 throw new SecurityException(
10600                         "Package " + packageName + " does not belong to calling UID " + callingUid);
10601             }
10602         } catch (RemoteException e) {
10603             throw new SecurityException("Failed to verify package name ownership");
10604         }
10605
10606         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10607         synchronized (this) {
10608             if (incoming) {
10609                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10610                         callingUid);
10611                 if (perms == null) {
10612                     Slog.w(TAG, "No permission grants found for " + packageName);
10613                 } else {
10614                     for (int j = 0; j < perms.size(); j++) {
10615                         final UriPermission perm = perms.valueAt(j);
10616                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10617                             result.add(perm.buildPersistedPublicApiObject());
10618                         }
10619                     }
10620                 }
10621             } else {
10622                 final int size = mGrantedUriPermissions.size();
10623                 for (int i = 0; i < size; i++) {
10624                     final ArrayMap<GrantUri, UriPermission> perms =
10625                             mGrantedUriPermissions.valueAt(i);
10626                     for (int j = 0; j < perms.size(); j++) {
10627                         final UriPermission perm = perms.valueAt(j);
10628                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10629                             result.add(perm.buildPersistedPublicApiObject());
10630                         }
10631                     }
10632                 }
10633             }
10634         }
10635         return new ParceledListSlice<android.content.UriPermission>(result);
10636     }
10637
10638     @Override
10639     public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
10640             @Nullable String packageName, int userId) {
10641         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10642                 "getGrantedUriPermissions");
10643
10644         final List<GrantedUriPermission> result = new ArrayList<>();
10645         synchronized (this) {
10646             final int size = mGrantedUriPermissions.size();
10647             for (int i = 0; i < size; i++) {
10648                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10649                 for (int j = 0; j < perms.size(); j++) {
10650                     final UriPermission perm = perms.valueAt(j);
10651                     if ((packageName == null || packageName.equals(perm.targetPkg))
10652                             && perm.targetUserId == userId
10653                             && perm.persistedModeFlags != 0) {
10654                         result.add(perm.buildGrantedUriPermission());
10655                     }
10656                 }
10657             }
10658         }
10659         return new ParceledListSlice<>(result);
10660     }
10661
10662     @Override
10663     public void clearGrantedUriPermissions(String packageName, int userId) {
10664         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10665                 "clearGrantedUriPermissions");
10666         synchronized(this) {
10667             removeUriPermissionsForPackageLocked(packageName, userId, true, true);
10668         }
10669     }
10670
10671     @Override
10672     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10673         synchronized (this) {
10674             ProcessRecord app =
10675                 who != null ? getRecordForAppLocked(who) : null;
10676             if (app == null) return;
10677
10678             Message msg = Message.obtain();
10679             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10680             msg.obj = app;
10681             msg.arg1 = waiting ? 1 : 0;
10682             mUiHandler.sendMessage(msg);
10683         }
10684     }
10685
10686     @Override
10687     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10688         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10689         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10690         outInfo.availMem = getFreeMemory();
10691         outInfo.totalMem = getTotalMemory();
10692         outInfo.threshold = homeAppMem;
10693         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10694         outInfo.hiddenAppThreshold = cachedAppMem;
10695         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10696                 ProcessList.SERVICE_ADJ);
10697         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10698                 ProcessList.VISIBLE_APP_ADJ);
10699         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10700                 ProcessList.FOREGROUND_APP_ADJ);
10701     }
10702
10703     // =========================================================
10704     // TASK MANAGEMENT
10705     // =========================================================
10706
10707     @Override
10708     public List<IBinder> getAppTasks(String callingPackage) {
10709         int callingUid = Binder.getCallingUid();
10710         long ident = Binder.clearCallingIdentity();
10711         try {
10712             synchronized(this) {
10713                 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10714             }
10715         } finally {
10716             Binder.restoreCallingIdentity(ident);
10717         }
10718     }
10719
10720     @Override
10721     public List<RunningTaskInfo> getTasks(int maxNum) {
10722        return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10723     }
10724
10725     @Override
10726     public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10727             @WindowingMode int ignoreWindowingMode) {
10728         final int callingUid = Binder.getCallingUid();
10729         ArrayList<RunningTaskInfo> list = new ArrayList<>();
10730
10731         synchronized(this) {
10732             if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10733
10734             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10735                     callingUid);
10736             mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10737                     ignoreWindowingMode, callingUid, allowed);
10738         }
10739
10740         return list;
10741     }
10742
10743     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10744         if (mRecentTasks.isCallerRecents(callingUid)) {
10745             // Always allow the recents component to get tasks
10746             return true;
10747         }
10748
10749         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10750                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10751         if (!allowed) {
10752             if (checkPermission(android.Manifest.permission.GET_TASKS,
10753                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10754                 // Temporary compatibility: some existing apps on the system image may
10755                 // still be requesting the old permission and not switched to the new
10756                 // one; if so, we'll still allow them full access.  This means we need
10757                 // to see if they are holding the old permission and are a system app.
10758                 try {
10759                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10760                         allowed = true;
10761                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10762                                 + " is using old GET_TASKS but privileged; allowing");
10763                     }
10764                 } catch (RemoteException e) {
10765                 }
10766             }
10767         }
10768         if (!allowed) {
10769             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10770                     + " does not hold REAL_GET_TASKS; limiting output");
10771         }
10772         return allowed;
10773     }
10774
10775     @Override
10776     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10777             int userId) {
10778         final int callingUid = Binder.getCallingUid();
10779         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10780                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10781         final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10782                 callingUid);
10783         final boolean detailed = checkCallingPermission(
10784                 android.Manifest.permission.GET_DETAILED_TASKS)
10785                         == PackageManager.PERMISSION_GRANTED;
10786
10787         synchronized (this) {
10788             return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10789                     callingUid);
10790         }
10791     }
10792
10793     @Override
10794     public ActivityManager.TaskDescription getTaskDescription(int id) {
10795         synchronized (this) {
10796             enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10797             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10798                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10799             if (tr != null) {
10800                 return tr.lastTaskDescription;
10801             }
10802         }
10803         return null;
10804     }
10805
10806     @Override
10807     public int addAppTask(IBinder activityToken, Intent intent,
10808             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10809         final int callingUid = Binder.getCallingUid();
10810         final long callingIdent = Binder.clearCallingIdentity();
10811
10812         try {
10813             synchronized (this) {
10814                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10815                 if (r == null) {
10816                     throw new IllegalArgumentException("Activity does not exist; token="
10817                             + activityToken);
10818                 }
10819                 ComponentName comp = intent.getComponent();
10820                 if (comp == null) {
10821                     throw new IllegalArgumentException("Intent " + intent
10822                             + " must specify explicit component");
10823                 }
10824                 if (thumbnail.getWidth() != mThumbnailWidth
10825                         || thumbnail.getHeight() != mThumbnailHeight) {
10826                     throw new IllegalArgumentException("Bad thumbnail size: got "
10827                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10828                             + mThumbnailWidth + "x" + mThumbnailHeight);
10829                 }
10830                 if (intent.getSelector() != null) {
10831                     intent.setSelector(null);
10832                 }
10833                 if (intent.getSourceBounds() != null) {
10834                     intent.setSourceBounds(null);
10835                 }
10836                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10837                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10838                         // The caller has added this as an auto-remove task...  that makes no
10839                         // sense, so turn off auto-remove.
10840                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10841                     }
10842                 }
10843                 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
10844                         STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
10845                 if (ainfo.applicationInfo.uid != callingUid) {
10846                     throw new SecurityException(
10847                             "Can't add task for another application: target uid="
10848                             + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10849                 }
10850
10851                 final ActivityStack stack = r.getStack();
10852                 final TaskRecord task = stack.createTaskRecord(
10853                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
10854                         null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
10855                 if (!mRecentTasks.addToBottom(task)) {
10856                     // The app has too many tasks already and we can't add any more
10857                     stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
10858                     return INVALID_TASK_ID;
10859                 }
10860                 task.lastTaskDescription.copyFrom(description);
10861
10862                 // TODO: Send the thumbnail to WM to store it.
10863
10864                 return task.taskId;
10865             }
10866         } finally {
10867             Binder.restoreCallingIdentity(callingIdent);
10868         }
10869     }
10870
10871     @Override
10872     public Point getAppTaskThumbnailSize() {
10873         synchronized (this) {
10874             return new Point(mThumbnailWidth,  mThumbnailHeight);
10875         }
10876     }
10877
10878     @Override
10879     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10880         synchronized (this) {
10881             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10882             if (r != null) {
10883                 r.setTaskDescription(td);
10884                 final TaskRecord task = r.getTask();
10885                 task.updateTaskDescription();
10886                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10887             }
10888         }
10889     }
10890
10891     @Override
10892     public void setTaskResizeable(int taskId, int resizeableMode) {
10893         synchronized (this) {
10894             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10895                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10896             if (task == null) {
10897                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10898                 return;
10899             }
10900             task.setResizeMode(resizeableMode);
10901         }
10902     }
10903
10904     @Override
10905     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10906         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10907         long ident = Binder.clearCallingIdentity();
10908         try {
10909             synchronized (this) {
10910                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10911                 if (task == null) {
10912                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10913                     return;
10914                 }
10915                 // Place the task in the right stack if it isn't there already based on
10916                 // the requested bounds.
10917                 // The stack transition logic is:
10918                 // - a null bounds on a freeform task moves that task to fullscreen
10919                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10920                 //   that task to freeform
10921                 // - otherwise the task is not moved
10922                 ActivityStack stack = task.getStack();
10923                 if (!task.getWindowConfiguration().canResizeTask()) {
10924                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10925                 }
10926                 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10927                     stack = stack.getDisplay().getOrCreateStack(
10928                             WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10929                 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10930                     stack = stack.getDisplay().getOrCreateStack(
10931                             WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10932                 }
10933
10934                 // Reparent the task to the right stack if necessary
10935                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10936                 if (stack != task.getStack()) {
10937                     // Defer resume until the task is resized below
10938                     task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10939                             DEFER_RESUME, "resizeTask");
10940                     preserveWindow = false;
10941                 }
10942
10943                 // After reparenting (which only resizes the task to the stack bounds), resize the
10944                 // task to the actual bounds provided
10945                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10946             }
10947         } finally {
10948             Binder.restoreCallingIdentity(ident);
10949         }
10950     }
10951
10952     @Override
10953     public Rect getTaskBounds(int taskId) {
10954         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10955         long ident = Binder.clearCallingIdentity();
10956         Rect rect = new Rect();
10957         try {
10958             synchronized (this) {
10959                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10960                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10961                 if (task == null) {
10962                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10963                     return rect;
10964                 }
10965                 if (task.getStack() != null) {
10966                     // Return the bounds from window manager since it will be adjusted for various
10967                     // things like the presense of a docked stack for tasks that aren't resizeable.
10968                     task.getWindowContainerBounds(rect);
10969                 } else {
10970                     // Task isn't in window manager yet since it isn't associated with a stack.
10971                     // Return the persist value from activity manager
10972                     if (!task.matchParentBounds()) {
10973                         rect.set(task.getBounds());
10974                     } else if (task.mLastNonFullscreenBounds != null) {
10975                         rect.set(task.mLastNonFullscreenBounds);
10976                     }
10977                 }
10978             }
10979         } finally {
10980             Binder.restoreCallingIdentity(ident);
10981         }
10982         return rect;
10983     }
10984
10985     @Override
10986     public void cancelTaskWindowTransition(int taskId) {
10987         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10988                 "cancelTaskWindowTransition()");
10989         final long ident = Binder.clearCallingIdentity();
10990         try {
10991             synchronized (this) {
10992                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10993                         MATCH_TASK_IN_STACKS_ONLY);
10994                 if (task == null) {
10995                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10996                     return;
10997                 }
10998                 task.cancelWindowTransition();
10999             }
11000         } finally {
11001             Binder.restoreCallingIdentity(ident);
11002         }
11003     }
11004
11005     @Override
11006     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
11007         enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
11008         final long ident = Binder.clearCallingIdentity();
11009         try {
11010             final TaskRecord task;
11011             synchronized (this) {
11012                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
11013                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
11014                 if (task == null) {
11015                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
11016                     return null;
11017                 }
11018             }
11019             // Don't call this while holding the lock as this operation might hit the disk.
11020             return task.getSnapshot(reducedResolution);
11021         } finally {
11022             Binder.restoreCallingIdentity(ident);
11023         }
11024     }
11025
11026     @Override
11027     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
11028         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11029                 userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
11030
11031         final File passedIconFile = new File(filePath);
11032         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
11033                 passedIconFile.getName());
11034         if (!legitIconFile.getPath().equals(filePath)
11035                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
11036             throw new IllegalArgumentException("Bad file path: " + filePath
11037                     + " passed for userId " + userId);
11038         }
11039         return mRecentTasks.getTaskDescriptionIcon(filePath);
11040     }
11041
11042     @Override
11043     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
11044             throws RemoteException {
11045         final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
11046         final ActivityOptions activityOptions = safeOptions != null
11047                 ? safeOptions.getOptions(mStackSupervisor)
11048                 : null;
11049         if (activityOptions == null
11050                 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
11051                 || activityOptions.getCustomInPlaceResId() == 0) {
11052             throw new IllegalArgumentException("Expected in-place ActivityOption " +
11053                     "with valid animation");
11054         }
11055         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
11056         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
11057                 activityOptions.getCustomInPlaceResId());
11058         mWindowManager.executeAppTransition();
11059     }
11060
11061     @Override
11062     public void removeStack(int stackId) {
11063         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
11064         synchronized (this) {
11065             final long ident = Binder.clearCallingIdentity();
11066             try {
11067                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11068                 if (stack == null) {
11069                     Slog.w(TAG, "removeStack: No stack with id=" + stackId);
11070                     return;
11071                 }
11072                 if (!stack.isActivityTypeStandardOrUndefined()) {
11073                     throw new IllegalArgumentException(
11074                             "Removing non-standard stack is not allowed.");
11075                 }
11076                 mStackSupervisor.removeStack(stack);
11077             } finally {
11078                 Binder.restoreCallingIdentity(ident);
11079             }
11080         }
11081     }
11082
11083     /**
11084      * Removes stacks in the input windowing modes from the system if they are of activity type
11085      * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
11086      */
11087     @Override
11088     public void removeStacksInWindowingModes(int[] windowingModes) {
11089         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11090                 "removeStacksInWindowingModes()");
11091         synchronized (this) {
11092             final long ident = Binder.clearCallingIdentity();
11093             try {
11094                 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
11095             } finally {
11096                 Binder.restoreCallingIdentity(ident);
11097             }
11098         }
11099     }
11100
11101     @Override
11102     public void removeStacksWithActivityTypes(int[] activityTypes) {
11103         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11104                 "removeStacksWithActivityTypes()");
11105         synchronized (this) {
11106             final long ident = Binder.clearCallingIdentity();
11107             try {
11108                 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
11109             } finally {
11110                 Binder.restoreCallingIdentity(ident);
11111             }
11112         }
11113     }
11114
11115     /**
11116      * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
11117      * the whitelist
11118      */
11119     String getPendingTempWhitelistTagForUidLocked(int uid) {
11120         final PendingTempWhitelist ptw = mPendingTempWhitelist.get(uid);
11121         return ptw != null ? ptw.tag : null;
11122     }
11123
11124     @VisibleForTesting
11125     boolean isActivityStartsLoggingEnabled() {
11126         return mConstants.mFlagActivityStartsLoggingEnabled;
11127     }
11128
11129     @Override
11130     public void moveStackToDisplay(int stackId, int displayId) {
11131         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
11132
11133         synchronized (this) {
11134             final long ident = Binder.clearCallingIdentity();
11135             try {
11136                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
11137                         + " to displayId=" + displayId);
11138                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
11139             } finally {
11140                 Binder.restoreCallingIdentity(ident);
11141             }
11142         }
11143     }
11144
11145     @Override
11146     public boolean removeTask(int taskId) {
11147         enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
11148         synchronized (this) {
11149             final long ident = Binder.clearCallingIdentity();
11150             try {
11151                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
11152                         "remove-task");
11153             } finally {
11154                 Binder.restoreCallingIdentity(ident);
11155             }
11156         }
11157     }
11158
11159     /**
11160      * TODO: Add mController hook
11161      */
11162     @Override
11163     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
11164         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
11165
11166         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
11167         synchronized(this) {
11168             moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
11169                     false /* fromRecents */);
11170         }
11171     }
11172
11173     void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
11174             boolean fromRecents) {
11175
11176         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11177                 Binder.getCallingUid(), -1, -1, "Task to front")) {
11178             SafeActivityOptions.abort(options);
11179             return;
11180         }
11181         final long origId = Binder.clearCallingIdentity();
11182         try {
11183             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11184             if (task == null) {
11185                 Slog.d(TAG, "Could not find task for id: "+ taskId);
11186                 return;
11187             }
11188             if (mLockTaskController.isLockTaskModeViolation(task)) {
11189                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
11190                 return;
11191             }
11192             ActivityOptions realOptions = options != null
11193                     ? options.getOptions(mStackSupervisor)
11194                     : null;
11195             mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
11196                     false /* forceNonResizable */);
11197
11198             final ActivityRecord topActivity = task.getTopActivity();
11199             if (topActivity != null) {
11200
11201                 // We are reshowing a task, use a starting window to hide the initial draw delay
11202                 // so the transition can start earlier.
11203                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
11204                         true /* taskSwitch */, fromRecents);
11205             }
11206         } finally {
11207             Binder.restoreCallingIdentity(origId);
11208         }
11209         SafeActivityOptions.abort(options);
11210     }
11211
11212     /**
11213      * Attempts to move a task backwards in z-order (the order of activities within the task is
11214      * unchanged).
11215      *
11216      * There are several possible results of this call:
11217      * - if the task is locked, then we will show the lock toast
11218      * - if there is a task behind the provided task, then that task is made visible and resumed as
11219      *   this task is moved to the back
11220      * - otherwise, if there are no other tasks in the stack:
11221      *     - if this task is in the pinned stack, then we remove the stack completely, which will
11222      *       have the effect of moving the task to the top or bottom of the fullscreen stack
11223      *       (depending on whether it is visible)
11224      *     - otherwise, we simply return home and hide this task
11225      *
11226      * @param token A reference to the activity we wish to move
11227      * @param nonRoot If false then this only works if the activity is the root
11228      *                of a task; if true it will work for any activity in a task.
11229      * @return Returns true if the move completed, false if not.
11230      */
11231     @Override
11232     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
11233         enforceNotIsolatedCaller("moveActivityTaskToBack");
11234         synchronized(this) {
11235             final long origId = Binder.clearCallingIdentity();
11236             try {
11237                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
11238                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11239                 if (task != null) {
11240                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
11241                 }
11242             } finally {
11243                 Binder.restoreCallingIdentity(origId);
11244             }
11245         }
11246         return false;
11247     }
11248
11249     @Override
11250     public void moveTaskBackwards(int task) {
11251         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
11252                 "moveTaskBackwards()");
11253
11254         synchronized(this) {
11255             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11256                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
11257                 return;
11258             }
11259             final long origId = Binder.clearCallingIdentity();
11260             moveTaskBackwardsLocked(task);
11261             Binder.restoreCallingIdentity(origId);
11262         }
11263     }
11264
11265     private final void moveTaskBackwardsLocked(int task) {
11266         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
11267     }
11268
11269     @Override
11270     public int createStackOnDisplay(int displayId) throws RemoteException {
11271         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
11272         synchronized (this) {
11273             final ActivityDisplay display =
11274                     mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
11275             if (display == null) {
11276                 return INVALID_STACK_ID;
11277             }
11278             // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
11279             final ActivityStack stack = display.createStack(
11280                     WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
11281                     ON_TOP);
11282             return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
11283         }
11284     }
11285
11286     @Override
11287     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
11288         synchronized (this) {
11289             final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
11290             if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
11291                 return stack.mDisplayId;
11292             }
11293             return DEFAULT_DISPLAY;
11294         }
11295     }
11296
11297     @Override
11298     public void exitFreeformMode(IBinder token) throws RemoteException {
11299         synchronized (this) {
11300             long ident = Binder.clearCallingIdentity();
11301             try {
11302                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11303                 if (r == null) {
11304                     throw new IllegalArgumentException(
11305                             "exitFreeformMode: No activity record matching token=" + token);
11306                 }
11307
11308                 final ActivityStack stack = r.getStack();
11309                 if (stack == null || !stack.inFreeformWindowingMode()) {
11310                     throw new IllegalStateException(
11311                             "exitFreeformMode: You can only go fullscreen from freeform.");
11312                 }
11313
11314                 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11315             } finally {
11316                 Binder.restoreCallingIdentity(ident);
11317             }
11318         }
11319     }
11320
11321     @Override
11322     public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
11323         if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
11324             setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
11325                     toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
11326             return;
11327         }
11328         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
11329         synchronized (this) {
11330             final long ident = Binder.clearCallingIdentity();
11331             try {
11332                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11333                 if (task == null) {
11334                     Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
11335                     return;
11336                 }
11337
11338                 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
11339                         + " to windowingMode=" + windowingMode + " toTop=" + toTop);
11340
11341                 if (!task.isActivityTypeStandardOrUndefined()) {
11342                     throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11343                             + " non-standard task " + taskId + " to windowing mode="
11344                             + windowingMode);
11345                 }
11346
11347                 final ActivityStack stack = task.getStack();
11348                 if (toTop) {
11349                     stack.moveToFront("setTaskWindowingMode", task);
11350                 }
11351                 stack.setWindowingMode(windowingMode);
11352             } finally {
11353                 Binder.restoreCallingIdentity(ident);
11354             }
11355         }
11356     }
11357
11358     /**
11359      * Moves the specified task to the primary-split-screen stack.
11360      *
11361      * @param taskId Id of task to move.
11362      * @param createMode The mode the primary split screen stack should be created in if it doesn't
11363      *                   exist already. See
11364      *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
11365      *                   and
11366      *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
11367      * @param toTop If the task and stack should be moved to the top.
11368      * @param animate Whether we should play an animation for the moving the task.
11369      * @param initialBounds If the primary stack gets created, it will use these bounds for the
11370      *                      stack. Pass {@code null} to use default bounds.
11371      * @param showRecents If the recents activity should be shown on the other side of the task
11372      *                    going into split-screen mode.
11373      */
11374     @Override
11375     public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
11376             boolean animate, Rect initialBounds, boolean showRecents) {
11377         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11378                 "setTaskWindowingModeSplitScreenPrimary()");
11379         synchronized (this) {
11380             long ident = Binder.clearCallingIdentity();
11381             try {
11382                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11383                 if (task == null) {
11384                     Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
11385                     return false;
11386                 }
11387                 if (DEBUG_STACK) Slog.d(TAG_STACK,
11388                         "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
11389                         + " to createMode=" + createMode + " toTop=" + toTop);
11390                 if (!task.isActivityTypeStandardOrUndefined()) {
11391                     throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11392                             + " non-standard task " + taskId + " to split-screen windowing mode");
11393                 }
11394
11395                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
11396                 final int windowingMode = task.getWindowingMode();
11397                 final ActivityStack stack = task.getStack();
11398                 if (toTop) {
11399                     stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
11400                 }
11401                 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
11402                         false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
11403                 return windowingMode != task.getWindowingMode();
11404             } finally {
11405                 Binder.restoreCallingIdentity(ident);
11406             }
11407         }
11408     }
11409
11410     @Override
11411     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
11412         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
11413         synchronized (this) {
11414             long ident = Binder.clearCallingIdentity();
11415             try {
11416                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11417                 if (task == null) {
11418                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
11419                     return;
11420                 }
11421
11422                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
11423                         + " to stackId=" + stackId + " toTop=" + toTop);
11424
11425                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11426                 if (stack == null) {
11427                     throw new IllegalStateException(
11428                             "moveTaskToStack: No stack for stackId=" + stackId);
11429                 }
11430                 if (!stack.isActivityTypeStandardOrUndefined()) {
11431                     throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
11432                             + taskId + " to stack " + stackId);
11433                 }
11434                 if (stack.inSplitScreenPrimaryWindowingMode()) {
11435                     mWindowManager.setDockedStackCreateState(
11436                             SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
11437                 }
11438                 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
11439                         "moveTaskToStack");
11440             } finally {
11441                 Binder.restoreCallingIdentity(ident);
11442             }
11443         }
11444     }
11445
11446     /**
11447      * Dismisses split-screen multi-window mode.
11448      * @param toTop If true the current primary split-screen stack will be placed or left on top.
11449      */
11450     @Override
11451     public void dismissSplitScreenMode(boolean toTop) {
11452         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
11453         final long ident = Binder.clearCallingIdentity();
11454         try {
11455             synchronized (this) {
11456                 final ActivityStack stack =
11457                         mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
11458                 if (stack == null) {
11459                     Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
11460                     return;
11461                 }
11462
11463                 if (toTop) {
11464                     // Caller wants the current split-screen primary stack to be the top stack after
11465                     // it goes fullscreen, so move it to the front.
11466                     stack.moveToFront("dismissSplitScreenMode");
11467                 } else if (mStackSupervisor.isFocusedStack(stack)) {
11468                     // In this case the current split-screen primary stack shouldn't be the top
11469                     // stack after it goes fullscreen, but it current has focus, so we move the
11470                     // focus to the top-most split-screen secondary stack next to it.
11471                     final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
11472                             WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
11473                     if (otherStack != null) {
11474                         otherStack.moveToFront("dismissSplitScreenMode_other");
11475                     }
11476                 }
11477
11478                 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11479             }
11480         } finally {
11481             Binder.restoreCallingIdentity(ident);
11482         }
11483     }
11484
11485     /**
11486      * Dismisses Pip
11487      * @param animate True if the dismissal should be animated.
11488      * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
11489      *                          default animation duration should be used.
11490      */
11491     @Override
11492     public void dismissPip(boolean animate, int animationDuration) {
11493         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
11494         final long ident = Binder.clearCallingIdentity();
11495         try {
11496             synchronized (this) {
11497                 final PinnedActivityStack stack =
11498                         mStackSupervisor.getDefaultDisplay().getPinnedStack();
11499                 if (stack == null) {
11500                     Slog.w(TAG, "dismissPip: pinned stack not found.");
11501                     return;
11502                 }
11503                 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11504                     throw new IllegalArgumentException("Stack: " + stack
11505                             + " doesn't support animated resize.");
11506                 }
11507                 if (animate) {
11508                     stack.animateResizePinnedStack(null /* sourceHintBounds */,
11509                             null /* destBounds */, animationDuration, false /* fromFullscreen */);
11510                 } else {
11511                     mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
11512                 }
11513             }
11514         } finally {
11515             Binder.restoreCallingIdentity(ident);
11516         }
11517     }
11518
11519     /**
11520      * Moves the top activity in the input stackId to the pinned stack.
11521      *
11522      * @param stackId Id of stack to move the top activity to pinned stack.
11523      * @param bounds Bounds to use for pinned stack.
11524      *
11525      * @return True if the top activity of the input stack was successfully moved to the pinned
11526      *          stack.
11527      */
11528     @Override
11529     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
11530         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11531                 "moveTopActivityToPinnedStack()");
11532         synchronized (this) {
11533             if (!mSupportsPictureInPicture) {
11534                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
11535                         + "Device doesn't support picture-in-picture mode");
11536             }
11537
11538             long ident = Binder.clearCallingIdentity();
11539             try {
11540                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
11541             } finally {
11542                 Binder.restoreCallingIdentity(ident);
11543             }
11544         }
11545     }
11546
11547     @Override
11548     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
11549             boolean preserveWindows, boolean animate, int animationDuration) {
11550         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
11551         long ident = Binder.clearCallingIdentity();
11552         try {
11553             synchronized (this) {
11554                 if (animate) {
11555                     final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
11556                     if (stack == null) {
11557                         Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11558                         return;
11559                     }
11560                     if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11561                         throw new IllegalArgumentException("Stack: " + stackId
11562                                 + " doesn't support animated resize.");
11563                     }
11564                     stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11565                             animationDuration, false /* fromFullscreen */);
11566                 } else {
11567                     final ActivityStack stack = mStackSupervisor.getStack(stackId);
11568                     if (stack == null) {
11569                         Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11570                         return;
11571                     }
11572                     mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11573                             null /* tempTaskInsetBounds */, preserveWindows,
11574                             allowResizeInDockedMode, !DEFER_RESUME);
11575                 }
11576             }
11577         } finally {
11578             Binder.restoreCallingIdentity(ident);
11579         }
11580     }
11581
11582     @Override
11583     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
11584             Rect tempDockedTaskInsetBounds,
11585             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
11586         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
11587         long ident = Binder.clearCallingIdentity();
11588         try {
11589             synchronized (this) {
11590                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11591                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11592                         PRESERVE_WINDOWS);
11593             }
11594         } finally {
11595             Binder.restoreCallingIdentity(ident);
11596         }
11597     }
11598
11599     @Override
11600     public void setSplitScreenResizing(boolean resizing) {
11601         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
11602         final long ident = Binder.clearCallingIdentity();
11603         try {
11604             synchronized (this) {
11605                 mStackSupervisor.setSplitScreenResizing(resizing);
11606             }
11607         } finally {
11608             Binder.restoreCallingIdentity(ident);
11609         }
11610     }
11611
11612     @Override
11613     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11614         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11615         final long ident = Binder.clearCallingIdentity();
11616         try {
11617             synchronized (this) {
11618                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11619             }
11620         } finally {
11621             Binder.restoreCallingIdentity(ident);
11622         }
11623     }
11624
11625     /**
11626      * Try to place task to provided position. The final position might be different depending on
11627      * current user and stacks state. The task will be moved to target stack if it's currently in
11628      * different stack.
11629      */
11630     @Override
11631     public void positionTaskInStack(int taskId, int stackId, int position) {
11632         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11633         synchronized (this) {
11634             long ident = Binder.clearCallingIdentity();
11635             try {
11636                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
11637                         + taskId + " in stackId=" + stackId + " at position=" + position);
11638                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11639                 if (task == null) {
11640                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
11641                             + taskId);
11642                 }
11643
11644                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11645
11646                 if (stack == null) {
11647                     throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11648                             + stackId);
11649                 }
11650                 if (!stack.isActivityTypeStandardOrUndefined()) {
11651                     throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11652                             + " the position of task " + taskId + " in/to non-standard stack");
11653                 }
11654
11655                 // TODO: Have the callers of this API call a separate reparent method if that is
11656                 // what they intended to do vs. having this method also do reparenting.
11657                 if (task.getStack() == stack) {
11658                     // Change position in current stack.
11659                     stack.positionChildAt(task, position);
11660                 } else {
11661                     // Reparent to new stack.
11662                     task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11663                             !DEFER_RESUME, "positionTaskInStack");
11664                 }
11665             } finally {
11666                 Binder.restoreCallingIdentity(ident);
11667             }
11668         }
11669     }
11670
11671     @Override
11672     public List<StackInfo> getAllStackInfos() {
11673         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11674         long ident = Binder.clearCallingIdentity();
11675         try {
11676             synchronized (this) {
11677                 return mStackSupervisor.getAllStackInfosLocked();
11678             }
11679         } finally {
11680             Binder.restoreCallingIdentity(ident);
11681         }
11682     }
11683
11684     @Override
11685     public StackInfo getStackInfo(int windowingMode, int activityType) {
11686         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11687         long ident = Binder.clearCallingIdentity();
11688         try {
11689             synchronized (this) {
11690                 return mStackSupervisor.getStackInfo(windowingMode, activityType);
11691             }
11692         } finally {
11693             Binder.restoreCallingIdentity(ident);
11694         }
11695     }
11696
11697     @Override
11698     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11699         synchronized(this) {
11700             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11701         }
11702     }
11703
11704     @Override
11705     public void updateDeviceOwner(String packageName) {
11706         final int callingUid = Binder.getCallingUid();
11707         if (callingUid != 0 && callingUid != SYSTEM_UID) {
11708             throw new SecurityException("updateDeviceOwner called from non-system process");
11709         }
11710         synchronized (this) {
11711             mDeviceOwnerName = packageName;
11712         }
11713     }
11714
11715     @Override
11716     public void updateLockTaskPackages(int userId, String[] packages) {
11717         final int callingUid = Binder.getCallingUid();
11718         if (callingUid != 0 && callingUid != SYSTEM_UID) {
11719             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11720                     "updateLockTaskPackages()");
11721         }
11722         synchronized (this) {
11723             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11724                     Arrays.toString(packages));
11725             mLockTaskController.updateLockTaskPackages(userId, packages);
11726         }
11727     }
11728
11729     @Override
11730     public void updateLockTaskFeatures(int userId, int flags) {
11731         final int callingUid = Binder.getCallingUid();
11732         if (callingUid != 0 && callingUid != SYSTEM_UID) {
11733             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11734                     "updateLockTaskFeatures()");
11735         }
11736         synchronized (this) {
11737             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11738                     Integer.toHexString(flags));
11739             mLockTaskController.updateLockTaskFeatures(userId, flags);
11740         }
11741     }
11742
11743     private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11744         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11745         if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11746             return;
11747         }
11748
11749         final ActivityStack stack = mStackSupervisor.getFocusedStack();
11750         if (stack == null || task != stack.topTask()) {
11751             throw new IllegalArgumentException("Invalid task, not in foreground");
11752         }
11753
11754         // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11755         // system or a specific app.
11756         // * System-initiated requests will only start the pinned mode (screen pinning)
11757         // * App-initiated requests
11758         //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
11759         //   - will start the pinned mode, otherwise
11760         final int callingUid = Binder.getCallingUid();
11761         long ident = Binder.clearCallingIdentity();
11762         try {
11763             // When a task is locked, dismiss the pinned stack if it exists
11764             mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11765
11766             mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11767         } finally {
11768             Binder.restoreCallingIdentity(ident);
11769         }
11770     }
11771
11772     @Override
11773     public void startLockTaskModeByToken(IBinder token) {
11774         synchronized (this) {
11775             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11776             if (r == null) {
11777                 return;
11778             }
11779             startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11780         }
11781     }
11782
11783     @Override
11784     public void startSystemLockTaskMode(int taskId) throws RemoteException {
11785         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11786         // This makes inner call to look as if it was initiated by system.
11787         long ident = Binder.clearCallingIdentity();
11788         try {
11789             synchronized (this) {
11790                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11791
11792                 // When starting lock task mode the stack must be in front and focused
11793                 task.getStack().moveToFront("startSystemLockTaskMode");
11794                 startLockTaskModeLocked(task, true /* isSystemCaller */);
11795             }
11796         } finally {
11797             Binder.restoreCallingIdentity(ident);
11798         }
11799     }
11800
11801     @Override
11802     public void stopLockTaskModeByToken(IBinder token) {
11803         synchronized (this) {
11804             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11805             if (r == null) {
11806                 return;
11807             }
11808             stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11809         }
11810     }
11811
11812     /**
11813      * This API should be called by SystemUI only when user perform certain action to dismiss
11814      * lock task mode. We should only dismiss pinned lock task mode in this case.
11815      */
11816     @Override
11817     public void stopSystemLockTaskMode() throws RemoteException {
11818         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11819         stopLockTaskModeInternal(null, true /* isSystemCaller */);
11820     }
11821
11822     private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11823         final int callingUid = Binder.getCallingUid();
11824         long ident = Binder.clearCallingIdentity();
11825         try {
11826             synchronized (this) {
11827                 mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11828             }
11829             // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11830             // task and jumping straight into a call in the case of emergency call back.
11831             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11832             if (tm != null) {
11833                 tm.showInCallScreen(false);
11834             }
11835         } finally {
11836             Binder.restoreCallingIdentity(ident);
11837         }
11838     }
11839
11840     @Override
11841     public boolean isInLockTaskMode() {
11842         return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11843     }
11844
11845     @Override
11846     public int getLockTaskModeState() {
11847         synchronized (this) {
11848             return mLockTaskController.getLockTaskModeState();
11849         }
11850     }
11851
11852     @Override
11853     public void showLockTaskEscapeMessage(IBinder token) {
11854         synchronized (this) {
11855             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11856             if (r == null) {
11857                 return;
11858             }
11859             mLockTaskController.showLockTaskToast();
11860         }
11861     }
11862
11863     @Override
11864     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11865             throws RemoteException {
11866         synchronized (this) {
11867             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11868             if (r == null) {
11869                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11870                         + token);
11871                 return;
11872             }
11873             final long origId = Binder.clearCallingIdentity();
11874             try {
11875                 r.setDisablePreviewScreenshots(disable);
11876             } finally {
11877                 Binder.restoreCallingIdentity(origId);
11878             }
11879         }
11880     }
11881
11882     // =========================================================
11883     // CONTENT PROVIDERS
11884     // =========================================================
11885
11886     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11887         List<ProviderInfo> providers = null;
11888         try {
11889             providers = AppGlobals.getPackageManager()
11890                     .queryContentProviders(app.processName, app.uid,
11891                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11892                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11893                     .getList();
11894         } catch (RemoteException ex) {
11895         }
11896         if (DEBUG_MU) Slog.v(TAG_MU,
11897                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11898         int userId = app.userId;
11899         if (providers != null) {
11900             int N = providers.size();
11901             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11902             for (int i=0; i<N; i++) {
11903                 // TODO: keep logic in sync with installEncryptionUnawareProviders
11904                 ProviderInfo cpi =
11905                     (ProviderInfo)providers.get(i);
11906                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11907                         cpi.name, cpi.flags);
11908                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11909                     // This is a singleton provider, but a user besides the
11910                     // default user is asking to initialize a process it runs
11911                     // in...  well, no, it doesn't actually run in this process,
11912                     // it runs in the process of the default user.  Get rid of it.
11913                     providers.remove(i);
11914                     N--;
11915                     i--;
11916                     continue;
11917                 }
11918
11919                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11920                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11921                 if (cpr == null) {
11922                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11923                     mProviderMap.putProviderByClass(comp, cpr);
11924                 }
11925                 if (DEBUG_MU) Slog.v(TAG_MU,
11926                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11927                 app.pubProviders.put(cpi.name, cpr);
11928                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11929                     // Don't add this if it is a platform component that is marked
11930                     // to run in multiple processes, because this is actually
11931                     // part of the framework so doesn't make sense to track as a
11932                     // separate apk in the process.
11933                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11934                             mProcessStats);
11935                 }
11936                 notifyPackageUse(cpi.applicationInfo.packageName,
11937                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11938             }
11939         }
11940         return providers;
11941     }
11942
11943     /**
11944      * Check if the calling UID has a possible chance at accessing the provider
11945      * at the given authority and user.
11946      */
11947     public String checkContentProviderAccess(String authority, int userId) {
11948         if (userId == UserHandle.USER_ALL) {
11949             mContext.enforceCallingOrSelfPermission(
11950                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11951             userId = UserHandle.getCallingUserId();
11952         }
11953
11954         ProviderInfo cpi = null;
11955         try {
11956             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11957                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11958                             | PackageManager.MATCH_DISABLED_COMPONENTS
11959                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
11960                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11961                     userId);
11962         } catch (RemoteException ignored) {
11963         }
11964         if (cpi == null) {
11965             return "Failed to find provider " + authority + " for user " + userId
11966                     + "; expected to find a valid ContentProvider for this authority";
11967         }
11968
11969         ProcessRecord r = null;
11970         synchronized (mPidsSelfLocked) {
11971             r = mPidsSelfLocked.get(Binder.getCallingPid());
11972         }
11973         if (r == null) {
11974             return "Failed to find PID " + Binder.getCallingPid();
11975         }
11976
11977         synchronized (this) {
11978             return checkContentProviderPermissionLocked(cpi, r, userId, true);
11979         }
11980     }
11981
11982     /**
11983      * Check if {@link ProcessRecord} has a possible chance at accessing the
11984      * given {@link ProviderInfo}. Final permission checking is always done
11985      * in {@link ContentProvider}.
11986      */
11987     private final String checkContentProviderPermissionLocked(
11988             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11989         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11990         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11991         boolean checkedGrants = false;
11992         if (checkUser) {
11993             // Looking for cross-user grants before enforcing the typical cross-users permissions
11994             int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11995             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11996                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11997                     return null;
11998                 }
11999                 checkedGrants = true;
12000             }
12001             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
12002                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
12003             if (userId != tmpTargetUserId) {
12004                 // When we actually went to determine the final targer user ID, this ended
12005                 // up different than our initial check for the authority.  This is because
12006                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
12007                 // SELF.  So we need to re-check the grants again.
12008                 checkedGrants = false;
12009             }
12010         }
12011         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
12012                 cpi.applicationInfo.uid, cpi.exported)
12013                 == PackageManager.PERMISSION_GRANTED) {
12014             return null;
12015         }
12016         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
12017                 cpi.applicationInfo.uid, cpi.exported)
12018                 == PackageManager.PERMISSION_GRANTED) {
12019             return null;
12020         }
12021
12022         PathPermission[] pps = cpi.pathPermissions;
12023         if (pps != null) {
12024             int i = pps.length;
12025             while (i > 0) {
12026                 i--;
12027                 PathPermission pp = pps[i];
12028                 String pprperm = pp.getReadPermission();
12029                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
12030                         cpi.applicationInfo.uid, cpi.exported)
12031                         == PackageManager.PERMISSION_GRANTED) {
12032                     return null;
12033                 }
12034                 String ppwperm = pp.getWritePermission();
12035                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
12036                         cpi.applicationInfo.uid, cpi.exported)
12037                         == PackageManager.PERMISSION_GRANTED) {
12038                     return null;
12039                 }
12040             }
12041         }
12042         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
12043             return null;
12044         }
12045
12046         final String suffix;
12047         if (!cpi.exported) {
12048             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
12049         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
12050             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
12051         } else {
12052             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
12053         }
12054         final String msg = "Permission Denial: opening provider " + cpi.name
12055                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
12056                 + ", uid=" + callingUid + ")" + suffix;
12057         Slog.w(TAG, msg);
12058         return msg;
12059     }
12060
12061     /**
12062      * Returns if the ContentProvider has granted a uri to callingUid
12063      */
12064     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
12065         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
12066         if (perms != null) {
12067             for (int i=perms.size()-1; i>=0; i--) {
12068                 GrantUri grantUri = perms.keyAt(i);
12069                 if (grantUri.sourceUserId == userId || !checkUser) {
12070                     if (matchesProvider(grantUri.uri, cpi)) {
12071                         return true;
12072                     }
12073                 }
12074             }
12075         }
12076         return false;
12077     }
12078
12079     /**
12080      * Returns true if the uri authority is one of the authorities specified in the provider.
12081      */
12082     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
12083         String uriAuth = uri.getAuthority();
12084         String cpiAuth = cpi.authority;
12085         if (cpiAuth.indexOf(';') == -1) {
12086             return cpiAuth.equals(uriAuth);
12087         }
12088         String[] cpiAuths = cpiAuth.split(";");
12089         int length = cpiAuths.length;
12090         for (int i = 0; i < length; i++) {
12091             if (cpiAuths[i].equals(uriAuth)) return true;
12092         }
12093         return false;
12094     }
12095
12096     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
12097             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
12098         if (r != null) {
12099             for (int i=0; i<r.conProviders.size(); i++) {
12100                 ContentProviderConnection conn = r.conProviders.get(i);
12101                 if (conn.provider == cpr) {
12102                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
12103                             "Adding provider requested by "
12104                             + r.processName + " from process "
12105                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
12106                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
12107                     if (stable) {
12108                         conn.stableCount++;
12109                         conn.numStableIncs++;
12110                     } else {
12111                         conn.unstableCount++;
12112                         conn.numUnstableIncs++;
12113                     }
12114                     return conn;
12115                 }
12116             }
12117             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
12118             if (stable) {
12119                 conn.stableCount = 1;
12120                 conn.numStableIncs = 1;
12121             } else {
12122                 conn.unstableCount = 1;
12123                 conn.numUnstableIncs = 1;
12124             }
12125             cpr.connections.add(conn);
12126             r.conProviders.add(conn);
12127             startAssociationLocked(r.uid, r.processName, r.curProcState,
12128                     cpr.uid, cpr.name, cpr.info.processName);
12129             return conn;
12130         }
12131         cpr.addExternalProcessHandleLocked(externalProcessToken);
12132         return null;
12133     }
12134
12135     boolean decProviderCountLocked(ContentProviderConnection conn,
12136             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
12137         if (conn != null) {
12138             cpr = conn.provider;
12139             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
12140                     "Removing provider requested by "
12141                     + conn.client.processName + " from process "
12142                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
12143                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
12144             if (stable) {
12145                 conn.stableCount--;
12146             } else {
12147                 conn.unstableCount--;
12148             }
12149             if (conn.stableCount == 0 && conn.unstableCount == 0) {
12150                 cpr.connections.remove(conn);
12151                 conn.client.conProviders.remove(conn);
12152                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
12153                     // The client is more important than last activity -- note the time this
12154                     // is happening, so we keep the old provider process around a bit as last
12155                     // activity to avoid thrashing it.
12156                     if (cpr.proc != null) {
12157                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
12158                     }
12159                 }
12160                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
12161                 return true;
12162             }
12163             return false;
12164         }
12165         cpr.removeExternalProcessHandleLocked(externalProcessToken);
12166         return false;
12167     }
12168
12169     private void checkTime(long startTime, String where) {
12170         long now = SystemClock.uptimeMillis();
12171         if ((now-startTime) > 50) {
12172             // If we are taking more than 50ms, log about it.
12173             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
12174         }
12175     }
12176
12177     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
12178             PROC_SPACE_TERM,
12179             PROC_SPACE_TERM|PROC_PARENS,
12180             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
12181     };
12182
12183     private final long[] mProcessStateStatsLongs = new long[1];
12184
12185     private boolean isProcessAliveLocked(ProcessRecord proc) {
12186         if (proc.pid <= 0) {
12187             if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
12188             return false;
12189         }
12190         if (proc.procStatFile == null) {
12191             proc.procStatFile = "/proc/" + proc.pid + "/stat";
12192         }
12193         mProcessStateStatsLongs[0] = 0;
12194         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
12195                 mProcessStateStatsLongs, null)) {
12196             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
12197             return false;
12198         }
12199         final long state = mProcessStateStatsLongs[0];
12200         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
12201                 + (char)state);
12202         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
12203     }
12204
12205     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
12206             String name, IBinder token, boolean stable, int userId) {
12207         ContentProviderRecord cpr;
12208         ContentProviderConnection conn = null;
12209         ProviderInfo cpi = null;
12210         boolean providerRunning = false;
12211
12212         synchronized(this) {
12213             long startTime = SystemClock.uptimeMillis();
12214
12215             ProcessRecord r = null;
12216             if (caller != null) {
12217                 r = getRecordForAppLocked(caller);
12218                 if (r == null) {
12219                     throw new SecurityException(
12220                             "Unable to find app for caller " + caller
12221                           + " (pid=" + Binder.getCallingPid()
12222                           + ") when getting content provider " + name);
12223                 }
12224             }
12225
12226             boolean checkCrossUser = true;
12227
12228             checkTime(startTime, "getContentProviderImpl: getProviderByName");
12229
12230             // First check if this content provider has been published...
12231             cpr = mProviderMap.getProviderByName(name, userId);
12232             // If that didn't work, check if it exists for user 0 and then
12233             // verify that it's a singleton provider before using it.
12234             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
12235                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
12236                 if (cpr != null) {
12237                     cpi = cpr.info;
12238                     if (isSingleton(cpi.processName, cpi.applicationInfo,
12239                             cpi.name, cpi.flags)
12240                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
12241                         userId = UserHandle.USER_SYSTEM;
12242                         checkCrossUser = false;
12243                     } else {
12244                         cpr = null;
12245                         cpi = null;
12246                     }
12247                 }
12248             }
12249
12250             if (cpr != null && cpr.proc != null) {
12251                 providerRunning = !cpr.proc.killed;
12252
12253                 // Note if killedByAm is also set, this means the provider process has just been
12254                 // killed by AM (in ProcessRecord.kill()), but appDiedLocked() hasn't been called
12255                 // yet. So we need to call appDiedLocked() here and let it clean up.
12256                 // (See the commit message on I2c4ba1e87c2d47f2013befff10c49b3dc337a9a7 to see
12257                 // how to test this case.)
12258                 if (cpr.proc.killed && cpr.proc.killedByAm) {
12259                     checkTime(startTime, "getContentProviderImpl: before appDied (killedByAm)");
12260                     final long iden = Binder.clearCallingIdentity();
12261                     try {
12262                         appDiedLocked(cpr.proc);
12263                     } finally {
12264                         Binder.restoreCallingIdentity(iden);
12265                     }
12266                     checkTime(startTime, "getContentProviderImpl: after appDied (killedByAm)");
12267                 }
12268             }
12269
12270             if (providerRunning) {
12271                 cpi = cpr.info;
12272                 String msg;
12273                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12274                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
12275                         != null) {
12276                     throw new SecurityException(msg);
12277                 }
12278                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12279
12280                 if (r != null && cpr.canRunHere(r)) {
12281                     // This provider has been published or is in the process
12282                     // of being published...  but it is also allowed to run
12283                     // in the caller's process, so don't make a connection
12284                     // and just let the caller instantiate its own instance.
12285                     ContentProviderHolder holder = cpr.newHolder(null);
12286                     // don't give caller the provider object, it needs
12287                     // to make its own.
12288                     holder.provider = null;
12289                     return holder;
12290                 }
12291                 // Don't expose providers between normal apps and instant apps
12292                 try {
12293                     if (AppGlobals.getPackageManager()
12294                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
12295                         return null;
12296                     }
12297                 } catch (RemoteException e) {
12298                 }
12299
12300                 final long origId = Binder.clearCallingIdentity();
12301
12302                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
12303
12304                 // In this case the provider instance already exists, so we can
12305                 // return it right away.
12306                 conn = incProviderCountLocked(r, cpr, token, stable);
12307                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
12308                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12309                         // If this is a perceptible app accessing the provider,
12310                         // make sure to count it as being accessed and thus
12311                         // back up on the LRU list.  This is good because
12312                         // content providers are often expensive to start.
12313                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
12314                         updateLruProcessLocked(cpr.proc, false, null);
12315                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
12316                     }
12317                 }
12318
12319                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
12320                 final int verifiedAdj = cpr.proc.verifiedAdj;
12321                 boolean success = updateOomAdjLocked(cpr.proc, true);
12322                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
12323                 // if the process has been successfully adjusted.  So to reduce races with
12324                 // it, we will check whether the process still exists.  Note that this doesn't
12325                 // completely get rid of races with LMK killing the process, but should make
12326                 // them much smaller.
12327                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
12328                     success = false;
12329                 }
12330                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
12331                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
12332                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
12333                 // NOTE: there is still a race here where a signal could be
12334                 // pending on the process even though we managed to update its
12335                 // adj level.  Not sure what to do about this, but at least
12336                 // the race is now smaller.
12337                 if (!success) {
12338                     // Uh oh...  it looks like the provider's process
12339                     // has been killed on us.  We need to wait for a new
12340                     // process to be started, and make sure its death
12341                     // doesn't kill our process.
12342                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
12343                             + " is crashing; detaching " + r);
12344                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
12345                     checkTime(startTime, "getContentProviderImpl: before appDied");
12346                     appDiedLocked(cpr.proc);
12347                     checkTime(startTime, "getContentProviderImpl: after appDied");
12348                     if (!lastRef) {
12349                         // This wasn't the last ref our process had on
12350                         // the provider...  we have now been killed, bail.
12351                         return null;
12352                     }
12353                     providerRunning = false;
12354                     conn = null;
12355                 } else {
12356                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
12357                 }
12358
12359                 Binder.restoreCallingIdentity(origId);
12360             }
12361
12362             if (!providerRunning) {
12363                 try {
12364                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
12365                     cpi = AppGlobals.getPackageManager().
12366                         resolveContentProvider(name,
12367                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
12368                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
12369                 } catch (RemoteException ex) {
12370                 }
12371                 if (cpi == null) {
12372                     return null;
12373                 }
12374                 // If the provider is a singleton AND
12375                 // (it's a call within the same user || the provider is a
12376                 // privileged app)
12377                 // Then allow connecting to the singleton provider
12378                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
12379                         cpi.name, cpi.flags)
12380                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
12381                 if (singleton) {
12382                     userId = UserHandle.USER_SYSTEM;
12383                 }
12384                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
12385                 checkTime(startTime, "getContentProviderImpl: got app info for user");
12386
12387                 String msg;
12388                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12389                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
12390                         != null) {
12391                     throw new SecurityException(msg);
12392                 }
12393                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12394
12395                 if (!mProcessesReady
12396                         && !cpi.processName.equals("system")) {
12397                     // If this content provider does not run in the system
12398                     // process, and the system is not yet ready to run other
12399                     // processes, then fail fast instead of hanging.
12400                     throw new IllegalArgumentException(
12401                             "Attempt to launch content provider before system ready");
12402                 }
12403
12404                 // If system providers are not installed yet we aggressively crash to avoid
12405                 // creating multiple instance of these providers and then bad things happen!
12406                 if (!mSystemProvidersInstalled && cpi.applicationInfo.isSystemApp()
12407                         && "system".equals(cpi.processName)) {
12408                     throw new IllegalStateException("Cannot access system provider: '"
12409                             + cpi.authority + "' before system providers are installed!");
12410                 }
12411
12412                 // Make sure that the user who owns this provider is running.  If not,
12413                 // we don't want to allow it to run.
12414                 if (!mUserController.isUserRunning(userId, 0)) {
12415                     Slog.w(TAG, "Unable to launch app "
12416                             + cpi.applicationInfo.packageName + "/"
12417                             + cpi.applicationInfo.uid + " for provider "
12418                             + name + ": user " + userId + " is stopped");
12419                     return null;
12420                 }
12421
12422                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
12423                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
12424                 cpr = mProviderMap.getProviderByClass(comp, userId);
12425                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
12426                 final boolean firstClass = cpr == null;
12427                 if (firstClass) {
12428                     final long ident = Binder.clearCallingIdentity();
12429
12430                     // If permissions need a review before any of the app components can run,
12431                     // we return no provider and launch a review activity if the calling app
12432                     // is in the foreground.
12433                     if (mPermissionReviewRequired) {
12434                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
12435                             return null;
12436                         }
12437                     }
12438
12439                     try {
12440                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
12441                         ApplicationInfo ai =
12442                             AppGlobals.getPackageManager().
12443                                 getApplicationInfo(
12444                                         cpi.applicationInfo.packageName,
12445                                         STOCK_PM_FLAGS, userId);
12446                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
12447                         if (ai == null) {
12448                             Slog.w(TAG, "No package info for content provider "
12449                                     + cpi.name);
12450                             return null;
12451                         }
12452                         ai = getAppInfoForUser(ai, userId);
12453                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
12454                     } catch (RemoteException ex) {
12455                         // pm is in same process, this will never happen.
12456                     } finally {
12457                         Binder.restoreCallingIdentity(ident);
12458                     }
12459                 }
12460
12461                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
12462
12463                 if (r != null && cpr.canRunHere(r)) {
12464                     // If this is a multiprocess provider, then just return its
12465                     // info and allow the caller to instantiate it.  Only do
12466                     // this if the provider is the same user as the caller's
12467                     // process, or can run as root (so can be in any process).
12468                     return cpr.newHolder(null);
12469                 }
12470
12471                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
12472                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
12473                             + cpr.info.name + " callers=" + Debug.getCallers(6));
12474
12475                 // This is single process, and our app is now connecting to it.
12476                 // See if we are already in the process of launching this
12477                 // provider.
12478                 final int N = mLaunchingProviders.size();
12479                 int i;
12480                 for (i = 0; i < N; i++) {
12481                     if (mLaunchingProviders.get(i) == cpr) {
12482                         break;
12483                     }
12484                 }
12485
12486                 // If the provider is not already being launched, then get it
12487                 // started.
12488                 if (i >= N) {
12489                     final long origId = Binder.clearCallingIdentity();
12490
12491                     try {
12492                         // Content provider is now in use, its package can't be stopped.
12493                         try {
12494                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
12495                             AppGlobals.getPackageManager().setPackageStoppedState(
12496                                     cpr.appInfo.packageName, false, userId);
12497                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
12498                         } catch (RemoteException e) {
12499                         } catch (IllegalArgumentException e) {
12500                             Slog.w(TAG, "Failed trying to unstop package "
12501                                     + cpr.appInfo.packageName + ": " + e);
12502                         }
12503
12504                         // Use existing process if already started
12505                         checkTime(startTime, "getContentProviderImpl: looking for process record");
12506                         ProcessRecord proc = getProcessRecordLocked(
12507                                 cpi.processName, cpr.appInfo.uid, false);
12508                         if (proc != null && proc.thread != null && !proc.killed) {
12509                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
12510                                     "Installing in existing process " + proc);
12511                             if (!proc.pubProviders.containsKey(cpi.name)) {
12512                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
12513                                 proc.pubProviders.put(cpi.name, cpr);
12514                                 try {
12515                                     proc.thread.scheduleInstallProvider(cpi);
12516                                 } catch (RemoteException e) {
12517                                 }
12518                             }
12519                         } else {
12520                             checkTime(startTime, "getContentProviderImpl: before start process");
12521                             proc = startProcessLocked(cpi.processName,
12522                                     cpr.appInfo, false, 0, "content provider",
12523                                     new ComponentName(cpi.applicationInfo.packageName,
12524                                             cpi.name), false, false, false);
12525                             checkTime(startTime, "getContentProviderImpl: after start process");
12526                             if (proc == null) {
12527                                 Slog.w(TAG, "Unable to launch app "
12528                                         + cpi.applicationInfo.packageName + "/"
12529                                         + cpi.applicationInfo.uid + " for provider "
12530                                         + name + ": process is bad");
12531                                 return null;
12532                             }
12533                         }
12534                         cpr.launchingApp = proc;
12535                         mLaunchingProviders.add(cpr);
12536                     } finally {
12537                         Binder.restoreCallingIdentity(origId);
12538                     }
12539                 }
12540
12541                 checkTime(startTime, "getContentProviderImpl: updating data structures");
12542
12543                 // Make sure the provider is published (the same provider class
12544                 // may be published under multiple names).
12545                 if (firstClass) {
12546                     mProviderMap.putProviderByClass(comp, cpr);
12547                 }
12548
12549                 mProviderMap.putProviderByName(name, cpr);
12550                 conn = incProviderCountLocked(r, cpr, token, stable);
12551                 if (conn != null) {
12552                     conn.waiting = true;
12553                 }
12554             }
12555             checkTime(startTime, "getContentProviderImpl: done!");
12556
12557             grantEphemeralAccessLocked(userId, null /*intent*/,
12558                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
12559         }
12560
12561         // Wait for the provider to be published...
12562         final long timeout = SystemClock.uptimeMillis() + CONTENT_PROVIDER_WAIT_TIMEOUT;
12563         synchronized (cpr) {
12564             while (cpr.provider == null) {
12565                 if (cpr.launchingApp == null) {
12566                     Slog.w(TAG, "Unable to launch app "
12567                             + cpi.applicationInfo.packageName + "/"
12568                             + cpi.applicationInfo.uid + " for provider "
12569                             + name + ": launching app became null");
12570                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
12571                             UserHandle.getUserId(cpi.applicationInfo.uid),
12572                             cpi.applicationInfo.packageName,
12573                             cpi.applicationInfo.uid, name);
12574                     return null;
12575                 }
12576                 try {
12577                     final long wait = Math.max(0L, timeout - SystemClock.uptimeMillis());
12578                     if (DEBUG_MU) Slog.v(TAG_MU,
12579                             "Waiting to start provider " + cpr
12580                             + " launchingApp=" + cpr.launchingApp + " for " + wait + " ms");
12581                     if (conn != null) {
12582                         conn.waiting = true;
12583                     }
12584                     cpr.wait(wait);
12585                     if (cpr.provider == null) {
12586                         Slog.wtf(TAG, "Timeout waiting for provider "
12587                                 + cpi.applicationInfo.packageName + "/"
12588                                 + cpi.applicationInfo.uid + " for provider "
12589                                 + name
12590                                 + " providerRunning=" + providerRunning);
12591                         return null;
12592                     }
12593                 } catch (InterruptedException ex) {
12594                 } finally {
12595                     if (conn != null) {
12596                         conn.waiting = false;
12597                     }
12598                 }
12599             }
12600         }
12601         return cpr != null ? cpr.newHolder(conn) : null;
12602     }
12603
12604     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
12605             ProcessRecord r, final int userId) {
12606         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
12607                 cpi.packageName, userId)) {
12608
12609             final boolean callerForeground = r == null || r.setSchedGroup
12610                     != ProcessList.SCHED_GROUP_BACKGROUND;
12611
12612             // Show a permission review UI only for starting from a foreground app
12613             if (!callerForeground) {
12614                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
12615                         + cpi.packageName + " requires a permissions review");
12616                 return false;
12617             }
12618
12619             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
12620             intent.addFlags(FLAG_ACTIVITY_NEW_TASK
12621                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
12622             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
12623
12624             if (DEBUG_PERMISSIONS_REVIEW) {
12625                 Slog.i(TAG, "u" + userId + " Launching permission review "
12626                         + "for package " + cpi.packageName);
12627             }
12628
12629             final UserHandle userHandle = new UserHandle(userId);
12630             mHandler.post(new Runnable() {
12631                 @Override
12632                 public void run() {
12633                     mContext.startActivityAsUser(intent, userHandle);
12634                 }
12635             });
12636
12637             return false;
12638         }
12639
12640         return true;
12641     }
12642
12643     /**
12644      * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
12645      * PackageManager could be unavailable at construction time and therefore needs to be accessed
12646      * on demand.
12647      */
12648     IPackageManager getPackageManager() {
12649         return AppGlobals.getPackageManager();
12650     }
12651
12652     ActivityStartController getActivityStartController() {
12653         return mActivityStartController;
12654     }
12655
12656     LockTaskController getLockTaskController() {
12657         return mLockTaskController;
12658     }
12659
12660     ClientLifecycleManager getLifecycleManager() {
12661         return mLifecycleManager;
12662     }
12663
12664     PackageManagerInternal getPackageManagerInternalLocked() {
12665         if (mPackageManagerInt == null) {
12666             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12667         }
12668         return mPackageManagerInt;
12669     }
12670
12671     @Override
12672     public final ContentProviderHolder getContentProvider(
12673             IApplicationThread caller, String name, int userId, boolean stable) {
12674         enforceNotIsolatedCaller("getContentProvider");
12675         if (caller == null) {
12676             String msg = "null IApplicationThread when getting content provider "
12677                     + name;
12678             Slog.w(TAG, msg);
12679             throw new SecurityException(msg);
12680         }
12681         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
12682         // with cross-user grant.
12683         return getContentProviderImpl(caller, name, null, stable, userId);
12684     }
12685
12686     public ContentProviderHolder getContentProviderExternal(
12687             String name, int userId, IBinder token) {
12688         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12689             "Do not have permission in call getContentProviderExternal()");
12690         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12691                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
12692         return getContentProviderExternalUnchecked(name, token, userId);
12693     }
12694
12695     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12696             IBinder token, int userId) {
12697         return getContentProviderImpl(null, name, token, true, userId);
12698     }
12699
12700     /**
12701      * Drop a content provider from a ProcessRecord's bookkeeping
12702      */
12703     public void removeContentProvider(IBinder connection, boolean stable) {
12704         enforceNotIsolatedCaller("removeContentProvider");
12705         long ident = Binder.clearCallingIdentity();
12706         try {
12707             synchronized (this) {
12708                 ContentProviderConnection conn;
12709                 try {
12710                     conn = (ContentProviderConnection)connection;
12711                 } catch (ClassCastException e) {
12712                     String msg ="removeContentProvider: " + connection
12713                             + " not a ContentProviderConnection";
12714                     Slog.w(TAG, msg);
12715                     throw new IllegalArgumentException(msg);
12716                 }
12717                 if (conn == null) {
12718                     throw new NullPointerException("connection is null");
12719                 }
12720                 if (decProviderCountLocked(conn, null, null, stable)) {
12721                     updateOomAdjLocked();
12722                 }
12723             }
12724         } finally {
12725             Binder.restoreCallingIdentity(ident);
12726         }
12727     }
12728
12729     public void removeContentProviderExternal(String name, IBinder token) {
12730         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12731             "Do not have permission in call removeContentProviderExternal()");
12732         int userId = UserHandle.getCallingUserId();
12733         long ident = Binder.clearCallingIdentity();
12734         try {
12735             removeContentProviderExternalUnchecked(name, token, userId);
12736         } finally {
12737             Binder.restoreCallingIdentity(ident);
12738         }
12739     }
12740
12741     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12742         synchronized (this) {
12743             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12744             if(cpr == null) {
12745                 //remove from mProvidersByClass
12746                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12747                 return;
12748             }
12749
12750             //update content provider record entry info
12751             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12752             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12753             if (localCpr.hasExternalProcessHandles()) {
12754                 if (localCpr.removeExternalProcessHandleLocked(token)) {
12755                     updateOomAdjLocked();
12756                 } else {
12757                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12758                             + " with no external reference for token: "
12759                             + token + ".");
12760                 }
12761             } else {
12762                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12763                         + " with no external references.");
12764             }
12765         }
12766     }
12767
12768     public final void publishContentProviders(IApplicationThread caller,
12769             List<ContentProviderHolder> providers) {
12770         if (providers == null) {
12771             return;
12772         }
12773
12774         enforceNotIsolatedCaller("publishContentProviders");
12775         synchronized (this) {
12776             final ProcessRecord r = getRecordForAppLocked(caller);
12777             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12778             if (r == null) {
12779                 throw new SecurityException(
12780                         "Unable to find app for caller " + caller
12781                       + " (pid=" + Binder.getCallingPid()
12782                       + ") when publishing content providers");
12783             }
12784
12785             final long origId = Binder.clearCallingIdentity();
12786
12787             final int N = providers.size();
12788             for (int i = 0; i < N; i++) {
12789                 ContentProviderHolder src = providers.get(i);
12790                 if (src == null || src.info == null || src.provider == null) {
12791                     continue;
12792                 }
12793                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12794                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12795                 if (dst != null) {
12796                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12797                     mProviderMap.putProviderByClass(comp, dst);
12798                     String names[] = dst.info.authority.split(";");
12799                     for (int j = 0; j < names.length; j++) {
12800                         mProviderMap.putProviderByName(names[j], dst);
12801                     }
12802
12803                     int launchingCount = mLaunchingProviders.size();
12804                     int j;
12805                     boolean wasInLaunchingProviders = false;
12806                     for (j = 0; j < launchingCount; j++) {
12807                         if (mLaunchingProviders.get(j) == dst) {
12808                             mLaunchingProviders.remove(j);
12809                             wasInLaunchingProviders = true;
12810                             j--;
12811                             launchingCount--;
12812                         }
12813                     }
12814                     if (wasInLaunchingProviders) {
12815                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12816                     }
12817                     synchronized (dst) {
12818                         dst.provider = src.provider;
12819                         dst.proc = r;
12820                         dst.notifyAll();
12821                     }
12822                     updateOomAdjLocked(r, true);
12823                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12824                             src.info.authority);
12825                 }
12826             }
12827
12828             Binder.restoreCallingIdentity(origId);
12829         }
12830     }
12831
12832     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12833         ContentProviderConnection conn;
12834         try {
12835             conn = (ContentProviderConnection)connection;
12836         } catch (ClassCastException e) {
12837             String msg ="refContentProvider: " + connection
12838                     + " not a ContentProviderConnection";
12839             Slog.w(TAG, msg);
12840             throw new IllegalArgumentException(msg);
12841         }
12842         if (conn == null) {
12843             throw new NullPointerException("connection is null");
12844         }
12845
12846         synchronized (this) {
12847             if (stable > 0) {
12848                 conn.numStableIncs += stable;
12849             }
12850             stable = conn.stableCount + stable;
12851             if (stable < 0) {
12852                 throw new IllegalStateException("stableCount < 0: " + stable);
12853             }
12854
12855             if (unstable > 0) {
12856                 conn.numUnstableIncs += unstable;
12857             }
12858             unstable = conn.unstableCount + unstable;
12859             if (unstable < 0) {
12860                 throw new IllegalStateException("unstableCount < 0: " + unstable);
12861             }
12862
12863             if ((stable+unstable) <= 0) {
12864                 throw new IllegalStateException("ref counts can't go to zero here: stable="
12865                         + stable + " unstable=" + unstable);
12866             }
12867             conn.stableCount = stable;
12868             conn.unstableCount = unstable;
12869             return !conn.dead;
12870         }
12871     }
12872
12873     public void unstableProviderDied(IBinder connection) {
12874         ContentProviderConnection conn;
12875         try {
12876             conn = (ContentProviderConnection)connection;
12877         } catch (ClassCastException e) {
12878             String msg ="refContentProvider: " + connection
12879                     + " not a ContentProviderConnection";
12880             Slog.w(TAG, msg);
12881             throw new IllegalArgumentException(msg);
12882         }
12883         if (conn == null) {
12884             throw new NullPointerException("connection is null");
12885         }
12886
12887         // Safely retrieve the content provider associated with the connection.
12888         IContentProvider provider;
12889         synchronized (this) {
12890             provider = conn.provider.provider;
12891         }
12892
12893         if (provider == null) {
12894             // Um, yeah, we're way ahead of you.
12895             return;
12896         }
12897
12898         // Make sure the caller is being honest with us.
12899         if (provider.asBinder().pingBinder()) {
12900             // Er, no, still looks good to us.
12901             synchronized (this) {
12902                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12903                         + " says " + conn + " died, but we don't agree");
12904                 return;
12905             }
12906         }
12907
12908         // Well look at that!  It's dead!
12909         synchronized (this) {
12910             if (conn.provider.provider != provider) {
12911                 // But something changed...  good enough.
12912                 return;
12913             }
12914
12915             ProcessRecord proc = conn.provider.proc;
12916             if (proc == null || proc.thread == null) {
12917                 // Seems like the process is already cleaned up.
12918                 return;
12919             }
12920
12921             // As far as we're concerned, this is just like receiving a
12922             // death notification...  just a bit prematurely.
12923             reportUidInfoMessageLocked(TAG,
12924                     "Process " + proc.processName + " (pid " + proc.pid
12925                             + ") early provider death",
12926                     proc.info.uid);
12927             final long ident = Binder.clearCallingIdentity();
12928             try {
12929                 appDiedLocked(proc);
12930             } finally {
12931                 Binder.restoreCallingIdentity(ident);
12932             }
12933         }
12934     }
12935
12936     @Override
12937     public void appNotRespondingViaProvider(IBinder connection) {
12938         enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12939
12940         final ContentProviderConnection conn = (ContentProviderConnection) connection;
12941         if (conn == null) {
12942             Slog.w(TAG, "ContentProviderConnection is null");
12943             return;
12944         }
12945
12946         final ProcessRecord host = conn.provider.proc;
12947         if (host == null) {
12948             Slog.w(TAG, "Failed to find hosting ProcessRecord");
12949             return;
12950         }
12951
12952         mHandler.post(new Runnable() {
12953             @Override
12954             public void run() {
12955                 mAppErrors.appNotResponding(host, null, null, false,
12956                         "ContentProvider not responding");
12957             }
12958         });
12959     }
12960
12961     public final void installSystemProviders() {
12962         List<ProviderInfo> providers;
12963         synchronized (this) {
12964             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12965             providers = generateApplicationProvidersLocked(app);
12966             if (providers != null) {
12967                 for (int i=providers.size()-1; i>=0; i--) {
12968                     ProviderInfo pi = (ProviderInfo)providers.get(i);
12969                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12970                         Slog.w(TAG, "Not installing system proc provider " + pi.name
12971                                 + ": not system .apk");
12972                         providers.remove(i);
12973                     }
12974                 }
12975             }
12976         }
12977         if (providers != null) {
12978             mSystemThread.installSystemProviders(providers);
12979         }
12980
12981         synchronized (this) {
12982             mSystemProvidersInstalled = true;
12983         }
12984
12985         mConstants.start(mContext.getContentResolver());
12986         mCoreSettingsObserver = new CoreSettingsObserver(this);
12987         mFontScaleSettingObserver = new FontScaleSettingObserver();
12988         mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
12989         GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12990
12991         // Now that the settings provider is published we can consider sending
12992         // in a rescue party.
12993         RescueParty.onSettingsProviderPublished(mContext);
12994
12995         //mUsageStatsService.monitorPackages();
12996     }
12997
12998     void startPersistentApps(int matchFlags) {
12999         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
13000
13001         synchronized (this) {
13002             try {
13003                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
13004                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
13005                 for (ApplicationInfo app : apps) {
13006                     if (!"android".equals(app.packageName)) {
13007                         addAppLocked(app, null, false, null /* ABI override */);
13008                     }
13009                 }
13010             } catch (RemoteException ex) {
13011             }
13012         }
13013     }
13014
13015     /**
13016      * When a user is unlocked, we need to install encryption-unaware providers
13017      * belonging to any running apps.
13018      */
13019     void installEncryptionUnawareProviders(int userId) {
13020         // We're only interested in providers that are encryption unaware, and
13021         // we don't care about uninstalled apps, since there's no way they're
13022         // running at this point.
13023         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
13024
13025         synchronized (this) {
13026             final int NP = mProcessNames.getMap().size();
13027             for (int ip = 0; ip < NP; ip++) {
13028                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13029                 final int NA = apps.size();
13030                 for (int ia = 0; ia < NA; ia++) {
13031                     final ProcessRecord app = apps.valueAt(ia);
13032                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
13033
13034                     final int NG = app.pkgList.size();
13035                     for (int ig = 0; ig < NG; ig++) {
13036                         try {
13037                             final String pkgName = app.pkgList.keyAt(ig);
13038                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
13039                                     .getPackageInfo(pkgName, matchFlags, userId);
13040                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
13041                                 for (ProviderInfo pi : pkgInfo.providers) {
13042                                     // TODO: keep in sync with generateApplicationProvidersLocked
13043                                     final boolean processMatch = Objects.equals(pi.processName,
13044                                             app.processName) || pi.multiprocess;
13045                                     final boolean userMatch = isSingleton(pi.processName,
13046                                             pi.applicationInfo, pi.name, pi.flags)
13047                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
13048                                     if (processMatch && userMatch) {
13049                                         Log.v(TAG, "Installing " + pi);
13050                                         app.thread.scheduleInstallProvider(pi);
13051                                     } else {
13052                                         Log.v(TAG, "Skipping " + pi);
13053                                     }
13054                                 }
13055                             }
13056                         } catch (RemoteException ignored) {
13057                         }
13058                     }
13059                 }
13060             }
13061         }
13062     }
13063
13064     /**
13065      * Allows apps to retrieve the MIME type of a URI.
13066      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
13067      * users, then it does not need permission to access the ContentProvider.
13068      * Either, it needs cross-user uri grants.
13069      *
13070      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
13071      *
13072      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
13073      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
13074      */
13075     public String getProviderMimeType(Uri uri, int userId) {
13076         enforceNotIsolatedCaller("getProviderMimeType");
13077         final String name = uri.getAuthority();
13078         int callingUid = Binder.getCallingUid();
13079         int callingPid = Binder.getCallingPid();
13080         long ident = 0;
13081         boolean clearedIdentity = false;
13082         userId = mUserController.unsafeConvertIncomingUser(userId);
13083         if (canClearIdentity(callingPid, callingUid, userId)) {
13084             clearedIdentity = true;
13085             ident = Binder.clearCallingIdentity();
13086         }
13087         ContentProviderHolder holder = null;
13088         try {
13089             holder = getContentProviderExternalUnchecked(name, null, userId);
13090             if (holder != null) {
13091                 return holder.provider.getType(uri);
13092             }
13093         } catch (RemoteException e) {
13094             Log.w(TAG, "Content provider dead retrieving " + uri, e);
13095             return null;
13096         } catch (Exception e) {
13097             Log.w(TAG, "Exception while determining type of " + uri, e);
13098             return null;
13099         } finally {
13100             // We need to clear the identity to call removeContentProviderExternalUnchecked
13101             if (!clearedIdentity) {
13102                 ident = Binder.clearCallingIdentity();
13103             }
13104             try {
13105                 if (holder != null) {
13106                     removeContentProviderExternalUnchecked(name, null, userId);
13107                 }
13108             } finally {
13109                 Binder.restoreCallingIdentity(ident);
13110             }
13111         }
13112
13113         return null;
13114     }
13115
13116     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
13117         if (UserHandle.getUserId(callingUid) == userId) {
13118             return true;
13119         }
13120         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13121                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
13122                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13123                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13124                 return true;
13125         }
13126         return false;
13127     }
13128
13129     // =========================================================
13130     // GLOBAL MANAGEMENT
13131     // =========================================================
13132
13133     @GuardedBy("this")
13134     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
13135             boolean isolated, int isolatedUid) {
13136         String proc = customProcess != null ? customProcess : info.processName;
13137         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13138         final int userId = UserHandle.getUserId(info.uid);
13139         int uid = info.uid;
13140         if (isolated) {
13141             if (isolatedUid == 0) {
13142                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
13143                 while (true) {
13144                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
13145                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
13146                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
13147                     }
13148                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
13149                     mNextIsolatedProcessUid++;
13150                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
13151                         // No process for this uid, use it.
13152                         break;
13153                     }
13154                     stepsLeft--;
13155                     if (stepsLeft <= 0) {
13156                         return null;
13157                     }
13158                 }
13159             } else {
13160                 // Special case for startIsolatedProcess (internal only), where
13161                 // the uid of the isolated process is specified by the caller.
13162                 uid = isolatedUid;
13163             }
13164             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
13165
13166             // Register the isolated UID with this application so BatteryStats knows to
13167             // attribute resource usage to the application.
13168             //
13169             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
13170             // about the process state of the isolated UID *before* it is registered with the
13171             // owning application.
13172             mBatteryStatsService.addIsolatedUid(uid, info.uid);
13173         }
13174         final ProcessRecord r = new ProcessRecord(this, stats, info, proc, uid);
13175         if (!mBooted && !mBooting
13176                 && userId == UserHandle.USER_SYSTEM
13177                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
13178             // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
13179             r.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
13180             r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
13181             r.persistent = true;
13182             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
13183         }
13184         if (isolated && isolatedUid != 0) {
13185             // Special case for startIsolatedProcess (internal only) - assume the process
13186             // is required by the system server to prevent it being killed.
13187             r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
13188         }
13189         addProcessNameLocked(r);
13190         return r;
13191     }
13192
13193     private boolean uidOnBackgroundWhitelist(final int uid) {
13194         final int appId = UserHandle.getAppId(uid);
13195         final int[] whitelist = mBackgroundAppIdWhitelist;
13196         final int N = whitelist.length;
13197         for (int i = 0; i < N; i++) {
13198             if (appId == whitelist[i]) {
13199                 return true;
13200             }
13201         }
13202         return false;
13203     }
13204
13205     @Override
13206     public boolean isBackgroundRestricted(String packageName) {
13207         final int callingUid = Binder.getCallingUid();
13208         final IPackageManager pm = AppGlobals.getPackageManager();
13209         try {
13210             final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
13211                     UserHandle.getUserId(callingUid));
13212             if (packageUid != callingUid) {
13213                 throw new IllegalArgumentException("Uid " + callingUid
13214                         + " cannot query restriction state for package " + packageName);
13215             }
13216         } catch (RemoteException exc) {
13217             // Ignore.
13218         }
13219         return isBackgroundRestrictedNoCheck(callingUid, packageName);
13220     }
13221
13222     boolean isBackgroundRestrictedNoCheck(final int uid, final String packageName) {
13223         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
13224                 uid, packageName);
13225         return mode != AppOpsManager.MODE_ALLOWED;
13226     }
13227
13228     @Override
13229     public void backgroundWhitelistUid(final int uid) {
13230         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13231             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
13232         }
13233
13234         if (DEBUG_BACKGROUND_CHECK) {
13235             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
13236         }
13237         synchronized (this) {
13238             final int N = mBackgroundAppIdWhitelist.length;
13239             int[] newList = new int[N+1];
13240             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
13241             newList[N] = UserHandle.getAppId(uid);
13242             mBackgroundAppIdWhitelist = newList;
13243         }
13244     }
13245
13246     @GuardedBy("this")
13247     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13248             String abiOverride) {
13249         return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
13250                 abiOverride);
13251     }
13252
13253     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13254             boolean disableHiddenApiChecks, String abiOverride) {
13255         ProcessRecord app;
13256         if (!isolated) {
13257             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
13258                     info.uid, true);
13259         } else {
13260             app = null;
13261         }
13262
13263         if (app == null) {
13264             app = newProcessRecordLocked(info, customProcess, isolated, 0);
13265             updateLruProcessLocked(app, false, null);
13266             updateOomAdjLocked();
13267         }
13268
13269         // This package really, really can not be stopped.
13270         try {
13271             AppGlobals.getPackageManager().setPackageStoppedState(
13272                     info.packageName, false, UserHandle.getUserId(app.uid));
13273         } catch (RemoteException e) {
13274         } catch (IllegalArgumentException e) {
13275             Slog.w(TAG, "Failed trying to unstop package "
13276                     + info.packageName + ": " + e);
13277         }
13278
13279         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
13280             app.persistent = true;
13281             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
13282         }
13283         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
13284             mPersistentStartingProcesses.add(app);
13285             startProcessLocked(app, "added application",
13286                     customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
13287                     abiOverride);
13288         }
13289
13290         return app;
13291     }
13292
13293     public void unhandledBack() {
13294         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
13295                 "unhandledBack()");
13296
13297         synchronized(this) {
13298             final long origId = Binder.clearCallingIdentity();
13299             try {
13300                 getFocusedStack().unhandledBackLocked();
13301             } finally {
13302                 Binder.restoreCallingIdentity(origId);
13303             }
13304         }
13305     }
13306
13307     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
13308         enforceNotIsolatedCaller("openContentUri");
13309         final int userId = UserHandle.getCallingUserId();
13310         final Uri uri = Uri.parse(uriString);
13311         String name = uri.getAuthority();
13312         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
13313         ParcelFileDescriptor pfd = null;
13314         if (cph != null) {
13315             // We record the binder invoker's uid in thread-local storage before
13316             // going to the content provider to open the file.  Later, in the code
13317             // that handles all permissions checks, we look for this uid and use
13318             // that rather than the Activity Manager's own uid.  The effect is that
13319             // we do the check against the caller's permissions even though it looks
13320             // to the content provider like the Activity Manager itself is making
13321             // the request.
13322             Binder token = new Binder();
13323             sCallerIdentity.set(new Identity(
13324                     token, Binder.getCallingPid(), Binder.getCallingUid()));
13325             try {
13326                 pfd = cph.provider.openFile(null, uri, "r", null, token);
13327             } catch (FileNotFoundException e) {
13328                 // do nothing; pfd will be returned null
13329             } finally {
13330                 // Ensure that whatever happens, we clean up the identity state
13331                 sCallerIdentity.remove();
13332                 // Ensure we're done with the provider.
13333                 removeContentProviderExternalUnchecked(name, null, userId);
13334             }
13335         } else {
13336             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
13337         }
13338         return pfd;
13339     }
13340
13341     // Actually is sleeping or shutting down or whatever else in the future
13342     // is an inactive state.
13343     boolean isSleepingOrShuttingDownLocked() {
13344         return isSleepingLocked() || mShuttingDown;
13345     }
13346
13347     boolean isShuttingDownLocked() {
13348         return mShuttingDown;
13349     }
13350
13351     boolean isSleepingLocked() {
13352         return mSleeping;
13353     }
13354
13355     void reportGlobalUsageEventLocked(int event) {
13356         mUsageStatsService.reportEvent("android", mUserController.getCurrentUserId(), event);
13357         int[] profiles = mUserController.getCurrentProfileIds();
13358         if (profiles != null) {
13359             for (int i = profiles.length - 1; i >= 0; i--) {
13360                 mUsageStatsService.reportEvent((String)null, profiles[i], event);
13361             }
13362         }
13363     }
13364
13365     void reportCurWakefulnessUsageEventLocked() {
13366         reportGlobalUsageEventLocked(mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE
13367                 ? UsageEvents.Event.SCREEN_INTERACTIVE
13368                 : UsageEvents.Event.SCREEN_NON_INTERACTIVE);
13369     }
13370
13371     void reportCurKeyguardUsageEventLocked() {
13372         reportGlobalUsageEventLocked(mKeyguardShown
13373                 ? UsageEvents.Event.KEYGUARD_SHOWN
13374                 : UsageEvents.Event.KEYGUARD_HIDDEN);
13375     }
13376
13377     void onWakefulnessChanged(int wakefulness) {
13378         synchronized(this) {
13379             boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13380             boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13381             mWakefulness = wakefulness;
13382
13383             if (wasAwake != isAwake) {
13384                 // Also update state in a special way for running foreground services UI.
13385                 mServices.updateScreenStateLocked(isAwake);
13386                 reportCurWakefulnessUsageEventLocked();
13387                 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
13388                         .sendToTarget();
13389             }
13390             updateOomAdjLocked();
13391         }
13392     }
13393
13394     @GuardedBy("this")
13395     void finishRunningVoiceLocked() {
13396         if (mRunningVoice != null) {
13397             mRunningVoice = null;
13398             mVoiceWakeLock.release();
13399             updateSleepIfNeededLocked();
13400         }
13401     }
13402
13403     void startTimeTrackingFocusedActivityLocked() {
13404         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
13405         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
13406             mCurAppTimeTracker.start(resumedActivity.packageName);
13407         }
13408     }
13409
13410     @GuardedBy("this")
13411     void updateSleepIfNeededLocked() {
13412         final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
13413         final boolean wasSleeping = mSleeping;
13414
13415         if (!shouldSleep) {
13416             // If wasSleeping is true, we need to wake up activity manager state from when
13417             // we started sleeping. In either case, we need to apply the sleep tokens, which
13418             // will wake up stacks or put them to sleep as appropriate.
13419             if (wasSleeping) {
13420                 mSleeping = false;
13421                 startTimeTrackingFocusedActivityLocked();
13422                 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
13423                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
13424             }
13425             mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
13426             if (wasSleeping) {
13427                 updateOomAdjLocked();
13428             }
13429         } else if (!mSleeping && shouldSleep) {
13430             mSleeping = true;
13431             if (mCurAppTimeTracker != null) {
13432                 mCurAppTimeTracker.stop();
13433             }
13434             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
13435             mStackSupervisor.goingToSleepLocked();
13436             updateResumedAppTrace(null /* resumed */);
13437             updateOomAdjLocked();
13438         }
13439     }
13440
13441     /** Pokes the task persister. */
13442     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
13443         mRecentTasks.notifyTaskPersisterLocked(task, flush);
13444     }
13445
13446     /**
13447      * Notifies all listeners when the pinned stack animation starts.
13448      */
13449     @Override
13450     public void notifyPinnedStackAnimationStarted() {
13451         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
13452     }
13453
13454     /**
13455      * Notifies all listeners when the pinned stack animation ends.
13456      */
13457     @Override
13458     public void notifyPinnedStackAnimationEnded() {
13459         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
13460     }
13461
13462     @Override
13463     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
13464         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
13465     }
13466
13467     @Override
13468     public boolean shutdown(int timeout) {
13469         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
13470                 != PackageManager.PERMISSION_GRANTED) {
13471             throw new SecurityException("Requires permission "
13472                     + android.Manifest.permission.SHUTDOWN);
13473         }
13474
13475         boolean timedout = false;
13476
13477         synchronized(this) {
13478             mShuttingDown = true;
13479             mStackSupervisor.prepareForShutdownLocked();
13480             updateEventDispatchingLocked();
13481             timedout = mStackSupervisor.shutdownLocked(timeout);
13482         }
13483
13484         mAppOpsService.shutdown();
13485         if (mUsageStatsService != null) {
13486             mUsageStatsService.prepareShutdown();
13487         }
13488         mBatteryStatsService.shutdown();
13489         synchronized (this) {
13490             mProcessStats.shutdownLocked();
13491             notifyTaskPersisterLocked(null, true);
13492         }
13493
13494         return timedout;
13495     }
13496
13497     public final void activitySlept(IBinder token) {
13498         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
13499
13500         final long origId = Binder.clearCallingIdentity();
13501
13502         synchronized (this) {
13503             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13504             if (r != null) {
13505                 mStackSupervisor.activitySleptLocked(r);
13506             }
13507         }
13508
13509         Binder.restoreCallingIdentity(origId);
13510     }
13511
13512     @GuardedBy("this")
13513     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
13514         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
13515         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
13516         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
13517             boolean wasRunningVoice = mRunningVoice != null;
13518             mRunningVoice = session;
13519             if (!wasRunningVoice) {
13520                 mVoiceWakeLock.acquire();
13521                 updateSleepIfNeededLocked();
13522             }
13523         }
13524     }
13525
13526     private void updateEventDispatchingLocked() {
13527         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
13528     }
13529
13530     @Override
13531     public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
13532             int secondaryDisplayShowing) {
13533         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
13534                 != PackageManager.PERMISSION_GRANTED) {
13535             throw new SecurityException("Requires permission "
13536                     + android.Manifest.permission.DEVICE_POWER);
13537         }
13538
13539         synchronized(this) {
13540             long ident = Binder.clearCallingIdentity();
13541             if (mKeyguardShown != keyguardShowing) {
13542                 mKeyguardShown = keyguardShowing;
13543                 reportCurKeyguardUsageEventLocked();
13544             }
13545             try {
13546                 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
13547                         secondaryDisplayShowing);
13548             } finally {
13549                 Binder.restoreCallingIdentity(ident);
13550             }
13551         }
13552
13553         mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
13554                 .sendToTarget();
13555     }
13556
13557     @Override
13558     public void notifyLockedProfile(@UserIdInt int userId) {
13559         try {
13560             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
13561                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
13562             }
13563         } catch (RemoteException ex) {
13564             throw new SecurityException("Fail to check is caller a privileged app", ex);
13565         }
13566
13567         synchronized (this) {
13568             final long ident = Binder.clearCallingIdentity();
13569             try {
13570                 if (mUserController.shouldConfirmCredentials(userId)) {
13571                     if (mKeyguardController.isKeyguardLocked()) {
13572                         // Showing launcher to avoid user entering credential twice.
13573                         final int currentUserId = mUserController.getCurrentUserId();
13574                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
13575                     }
13576                     mStackSupervisor.lockAllProfileTasks(userId);
13577                 }
13578             } finally {
13579                 Binder.restoreCallingIdentity(ident);
13580             }
13581         }
13582     }
13583
13584     @Override
13585     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
13586         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
13587         synchronized (this) {
13588             final long ident = Binder.clearCallingIdentity();
13589             try {
13590                 intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
13591                         FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
13592                         FLAG_ACTIVITY_TASK_ON_HOME);
13593                 ActivityOptions activityOptions = options != null
13594                         ? new ActivityOptions(options)
13595                         : ActivityOptions.makeBasic();
13596                 activityOptions.setLaunchTaskId(
13597                         mStackSupervisor.getHomeActivity().getTask().taskId);
13598                 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
13599                         UserHandle.CURRENT);
13600             } finally {
13601                 Binder.restoreCallingIdentity(ident);
13602             }
13603         }
13604     }
13605
13606     @Override
13607     public void stopAppSwitches() {
13608         enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
13609         synchronized(this) {
13610             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
13611                     + APP_SWITCH_DELAY_TIME;
13612             mDidAppSwitch = false;
13613             mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
13614         }
13615     }
13616
13617     public void resumeAppSwitches() {
13618         enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
13619         synchronized(this) {
13620             // Note that we don't execute any pending app switches... we will
13621             // let those wait until either the timeout, or the next start
13622             // activity request.
13623             mAppSwitchesAllowedTime = 0;
13624         }
13625     }
13626
13627     boolean checkAllowAppSwitchUid(int uid) {
13628         ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
13629         if (types != null) {
13630             for (int i = types.size() - 1; i >= 0; i--) {
13631                 if (types.valueAt(i).intValue() == uid) {
13632                     return true;
13633                 }
13634             }
13635         }
13636         return false;
13637     }
13638
13639     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
13640             int callingPid, int callingUid, String name) {
13641         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
13642             return true;
13643         }
13644
13645         if (mRecentTasks.isCallerRecents(sourceUid)) {
13646             return true;
13647         }
13648
13649         int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
13650         if (perm == PackageManager.PERMISSION_GRANTED) {
13651             return true;
13652         }
13653         if (checkAllowAppSwitchUid(sourceUid)) {
13654             return true;
13655         }
13656
13657         // If the actual IPC caller is different from the logical source, then
13658         // also see if they are allowed to control app switches.
13659         if (callingUid != -1 && callingUid != sourceUid) {
13660             perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
13661             if (perm == PackageManager.PERMISSION_GRANTED) {
13662                 return true;
13663             }
13664             if (checkAllowAppSwitchUid(callingUid)) {
13665                 return true;
13666             }
13667         }
13668
13669         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
13670         return false;
13671     }
13672
13673     public void setDebugApp(String packageName, boolean waitForDebugger,
13674             boolean persistent) {
13675         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
13676                 "setDebugApp()");
13677
13678         long ident = Binder.clearCallingIdentity();
13679         try {
13680             // Note that this is not really thread safe if there are multiple
13681             // callers into it at the same time, but that's not a situation we
13682             // care about.
13683             if (persistent) {
13684                 final ContentResolver resolver = mContext.getContentResolver();
13685                 Settings.Global.putString(
13686                     resolver, Settings.Global.DEBUG_APP,
13687                     packageName);
13688                 Settings.Global.putInt(
13689                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13690                     waitForDebugger ? 1 : 0);
13691             }
13692
13693             synchronized (this) {
13694                 if (!persistent) {
13695                     mOrigDebugApp = mDebugApp;
13696                     mOrigWaitForDebugger = mWaitForDebugger;
13697                 }
13698                 mDebugApp = packageName;
13699                 mWaitForDebugger = waitForDebugger;
13700                 mDebugTransient = !persistent;
13701                 if (packageName != null) {
13702                     forceStopPackageLocked(packageName, -1, false, false, true, true,
13703                             false, UserHandle.USER_ALL, "set debug app");
13704                 }
13705             }
13706         } finally {
13707             Binder.restoreCallingIdentity(ident);
13708         }
13709     }
13710
13711     /**
13712      * Set or remove an agent to be run whenever an app with the given process name starts.
13713      *
13714      * This method will not check whether the given process name matches a debuggable app. That
13715      * would require scanning all current packages, and a rescan when new packages are installed
13716      * or updated.
13717      *
13718      * Instead, do the check when an application is started and matched to a stored agent.
13719      *
13720      * @param packageName the process name of the app.
13721      * @param agent the agent string to be used, or null to remove any previously set agent.
13722      */
13723     @Override
13724     public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
13725         synchronized (this) {
13726             // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13727             // its own permission.
13728             if (checkCallingPermission(
13729                     android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
13730                         PackageManager.PERMISSION_GRANTED) {
13731                 throw new SecurityException(
13732                         "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13733             }
13734
13735             if (agent == null) {
13736                 if (mAppAgentMap != null) {
13737                     mAppAgentMap.remove(packageName);
13738                     if (mAppAgentMap.isEmpty()) {
13739                         mAppAgentMap = null;
13740                     }
13741                 }
13742             } else {
13743                 if (mAppAgentMap == null) {
13744                     mAppAgentMap = new HashMap<>();
13745                 }
13746                 if (mAppAgentMap.size() >= 100) {
13747                     // Limit the size of the map, to avoid OOMEs.
13748                     Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
13749                             + "/" + agent);
13750                     return;
13751                 }
13752                 mAppAgentMap.put(packageName, agent);
13753             }
13754         }
13755     }
13756
13757     void setTrackAllocationApp(ApplicationInfo app, String processName) {
13758         synchronized (this) {
13759             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13760             if (!isDebuggable) {
13761                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13762                     throw new SecurityException("Process not debuggable: " + app.packageName);
13763                 }
13764             }
13765
13766             mTrackAllocationApp = processName;
13767         }
13768     }
13769
13770     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
13771         synchronized (this) {
13772             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13773             if (!isDebuggable) {
13774                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13775                     throw new SecurityException("Process not debuggable: " + app.packageName);
13776                 }
13777             }
13778             mProfileApp = processName;
13779
13780             if (mProfilerInfo != null) {
13781                 if (mProfilerInfo.profileFd != null) {
13782                     try {
13783                         mProfilerInfo.profileFd.close();
13784                     } catch (IOException e) {
13785                     }
13786                 }
13787             }
13788             mProfilerInfo = new ProfilerInfo(profilerInfo);
13789             mProfileType = 0;
13790         }
13791     }
13792
13793     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
13794         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13795         if (!isDebuggable) {
13796             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13797                 throw new SecurityException("Process not debuggable: " + app.packageName);
13798             }
13799         }
13800         mNativeDebuggingApp = processName;
13801     }
13802
13803     @Override
13804     public void setAlwaysFinish(boolean enabled) {
13805         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13806                 "setAlwaysFinish()");
13807
13808         long ident = Binder.clearCallingIdentity();
13809         try {
13810             Settings.Global.putInt(
13811                     mContext.getContentResolver(),
13812                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13813
13814             synchronized (this) {
13815                 mAlwaysFinishActivities = enabled;
13816             }
13817         } finally {
13818             Binder.restoreCallingIdentity(ident);
13819         }
13820     }
13821
13822     @Override
13823     public void setActivityController(IActivityController controller, boolean imAMonkey) {
13824         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13825                 "setActivityController()");
13826         synchronized (this) {
13827             mController = controller;
13828             mControllerIsAMonkey = imAMonkey;
13829             Watchdog.getInstance().setActivityController(controller);
13830         }
13831     }
13832
13833     @Override
13834     public void setUserIsMonkey(boolean userIsMonkey) {
13835         synchronized (this) {
13836             synchronized (mPidsSelfLocked) {
13837                 final int callingPid = Binder.getCallingPid();
13838                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13839                 if (proc == null) {
13840                     throw new SecurityException("Unknown process: " + callingPid);
13841                 }
13842                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13843                     throw new SecurityException("Only an instrumentation process "
13844                             + "with a UiAutomation can call setUserIsMonkey");
13845                 }
13846             }
13847             mUserIsMonkey = userIsMonkey;
13848         }
13849     }
13850
13851     @Override
13852     public boolean isUserAMonkey() {
13853         synchronized (this) {
13854             // If there is a controller also implies the user is a monkey.
13855             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13856         }
13857     }
13858
13859     /**
13860      * @deprecated This method is only used by a few internal components and it will soon be
13861      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13862      * No new code should be calling it.
13863      */
13864     @Deprecated
13865     @Override
13866     public void requestBugReport(int bugreportType) {
13867         String extraOptions = null;
13868         switch (bugreportType) {
13869             case ActivityManager.BUGREPORT_OPTION_FULL:
13870                 // Default options.
13871                 break;
13872             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13873                 extraOptions = "bugreportplus";
13874                 break;
13875             case ActivityManager.BUGREPORT_OPTION_REMOTE:
13876                 extraOptions = "bugreportremote";
13877                 break;
13878             case ActivityManager.BUGREPORT_OPTION_WEAR:
13879                 extraOptions = "bugreportwear";
13880                 break;
13881             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13882                 extraOptions = "bugreporttelephony";
13883                 break;
13884             case ActivityManager.BUGREPORT_OPTION_WIFI:
13885                 extraOptions = "bugreportwifi";
13886                 break;
13887             default:
13888                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13889                         + bugreportType);
13890         }
13891         // Always log caller, even if it does not have permission to dump.
13892         String type = extraOptions == null ? "bugreport" : extraOptions;
13893         Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13894
13895         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13896         if (extraOptions != null) {
13897             SystemProperties.set("dumpstate.options", extraOptions);
13898         }
13899         SystemProperties.set("ctl.start", "bugreport");
13900     }
13901
13902     /**
13903      * @deprecated This method is only used by a few internal components and it will soon be
13904      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13905      * No new code should be calling it.
13906      */
13907     @Deprecated
13908     private void requestBugReportWithDescription(String shareTitle, String shareDescription,
13909                                                  int bugreportType) {
13910         if (!TextUtils.isEmpty(shareTitle)) {
13911             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13912                 String errorStr = "shareTitle should be less than " +
13913                         MAX_BUGREPORT_TITLE_SIZE + " characters";
13914                 throw new IllegalArgumentException(errorStr);
13915             } else {
13916                 if (!TextUtils.isEmpty(shareDescription)) {
13917                     int length;
13918                     try {
13919                         length = shareDescription.getBytes("UTF-8").length;
13920                     } catch (UnsupportedEncodingException e) {
13921                         String errorStr = "shareDescription: UnsupportedEncodingException";
13922                         throw new IllegalArgumentException(errorStr);
13923                     }
13924                     if (length > SystemProperties.PROP_VALUE_MAX) {
13925                         String errorStr = "shareTitle should be less than " +
13926                                 SystemProperties.PROP_VALUE_MAX + " bytes";
13927                         throw new IllegalArgumentException(errorStr);
13928                     } else {
13929                         SystemProperties.set("dumpstate.options.description", shareDescription);
13930                     }
13931                 }
13932                 SystemProperties.set("dumpstate.options.title", shareTitle);
13933             }
13934         }
13935
13936         Slog.d(TAG, "Bugreport notification title " + shareTitle
13937                 + " description " + shareDescription);
13938         requestBugReport(bugreportType);
13939     }
13940
13941     /**
13942      * @deprecated This method is only used by a few internal components and it will soon be
13943      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13944      * No new code should be calling it.
13945      */
13946     @Deprecated
13947     @Override
13948     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13949         requestBugReportWithDescription(shareTitle, shareDescription,
13950                 ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13951     }
13952
13953     /**
13954      * @deprecated This method is only used by a few internal components and it will soon be
13955      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13956      * No new code should be calling it.
13957      */
13958     @Deprecated
13959     @Override
13960     public void requestWifiBugReport(String shareTitle, String shareDescription) {
13961         requestBugReportWithDescription(shareTitle, shareDescription,
13962                 ActivityManager.BUGREPORT_OPTION_WIFI);
13963     }
13964
13965
13966     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13967         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13968     }
13969
13970     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13971         if (r != null && (r.instr != null || r.usingWrapper)) {
13972             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13973         }
13974         return KEY_DISPATCHING_TIMEOUT;
13975     }
13976
13977     @Override
13978     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13979         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13980                 != PackageManager.PERMISSION_GRANTED) {
13981             throw new SecurityException("Requires permission "
13982                     + android.Manifest.permission.FILTER_EVENTS);
13983         }
13984         ProcessRecord proc;
13985         long timeout;
13986         synchronized (this) {
13987             synchronized (mPidsSelfLocked) {
13988                 proc = mPidsSelfLocked.get(pid);
13989             }
13990             timeout = getInputDispatchingTimeoutLocked(proc);
13991         }
13992
13993         if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13994             return -1;
13995         }
13996
13997         return timeout;
13998     }
13999
14000     /**
14001      * Handle input dispatching timeouts.
14002      * Returns whether input dispatching should be aborted or not.
14003      */
14004     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
14005             final ActivityRecord activity, final ActivityRecord parent,
14006             final boolean aboveSystem, String reason) {
14007         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
14008                 != PackageManager.PERMISSION_GRANTED) {
14009             throw new SecurityException("Requires permission "
14010                     + android.Manifest.permission.FILTER_EVENTS);
14011         }
14012
14013         final String annotation;
14014         if (reason == null) {
14015             annotation = "Input dispatching timed out";
14016         } else {
14017             annotation = "Input dispatching timed out (" + reason + ")";
14018         }
14019
14020         if (proc != null) {
14021             synchronized (this) {
14022                 if (proc.debugging) {
14023                     return false;
14024                 }
14025
14026                 if (proc.instr != null) {
14027                     Bundle info = new Bundle();
14028                     info.putString("shortMsg", "keyDispatchingTimedOut");
14029                     info.putString("longMsg", annotation);
14030                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
14031                     return true;
14032                 }
14033             }
14034             mHandler.post(new Runnable() {
14035                 @Override
14036                 public void run() {
14037                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
14038                 }
14039             });
14040         }
14041
14042         return true;
14043     }
14044
14045     @Override
14046     public Bundle getAssistContextExtras(int requestType) {
14047         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
14048                 null, null, true /* focused */, true /* newSessionId */,
14049                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
14050         if (pae == null) {
14051             return null;
14052         }
14053         synchronized (pae) {
14054             while (!pae.haveResult) {
14055                 try {
14056                     pae.wait();
14057                 } catch (InterruptedException e) {
14058                 }
14059             }
14060         }
14061         synchronized (this) {
14062             buildAssistBundleLocked(pae, pae.result);
14063             mPendingAssistExtras.remove(pae);
14064             mUiHandler.removeCallbacks(pae);
14065         }
14066         return pae.extras;
14067     }
14068
14069     @Override
14070     public boolean isAssistDataAllowedOnCurrentActivity() {
14071         int userId;
14072         synchronized (this) {
14073             final ActivityStack focusedStack = getFocusedStack();
14074             if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
14075                 return false;
14076             }
14077
14078             final ActivityRecord activity = focusedStack.getTopActivity();
14079             if (activity == null) {
14080                 return false;
14081             }
14082             userId = activity.userId;
14083         }
14084         return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
14085     }
14086
14087     @Override
14088     public boolean showAssistFromActivity(IBinder token, Bundle args) {
14089         long ident = Binder.clearCallingIdentity();
14090         try {
14091             synchronized (this) {
14092                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
14093                 ActivityRecord top = getFocusedStack().getTopActivity();
14094                 if (top != caller) {
14095                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
14096                             + " is not current top " + top);
14097                     return false;
14098                 }
14099                 if (!top.nowVisible) {
14100                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
14101                             + " is not visible");
14102                     return false;
14103                 }
14104             }
14105             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
14106                     token);
14107         } finally {
14108             Binder.restoreCallingIdentity(ident);
14109         }
14110     }
14111
14112     @Override
14113     public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
14114             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
14115         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
14116                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
14117                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
14118     }
14119
14120     @Override
14121     public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
14122             IBinder activityToken, int flags) {
14123         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
14124                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
14125                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
14126     }
14127
14128     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
14129             IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
14130             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
14131             int flags) {
14132         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
14133                 "enqueueAssistContext()");
14134
14135         synchronized (this) {
14136             ActivityRecord activity = getFocusedStack().getTopActivity();
14137             if (activity == null) {
14138                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
14139                 return null;
14140             }
14141             if (activity.app == null || activity.app.thread == null) {
14142                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
14143                 return null;
14144             }
14145             if (focused) {
14146                 if (activityToken != null) {
14147                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
14148                     if (activity != caller) {
14149                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
14150                                 + " is not current top " + activity);
14151                         return null;
14152                     }
14153                 }
14154             } else {
14155                 activity = ActivityRecord.forTokenLocked(activityToken);
14156                 if (activity == null) {
14157                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
14158                             + " couldn't be found");
14159                     return null;
14160                 }
14161                 if (activity.app == null || activity.app.thread == null) {
14162                     Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
14163                     return null;
14164                 }
14165             }
14166
14167             PendingAssistExtras pae;
14168             Bundle extras = new Bundle();
14169             if (args != null) {
14170                 extras.putAll(args);
14171             }
14172             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
14173             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
14174
14175             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
14176                     userHandle);
14177             pae.isHome = activity.isActivityTypeHome();
14178
14179             // Increment the sessionId if necessary
14180             if (newSessionId) {
14181                 mViSessionId++;
14182             }
14183             try {
14184                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
14185                         mViSessionId, flags);
14186                 mPendingAssistExtras.add(pae);
14187                 mUiHandler.postDelayed(pae, timeout);
14188             } catch (RemoteException e) {
14189                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
14190                 return null;
14191             }
14192             return pae;
14193         }
14194     }
14195
14196     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
14197         IAssistDataReceiver receiver;
14198         synchronized (this) {
14199             mPendingAssistExtras.remove(pae);
14200             receiver = pae.receiver;
14201         }
14202         if (receiver != null) {
14203             // Caller wants result sent back to them.
14204             Bundle sendBundle = new Bundle();
14205             // At least return the receiver extras
14206             sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
14207             try {
14208                 pae.receiver.onHandleAssistData(sendBundle);
14209             } catch (RemoteException e) {
14210             }
14211         }
14212     }
14213
14214     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
14215         if (result != null) {
14216             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
14217         }
14218         if (pae.hint != null) {
14219             pae.extras.putBoolean(pae.hint, true);
14220         }
14221     }
14222
14223     /** Called from an app when assist data is ready. */
14224     @Override
14225     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
14226             AssistContent content, Uri referrer) {
14227         PendingAssistExtras pae = (PendingAssistExtras)token;
14228         synchronized (pae) {
14229             pae.result = extras;
14230             pae.structure = structure;
14231             pae.content = content;
14232             if (referrer != null) {
14233                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
14234             }
14235             if (structure != null) {
14236                 structure.setHomeActivity(pae.isHome);
14237             }
14238             pae.haveResult = true;
14239             pae.notifyAll();
14240             if (pae.intent == null && pae.receiver == null) {
14241                 // Caller is just waiting for the result.
14242                 return;
14243             }
14244         }
14245         // We are now ready to launch the assist activity.
14246         IAssistDataReceiver sendReceiver = null;
14247         Bundle sendBundle = null;
14248         synchronized (this) {
14249             buildAssistBundleLocked(pae, extras);
14250             boolean exists = mPendingAssistExtras.remove(pae);
14251             mUiHandler.removeCallbacks(pae);
14252             if (!exists) {
14253                 // Timed out.
14254                 return;
14255             }
14256
14257             if ((sendReceiver=pae.receiver) != null) {
14258                 // Caller wants result sent back to them.
14259                 sendBundle = new Bundle();
14260                 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
14261                 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
14262                 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
14263                 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
14264             }
14265         }
14266         if (sendReceiver != null) {
14267             try {
14268                 sendReceiver.onHandleAssistData(sendBundle);
14269             } catch (RemoteException e) {
14270             }
14271             return;
14272         }
14273
14274         final long ident = Binder.clearCallingIdentity();
14275         try {
14276             if (TextUtils.equals(pae.intent.getAction(),
14277                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
14278                 pae.intent.putExtras(pae.extras);
14279                 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
14280             } else {
14281                 pae.intent.replaceExtras(pae.extras);
14282                 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
14283                         | Intent.FLAG_ACTIVITY_SINGLE_TOP
14284                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
14285                 closeSystemDialogs("assist");
14286
14287                 try {
14288                     mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
14289                 } catch (ActivityNotFoundException e) {
14290                     Slog.w(TAG, "No activity to handle assist action.", e);
14291                 }
14292             }
14293         } finally {
14294             Binder.restoreCallingIdentity(ident);
14295         }
14296     }
14297
14298     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
14299             Bundle args) {
14300         return enqueueAssistContext(requestType, intent, hint, null, null, null,
14301                 true /* focused */, true /* newSessionId */, userHandle, args,
14302                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
14303     }
14304
14305     public void registerProcessObserver(IProcessObserver observer) {
14306         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
14307                 "registerProcessObserver()");
14308         synchronized (this) {
14309             mProcessObservers.register(observer);
14310         }
14311     }
14312
14313     @Override
14314     public void unregisterProcessObserver(IProcessObserver observer) {
14315         synchronized (this) {
14316             mProcessObservers.unregister(observer);
14317         }
14318     }
14319
14320     @Override
14321     public int getUidProcessState(int uid, String callingPackage) {
14322         if (!hasUsageStatsPermission(callingPackage)) {
14323             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14324                     "getUidProcessState");
14325         }
14326
14327         synchronized (this) {
14328             UidRecord uidRec = mActiveUids.get(uid);
14329             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
14330         }
14331     }
14332
14333     @Override
14334     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
14335             String callingPackage) {
14336         if (!hasUsageStatsPermission(callingPackage)) {
14337             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14338                     "registerUidObserver");
14339         }
14340         synchronized (this) {
14341             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
14342                     callingPackage, which, cutpoint));
14343         }
14344     }
14345
14346     @Override
14347     public void unregisterUidObserver(IUidObserver observer) {
14348         synchronized (this) {
14349             mUidObservers.unregister(observer);
14350         }
14351     }
14352
14353     @Override
14354     public boolean isUidActive(int uid, String callingPackage) {
14355         if (!hasUsageStatsPermission(callingPackage)) {
14356             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14357                     "isUidActive");
14358         }
14359         synchronized (this) {
14360             return isUidActiveLocked(uid);
14361         }
14362     }
14363
14364     boolean isUidActiveLocked(int uid) {
14365         final UidRecord uidRecord = mActiveUids.get(uid);
14366         return uidRecord != null && !uidRecord.setIdle;
14367     }
14368
14369     @Override
14370     public boolean convertFromTranslucent(IBinder token) {
14371         final long origId = Binder.clearCallingIdentity();
14372         try {
14373             synchronized (this) {
14374                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14375                 if (r == null) {
14376                     return false;
14377                 }
14378                 final boolean translucentChanged = r.changeWindowTranslucency(true);
14379                 if (translucentChanged) {
14380                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14381                 }
14382                 mWindowManager.setAppFullscreen(token, true);
14383                 return translucentChanged;
14384             }
14385         } finally {
14386             Binder.restoreCallingIdentity(origId);
14387         }
14388     }
14389
14390     @Override
14391     public boolean convertToTranslucent(IBinder token, Bundle options) {
14392         SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
14393         final long origId = Binder.clearCallingIdentity();
14394         try {
14395             synchronized (this) {
14396                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14397                 if (r == null) {
14398                     return false;
14399                 }
14400                 final TaskRecord task = r.getTask();
14401                 int index = task.mActivities.lastIndexOf(r);
14402                 if (index > 0) {
14403                     ActivityRecord under = task.mActivities.get(index - 1);
14404                     under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
14405                 }
14406                 final boolean translucentChanged = r.changeWindowTranslucency(false);
14407                 if (translucentChanged) {
14408                     r.getStack().convertActivityToTranslucent(r);
14409                 }
14410                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14411                 mWindowManager.setAppFullscreen(token, false);
14412                 return translucentChanged;
14413             }
14414         } finally {
14415             Binder.restoreCallingIdentity(origId);
14416         }
14417     }
14418
14419     @Override
14420     public Bundle getActivityOptions(IBinder token) {
14421         final long origId = Binder.clearCallingIdentity();
14422         try {
14423             synchronized (this) {
14424                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14425                 if (r != null) {
14426                     final ActivityOptions activityOptions = r.takeOptionsLocked();
14427                     return activityOptions == null ? null : activityOptions.toBundle();
14428                 }
14429                 return null;
14430             }
14431         } finally {
14432             Binder.restoreCallingIdentity(origId);
14433         }
14434     }
14435
14436     @Override
14437     public void setImmersive(IBinder token, boolean immersive) {
14438         synchronized(this) {
14439             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14440             if (r == null) {
14441                 throw new IllegalArgumentException();
14442             }
14443             r.immersive = immersive;
14444
14445             // update associated state if we're frontmost
14446             if (r == mStackSupervisor.getResumedActivityLocked()) {
14447                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
14448                 applyUpdateLockStateLocked(r);
14449             }
14450         }
14451     }
14452
14453     @Override
14454     public boolean isImmersive(IBinder token) {
14455         synchronized (this) {
14456             ActivityRecord r = ActivityRecord.isInStackLocked(token);
14457             if (r == null) {
14458                 throw new IllegalArgumentException();
14459             }
14460             return r.immersive;
14461         }
14462     }
14463
14464     @Override
14465     public void setVrThread(int tid) {
14466         enforceSystemHasVrFeature();
14467         synchronized (this) {
14468             synchronized (mPidsSelfLocked) {
14469                 final int pid = Binder.getCallingPid();
14470                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
14471                 mVrController.setVrThreadLocked(tid, pid, proc);
14472             }
14473         }
14474     }
14475
14476     @Override
14477     public void setPersistentVrThread(int tid) {
14478         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
14479             final String msg = "Permission Denial: setPersistentVrThread() from pid="
14480                     + Binder.getCallingPid()
14481                     + ", uid=" + Binder.getCallingUid()
14482                     + " requires " + permission.RESTRICTED_VR_ACCESS;
14483             Slog.w(TAG, msg);
14484             throw new SecurityException(msg);
14485         }
14486         enforceSystemHasVrFeature();
14487         synchronized (this) {
14488             synchronized (mPidsSelfLocked) {
14489                 final int pid = Binder.getCallingPid();
14490                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
14491                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
14492             }
14493         }
14494     }
14495
14496     /**
14497      * Schedule the given thread a normal scheduling priority.
14498      *
14499      * @param tid the tid of the thread to adjust the scheduling of.
14500      * @param suppressLogs {@code true} if any error logging should be disabled.
14501      *
14502      * @return {@code true} if this succeeded.
14503      */
14504     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
14505         try {
14506             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
14507             return true;
14508         } catch (IllegalArgumentException e) {
14509             if (!suppressLogs) {
14510                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14511             }
14512         } catch (SecurityException e) {
14513             if (!suppressLogs) {
14514                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14515             }
14516         }
14517         return false;
14518     }
14519
14520     /**
14521      * Schedule the given thread an FIFO scheduling priority.
14522      *
14523      * @param tid the tid of the thread to adjust the scheduling of.
14524      * @param suppressLogs {@code true} if any error logging should be disabled.
14525      *
14526      * @return {@code true} if this succeeded.
14527      */
14528     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
14529         try {
14530             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
14531             return true;
14532         } catch (IllegalArgumentException e) {
14533             if (!suppressLogs) {
14534                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14535             }
14536         } catch (SecurityException e) {
14537             if (!suppressLogs) {
14538                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14539             }
14540         }
14541         return false;
14542     }
14543
14544     /**
14545      * Check that we have the features required for VR-related API calls, and throw an exception if
14546      * not.
14547      */
14548     private void enforceSystemHasVrFeature() {
14549         if (!mContext.getPackageManager().hasSystemFeature(
14550                 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
14551             throw new UnsupportedOperationException("VR mode not supported on this device!");
14552         }
14553     }
14554
14555     @Override
14556     public void setRenderThread(int tid) {
14557         synchronized (this) {
14558             ProcessRecord proc;
14559             int pid = Binder.getCallingPid();
14560             if (pid == Process.myPid()) {
14561                 demoteSystemServerRenderThread(tid);
14562                 return;
14563             }
14564             synchronized (mPidsSelfLocked) {
14565                 proc = mPidsSelfLocked.get(pid);
14566                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
14567                     // ensure the tid belongs to the process
14568                     if (!isThreadInProcess(pid, tid)) {
14569                         throw new IllegalArgumentException(
14570                             "Render thread does not belong to process");
14571                     }
14572                     proc.renderThreadTid = tid;
14573                     if (DEBUG_OOM_ADJ) {
14574                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
14575                     }
14576                     // promote to FIFO now
14577                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
14578                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
14579                         if (mUseFifoUiScheduling) {
14580                             setThreadScheduler(proc.renderThreadTid,
14581                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
14582                         } else {
14583                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
14584                         }
14585                     }
14586                 } else {
14587                     if (DEBUG_OOM_ADJ) {
14588                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
14589                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
14590                                mUseFifoUiScheduling);
14591                     }
14592                 }
14593             }
14594         }
14595     }
14596
14597     /**
14598      * We only use RenderThread in system_server to store task snapshots to the disk, which should
14599      * happen in the background. Thus, demote render thread from system_server to a lower priority.
14600      *
14601      * @param tid the tid of the RenderThread
14602      */
14603     private void demoteSystemServerRenderThread(int tid) {
14604         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
14605     }
14606
14607     @Override
14608     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
14609         enforceSystemHasVrFeature();
14610
14611         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14612
14613         ActivityRecord r;
14614         synchronized (this) {
14615             r = ActivityRecord.isInStackLocked(token);
14616         }
14617
14618         if (r == null) {
14619             throw new IllegalArgumentException();
14620         }
14621
14622         int err;
14623         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
14624                 VrManagerInternal.NO_ERROR) {
14625             return err;
14626         }
14627
14628         // Clear the binder calling uid since this path may call moveToTask().
14629         final long callingId = Binder.clearCallingIdentity();
14630         try {
14631             synchronized(this) {
14632                 r.requestedVrComponent = (enabled) ? packageName : null;
14633
14634                 // Update associated state if this activity is currently focused
14635                 if (r == mStackSupervisor.getResumedActivityLocked()) {
14636                     applyUpdateVrModeLocked(r);
14637                 }
14638                 return 0;
14639             }
14640         } finally {
14641             Binder.restoreCallingIdentity(callingId);
14642         }
14643     }
14644
14645     @Override
14646     public boolean isVrModePackageEnabled(ComponentName packageName) {
14647         enforceSystemHasVrFeature();
14648
14649         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14650
14651         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
14652                 VrManagerInternal.NO_ERROR;
14653     }
14654
14655     public boolean isTopActivityImmersive() {
14656         enforceNotIsolatedCaller("startActivity");
14657         synchronized (this) {
14658             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
14659             return (r != null) ? r.immersive : false;
14660         }
14661     }
14662
14663     /**
14664      * @return whether the system should disable UI modes incompatible with VR mode.
14665      */
14666     boolean shouldDisableNonVrUiLocked() {
14667         return mVrController.shouldDisableNonVrUiLocked();
14668     }
14669
14670     @Override
14671     public boolean isTopOfTask(IBinder token) {
14672         synchronized (this) {
14673             ActivityRecord r = ActivityRecord.isInStackLocked(token);
14674             if (r == null) {
14675                 throw new IllegalArgumentException();
14676             }
14677             return r.getTask().getTopActivity() == r;
14678         }
14679     }
14680
14681     @Override
14682     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
14683         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
14684             String msg = "Permission Denial: setHasTopUi() from pid="
14685                     + Binder.getCallingPid()
14686                     + ", uid=" + Binder.getCallingUid()
14687                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
14688             Slog.w(TAG, msg);
14689             throw new SecurityException(msg);
14690         }
14691         final int pid = Binder.getCallingPid();
14692         final long origId = Binder.clearCallingIdentity();
14693         try {
14694             synchronized (this) {
14695                 boolean changed = false;
14696                 ProcessRecord pr;
14697                 synchronized (mPidsSelfLocked) {
14698                     pr = mPidsSelfLocked.get(pid);
14699                     if (pr == null) {
14700                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
14701                         return;
14702                     }
14703                     if (pr.hasTopUi != hasTopUi) {
14704                         if (DEBUG_OOM_ADJ) {
14705                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
14706                         }
14707                         pr.hasTopUi = hasTopUi;
14708                         changed = true;
14709                     }
14710                 }
14711                 if (changed) {
14712                     updateOomAdjLocked(pr, true);
14713                 }
14714             }
14715         } finally {
14716             Binder.restoreCallingIdentity(origId);
14717         }
14718     }
14719
14720     void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
14721         if (pid == Process.myPid()) {
14722             Slog.wtf(TAG, "system can't run remote animation");
14723             return;
14724         }
14725         synchronized (ActivityManagerService.this) {
14726             final ProcessRecord pr;
14727             synchronized (mPidsSelfLocked) {
14728                 pr = mPidsSelfLocked.get(pid);
14729                 if (pr == null) {
14730                     Slog.w(TAG, "setRunningRemoteAnimation called on unknown pid: " + pid);
14731                     return;
14732                 }
14733             }
14734             if (pr.runningRemoteAnimation == runningRemoteAnimation) {
14735                 return;
14736             }
14737             pr.runningRemoteAnimation = runningRemoteAnimation;
14738             if (DEBUG_OOM_ADJ) {
14739                 Slog.i(TAG, "Setting runningRemoteAnimation=" + pr.runningRemoteAnimation
14740                         + " for pid=" + pid);
14741             }
14742             updateOomAdjLocked(pr, true);
14743         }
14744     }
14745
14746     public final void enterSafeMode() {
14747         synchronized(this) {
14748             // It only makes sense to do this before the system is ready
14749             // and started launching other packages.
14750             if (!mSystemReady) {
14751                 try {
14752                     AppGlobals.getPackageManager().enterSafeMode();
14753                 } catch (RemoteException e) {
14754                 }
14755             }
14756
14757             mSafeMode = true;
14758         }
14759     }
14760
14761     public final void showSafeModeOverlay() {
14762         View v = LayoutInflater.from(mContext).inflate(
14763                 com.android.internal.R.layout.safe_mode, null);
14764         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
14765         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
14766         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
14767         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
14768         lp.gravity = Gravity.BOTTOM | Gravity.START;
14769         lp.format = v.getBackground().getOpacity();
14770         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
14771                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
14772         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
14773         ((WindowManager)mContext.getSystemService(
14774                 Context.WINDOW_SERVICE)).addView(v, lp);
14775     }
14776
14777     @Override
14778     public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
14779             String sourcePkg, String tag) {
14780         if (workSource != null && workSource.isEmpty()) {
14781             workSource = null;
14782         }
14783
14784         if (sourceUid <= 0 && workSource == null) {
14785             // Try and derive a UID to attribute things to based on the caller.
14786             if (sender != null) {
14787                 if (!(sender instanceof PendingIntentRecord)) {
14788                     return;
14789                 }
14790
14791                 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14792                 final int callerUid = Binder.getCallingUid();
14793                 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14794             } else {
14795                 // TODO(narayan): Should we throw an exception in this case ? It means that we
14796                 // haven't been able to derive a UID to attribute things to.
14797                 return;
14798             }
14799         }
14800
14801         if (DEBUG_POWER) {
14802             Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
14803                     + ", workSource=" + workSource + ", tag=" + tag + "]");
14804         }
14805
14806         mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
14807     }
14808
14809     @Override
14810     public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14811             String tag) {
14812         if (workSource != null && workSource.isEmpty()) {
14813             workSource = null;
14814         }
14815
14816         if (sourceUid <= 0 && workSource == null) {
14817             // Try and derive a UID to attribute things to based on the caller.
14818             if (sender != null) {
14819                 if (!(sender instanceof PendingIntentRecord)) {
14820                     return;
14821                 }
14822
14823                 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14824                 final int callerUid = Binder.getCallingUid();
14825                 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14826             } else {
14827                 // TODO(narayan): Should we throw an exception in this case ? It means that we
14828                 // haven't been able to derive a UID to attribute things to.
14829                 return;
14830             }
14831         }
14832
14833         if (DEBUG_POWER) {
14834             Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14835                     ", tag=" + tag + "]");
14836         }
14837
14838         mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14839     }
14840
14841     @Override
14842     public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14843             String tag) {
14844         if (workSource != null && workSource.isEmpty()) {
14845             workSource = null;
14846         }
14847
14848         if (sourceUid <= 0 && workSource == null) {
14849             // Try and derive a UID to attribute things to based on the caller.
14850             if (sender != null) {
14851                 if (!(sender instanceof PendingIntentRecord)) {
14852                     return;
14853                 }
14854
14855                 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14856                 final int callerUid = Binder.getCallingUid();
14857                 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14858             } else {
14859                 // TODO(narayan): Should we throw an exception in this case ? It means that we
14860                 // haven't been able to derive a UID to attribute things to.
14861                 return;
14862             }
14863         }
14864
14865         if (DEBUG_POWER) {
14866             Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14867                     ", tag=" + tag + "]");
14868         }
14869
14870         mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
14871     }
14872
14873     public boolean killPids(int[] pids, String pReason, boolean secure) {
14874         if (Binder.getCallingUid() != SYSTEM_UID) {
14875             throw new SecurityException("killPids only available to the system");
14876         }
14877         String reason = (pReason == null) ? "Unknown" : pReason;
14878         // XXX Note: don't acquire main activity lock here, because the window
14879         // manager calls in with its locks held.
14880
14881         boolean killed = false;
14882         synchronized (mPidsSelfLocked) {
14883             int worstType = 0;
14884             for (int i=0; i<pids.length; i++) {
14885                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14886                 if (proc != null) {
14887                     int type = proc.setAdj;
14888                     if (type > worstType) {
14889                         worstType = type;
14890                     }
14891                 }
14892             }
14893
14894             // If the worst oom_adj is somewhere in the cached proc LRU range,
14895             // then constrain it so we will kill all cached procs.
14896             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14897                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14898                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
14899             }
14900
14901             // If this is not a secure call, don't let it kill processes that
14902             // are important.
14903             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14904                 worstType = ProcessList.SERVICE_ADJ;
14905             }
14906
14907             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14908             for (int i=0; i<pids.length; i++) {
14909                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14910                 if (proc == null) {
14911                     continue;
14912                 }
14913                 int adj = proc.setAdj;
14914                 if (adj >= worstType && !proc.killedByAm) {
14915                     proc.kill(reason, true);
14916                     killed = true;
14917                 }
14918             }
14919         }
14920         return killed;
14921     }
14922
14923     @Override
14924     public void killUid(int appId, int userId, String reason) {
14925         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14926         synchronized (this) {
14927             final long identity = Binder.clearCallingIdentity();
14928             try {
14929                 killPackageProcessesLocked(null, appId, userId,
14930                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14931                         reason != null ? reason : "kill uid");
14932             } finally {
14933                 Binder.restoreCallingIdentity(identity);
14934             }
14935         }
14936     }
14937
14938     @Override
14939     public boolean killProcessesBelowForeground(String reason) {
14940         if (Binder.getCallingUid() != SYSTEM_UID) {
14941             throw new SecurityException("killProcessesBelowForeground() only available to system");
14942         }
14943
14944         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14945     }
14946
14947     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14948         if (Binder.getCallingUid() != SYSTEM_UID) {
14949             throw new SecurityException("killProcessesBelowAdj() only available to system");
14950         }
14951
14952         boolean killed = false;
14953         synchronized (mPidsSelfLocked) {
14954             final int size = mPidsSelfLocked.size();
14955             for (int i = 0; i < size; i++) {
14956                 final int pid = mPidsSelfLocked.keyAt(i);
14957                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14958                 if (proc == null) continue;
14959
14960                 final int adj = proc.setAdj;
14961                 if (adj > belowAdj && !proc.killedByAm) {
14962                     proc.kill(reason, true);
14963                     killed = true;
14964                 }
14965             }
14966         }
14967         return killed;
14968     }
14969
14970     @Override
14971     public void hang(final IBinder who, boolean allowRestart) {
14972         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14973                 != PackageManager.PERMISSION_GRANTED) {
14974             throw new SecurityException("Requires permission "
14975                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14976         }
14977
14978         final IBinder.DeathRecipient death = new DeathRecipient() {
14979             @Override
14980             public void binderDied() {
14981                 synchronized (this) {
14982                     notifyAll();
14983                 }
14984             }
14985         };
14986
14987         try {
14988             who.linkToDeath(death, 0);
14989         } catch (RemoteException e) {
14990             Slog.w(TAG, "hang: given caller IBinder is already dead.");
14991             return;
14992         }
14993
14994         synchronized (this) {
14995             Watchdog.getInstance().setAllowRestart(allowRestart);
14996             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14997             synchronized (death) {
14998                 while (who.isBinderAlive()) {
14999                     try {
15000                         death.wait();
15001                     } catch (InterruptedException e) {
15002                     }
15003                 }
15004             }
15005             Watchdog.getInstance().setAllowRestart(true);
15006         }
15007     }
15008
15009     @Override
15010     public void restart() {
15011         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15012                 != PackageManager.PERMISSION_GRANTED) {
15013             throw new SecurityException("Requires permission "
15014                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15015         }
15016
15017         Log.i(TAG, "Sending shutdown broadcast...");
15018
15019         BroadcastReceiver br = new BroadcastReceiver() {
15020             @Override public void onReceive(Context context, Intent intent) {
15021                 // Now the broadcast is done, finish up the low-level shutdown.
15022                 Log.i(TAG, "Shutting down activity manager...");
15023                 shutdown(10000);
15024                 Log.i(TAG, "Shutdown complete, restarting!");
15025                 killProcess(myPid());
15026                 System.exit(10);
15027             }
15028         };
15029
15030         // First send the high-level shut down broadcast.
15031         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
15032         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15033         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
15034         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
15035         mContext.sendOrderedBroadcastAsUser(intent,
15036                 UserHandle.ALL, null, br, mHandler, 0, null, null);
15037         */
15038         br.onReceive(mContext, intent);
15039     }
15040
15041     private long getLowRamTimeSinceIdle(long now) {
15042         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
15043     }
15044
15045     @Override
15046     public void performIdleMaintenance() {
15047         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15048                 != PackageManager.PERMISSION_GRANTED) {
15049             throw new SecurityException("Requires permission "
15050                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15051         }
15052
15053         synchronized (this) {
15054             final long now = SystemClock.uptimeMillis();
15055             final long timeSinceLastIdle = now - mLastIdleTime;
15056             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
15057             mLastIdleTime = now;
15058             mLowRamTimeSinceLastIdle = 0;
15059             if (mLowRamStartTime != 0) {
15060                 mLowRamStartTime = now;
15061             }
15062
15063             StringBuilder sb = new StringBuilder(128);
15064             sb.append("Idle maintenance over ");
15065             TimeUtils.formatDuration(timeSinceLastIdle, sb);
15066             sb.append(" low RAM for ");
15067             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
15068             Slog.i(TAG, sb.toString());
15069
15070             // If at least 1/3 of our time since the last idle period has been spent
15071             // with RAM low, then we want to kill processes.
15072             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
15073
15074             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15075                 ProcessRecord proc = mLruProcesses.get(i);
15076                 if (proc.notCachedSinceIdle) {
15077                     if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
15078                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
15079                         if (doKilling && proc.initialIdlePss != 0
15080                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
15081                             sb = new StringBuilder(128);
15082                             sb.append("Kill");
15083                             sb.append(proc.processName);
15084                             sb.append(" in idle maint: pss=");
15085                             sb.append(proc.lastPss);
15086                             sb.append(", swapPss=");
15087                             sb.append(proc.lastSwapPss);
15088                             sb.append(", initialPss=");
15089                             sb.append(proc.initialIdlePss);
15090                             sb.append(", period=");
15091                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
15092                             sb.append(", lowRamPeriod=");
15093                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
15094                             Slog.wtfQuiet(TAG, sb.toString());
15095                             proc.kill("idle maint (pss " + proc.lastPss
15096                                     + " from " + proc.initialIdlePss + ")", true);
15097                         }
15098                     }
15099                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
15100                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
15101                     proc.notCachedSinceIdle = true;
15102                     proc.initialIdlePss = 0;
15103                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
15104                             mTestPssMode, isSleepingLocked(), now);
15105                 }
15106             }
15107         }
15108     }
15109
15110     @Override
15111     public void sendIdleJobTrigger() {
15112         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15113                 != PackageManager.PERMISSION_GRANTED) {
15114             throw new SecurityException("Requires permission "
15115                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15116         }
15117
15118         final long ident = Binder.clearCallingIdentity();
15119         try {
15120             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
15121                     .setPackage("android")
15122                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15123             broadcastIntent(null, intent, null, null, 0, null, null, null,
15124                     OP_NONE, null, false, false, UserHandle.USER_ALL);
15125         } finally {
15126             Binder.restoreCallingIdentity(ident);
15127         }
15128     }
15129
15130     private void retrieveSettings() {
15131         final ContentResolver resolver = mContext.getContentResolver();
15132         final boolean freeformWindowManagement =
15133                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
15134                         || Settings.Global.getInt(
15135                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
15136
15137         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
15138         final boolean supportsPictureInPicture = supportsMultiWindow &&
15139                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
15140         final boolean supportsSplitScreenMultiWindow =
15141                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
15142         final boolean supportsMultiDisplay = mContext.getPackageManager()
15143                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
15144         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
15145         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
15146         final boolean alwaysFinishActivities =
15147                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
15148         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
15149         final boolean forceResizable = Settings.Global.getInt(
15150                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
15151         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
15152                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
15153         final boolean supportsLeanbackOnly =
15154                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
15155         mHiddenApiBlacklist.registerObserver();
15156
15157         // Transfer any global setting for forcing RTL layout, into a System Property
15158         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
15159
15160         final Configuration configuration = new Configuration();
15161         Settings.System.getConfiguration(resolver, configuration);
15162         if (forceRtl) {
15163             // This will take care of setting the correct layout direction flags
15164             configuration.setLayoutDirection(configuration.locale);
15165         }
15166
15167         synchronized (this) {
15168             mDebugApp = mOrigDebugApp = debugApp;
15169             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
15170             mAlwaysFinishActivities = alwaysFinishActivities;
15171             mSupportsLeanbackOnly = supportsLeanbackOnly;
15172             mForceResizableActivities = forceResizable;
15173             final boolean multiWindowFormEnabled = freeformWindowManagement
15174                     || supportsSplitScreenMultiWindow
15175                     || supportsPictureInPicture
15176                     || supportsMultiDisplay;
15177             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
15178                 mSupportsMultiWindow = true;
15179                 mSupportsFreeformWindowManagement = freeformWindowManagement;
15180                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
15181                 mSupportsPictureInPicture = supportsPictureInPicture;
15182                 mSupportsMultiDisplay = supportsMultiDisplay;
15183             } else {
15184                 mSupportsMultiWindow = false;
15185                 mSupportsFreeformWindowManagement = false;
15186                 mSupportsSplitScreenMultiWindow = false;
15187                 mSupportsPictureInPicture = false;
15188                 mSupportsMultiDisplay = false;
15189             }
15190             mWindowManager.setForceResizableTasks(mForceResizableActivities);
15191             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
15192             // This happens before any activities are started, so we can change global configuration
15193             // in-place.
15194             updateConfigurationLocked(configuration, null, true);
15195             final Configuration globalConfig = getGlobalConfiguration();
15196             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
15197
15198             // Load resources only after the current configuration has been set.
15199             final Resources res = mContext.getResources();
15200             mThumbnailWidth = res.getDimensionPixelSize(
15201                     com.android.internal.R.dimen.thumbnail_width);
15202             mThumbnailHeight = res.getDimensionPixelSize(
15203                     com.android.internal.R.dimen.thumbnail_height);
15204             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
15205                     com.android.internal.R.string.config_appsNotReportingCrashes));
15206             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
15207                     com.android.internal.R.bool.config_customUserSwitchUi);
15208             mUserController.mMaxRunningUsers = res.getInteger(
15209                     com.android.internal.R.integer.config_multiuserMaxRunningUsers);
15210
15211             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
15212                 mFullscreenThumbnailScale = (float) res
15213                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
15214                     (float) globalConfig.screenWidthDp;
15215             } else {
15216                 mFullscreenThumbnailScale = res.getFraction(
15217                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
15218             }
15219             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
15220         }
15221     }
15222
15223     public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
15224         traceLog.traceBegin("PhaseActivityManagerReady");
15225         synchronized(this) {
15226             if (mSystemReady) {
15227                 // If we're done calling all the receivers, run the next "boot phase" passed in
15228                 // by the SystemServer
15229                 if (goingCallback != null) {
15230                     goingCallback.run();
15231                 }
15232                 return;
15233             }
15234
15235             mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
15236                     PackageManager.FEATURE_CANT_SAVE_STATE);
15237             mLocalDeviceIdleController
15238                     = LocalServices.getService(DeviceIdleController.LocalService.class);
15239             mAssistUtils = new AssistUtils(mContext);
15240             mVrController.onSystemReady();
15241             // Make sure we have the current profile info, since it is needed for security checks.
15242             mUserController.onSystemReady();
15243             mRecentTasks.onSystemReadyLocked();
15244             mAppOpsService.systemReady();
15245             mSystemReady = true;
15246         }
15247
15248         try {
15249             sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
15250                     ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
15251                     .getSerial();
15252         } catch (RemoteException e) {}
15253
15254         ArrayList<ProcessRecord> procsToKill = null;
15255         synchronized(mPidsSelfLocked) {
15256             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
15257                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
15258                 if (!isAllowedWhileBooting(proc.info)){
15259                     if (procsToKill == null) {
15260                         procsToKill = new ArrayList<ProcessRecord>();
15261                     }
15262                     procsToKill.add(proc);
15263                 }
15264             }
15265         }
15266
15267         synchronized(this) {
15268             if (procsToKill != null) {
15269                 for (int i=procsToKill.size()-1; i>=0; i--) {
15270                     ProcessRecord proc = procsToKill.get(i);
15271                     Slog.i(TAG, "Removing system update proc: " + proc);
15272                     removeProcessLocked(proc, true, false, "system update done");
15273                 }
15274             }
15275
15276             // Now that we have cleaned up any update processes, we
15277             // are ready to start launching real processes and know that
15278             // we won't trample on them any more.
15279             mProcessesReady = true;
15280         }
15281
15282         Slog.i(TAG, "System now ready");
15283         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
15284             SystemClock.uptimeMillis());
15285
15286         synchronized(this) {
15287             // Make sure we have no pre-ready processes sitting around.
15288
15289             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
15290                 ResolveInfo ri = mContext.getPackageManager()
15291                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
15292                                 STOCK_PM_FLAGS);
15293                 CharSequence errorMsg = null;
15294                 if (ri != null) {
15295                     ActivityInfo ai = ri.activityInfo;
15296                     ApplicationInfo app = ai.applicationInfo;
15297                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
15298                         mTopAction = Intent.ACTION_FACTORY_TEST;
15299                         mTopData = null;
15300                         mTopComponent = new ComponentName(app.packageName,
15301                                 ai.name);
15302                     } else {
15303                         errorMsg = mContext.getResources().getText(
15304                                 com.android.internal.R.string.factorytest_not_system);
15305                     }
15306                 } else {
15307                     errorMsg = mContext.getResources().getText(
15308                             com.android.internal.R.string.factorytest_no_action);
15309                 }
15310                 if (errorMsg != null) {
15311                     mTopAction = null;
15312                     mTopData = null;
15313                     mTopComponent = null;
15314                     Message msg = Message.obtain();
15315                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
15316                     msg.getData().putCharSequence("msg", errorMsg);
15317                     mUiHandler.sendMessage(msg);
15318                 }
15319             }
15320         }
15321
15322         retrieveSettings();
15323         final int currentUserId = mUserController.getCurrentUserId();
15324         synchronized (this) {
15325             readGrantedUriPermissionsLocked();
15326         }
15327
15328         final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
15329         if (pmi != null) {
15330             pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
15331                     state -> updateForceBackgroundCheck(state.batterySaverEnabled));
15332             updateForceBackgroundCheck(
15333                     pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
15334         } else {
15335             Slog.wtf(TAG, "PowerManagerInternal not found.");
15336         }
15337
15338         if (goingCallback != null) goingCallback.run();
15339         traceLog.traceBegin("ActivityManagerStartApps");
15340         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
15341                 Integer.toString(currentUserId), currentUserId);
15342         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
15343                 Integer.toString(currentUserId), currentUserId);
15344         mSystemServiceManager.startUser(currentUserId);
15345
15346         synchronized (this) {
15347             // Only start up encryption-aware persistent apps; once user is
15348             // unlocked we'll come back around and start unaware apps
15349             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
15350
15351             // Start up initial activity.
15352             mBooting = true;
15353             // Enable home activity for system user, so that the system can always boot. We don't
15354             // do this when the system user is not setup since the setup wizard should be the one
15355             // to handle home activity in this case.
15356             if (UserManager.isSplitSystemUser() &&
15357                     Settings.Secure.getInt(mContext.getContentResolver(),
15358                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
15359                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
15360                 try {
15361                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
15362                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
15363                             UserHandle.USER_SYSTEM);
15364                 } catch (RemoteException e) {
15365                     throw e.rethrowAsRuntimeException();
15366                 }
15367             }
15368             startHomeActivityLocked(currentUserId, "systemReady");
15369
15370             try {
15371                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
15372                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
15373                             + " data partition or your device will be unstable.");
15374                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
15375                 }
15376             } catch (RemoteException e) {
15377             }
15378
15379             if (!Build.isBuildConsistent()) {
15380                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
15381                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
15382             }
15383
15384             long ident = Binder.clearCallingIdentity();
15385             try {
15386                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
15387                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15388                         | Intent.FLAG_RECEIVER_FOREGROUND);
15389                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15390                 broadcastIntentLocked(null, null, intent,
15391                         null, null, 0, null, null, null, OP_NONE,
15392                         null, false, false, MY_PID, SYSTEM_UID,
15393                         currentUserId);
15394                 intent = new Intent(Intent.ACTION_USER_STARTING);
15395                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15396                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15397                 broadcastIntentLocked(null, null, intent,
15398                         null, new IIntentReceiver.Stub() {
15399                             @Override
15400                             public void performReceive(Intent intent, int resultCode, String data,
15401                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
15402                                     throws RemoteException {
15403                             }
15404                         }, 0, null, null,
15405                         new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
15406                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
15407             } catch (Throwable t) {
15408                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
15409             } finally {
15410                 Binder.restoreCallingIdentity(ident);
15411             }
15412             mStackSupervisor.resumeFocusedStackTopActivityLocked();
15413             mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
15414
15415             BinderInternal.nSetBinderProxyCountWatermarks(6000,5500);
15416             BinderInternal.nSetBinderProxyCountEnabled(true);
15417             BinderInternal.setBinderProxyCountCallback(
15418                     new BinderInternal.BinderProxyLimitListener() {
15419                         @Override
15420                         public void onLimitReached(int uid) {
15421                             Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
15422                                     + Process.myUid());
15423                             if (uid == Process.SYSTEM_UID) {
15424                                 Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
15425                             } else {
15426                                 killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
15427                                         "Too many Binders sent to SYSTEM");
15428                             }
15429                         }
15430                     }, mHandler);
15431
15432             traceLog.traceEnd(); // ActivityManagerStartApps
15433             traceLog.traceEnd(); // PhaseActivityManagerReady
15434         }
15435     }
15436
15437     private void updateForceBackgroundCheck(boolean enabled) {
15438         synchronized (this) {
15439             if (mForceBackgroundCheck != enabled) {
15440                 mForceBackgroundCheck = enabled;
15441
15442                 if (DEBUG_BACKGROUND_CHECK) {
15443                     Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
15444                 }
15445
15446                 if (mForceBackgroundCheck) {
15447                     // Stop background services for idle UIDs.
15448                     doStopUidForIdleUidsLocked();
15449                 }
15450             }
15451         }
15452     }
15453
15454     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
15455         synchronized (this) {
15456             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
15457         }
15458     }
15459
15460     void skipCurrentReceiverLocked(ProcessRecord app) {
15461         for (BroadcastQueue queue : mBroadcastQueues) {
15462             queue.skipCurrentReceiverLocked(app);
15463         }
15464     }
15465
15466     /**
15467      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
15468      * The application process will exit immediately after this call returns.
15469      * @param app object of the crashing app, null for the system server
15470      * @param crashInfo describing the exception
15471      */
15472     public void handleApplicationCrash(IBinder app,
15473             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15474         ProcessRecord r = findAppProcess(app, "Crash");
15475         final String processName = app == null ? "system_server"
15476                 : (r == null ? "unknown" : r.processName);
15477
15478         handleApplicationCrashInner("crash", r, processName, crashInfo);
15479     }
15480
15481     /* Native crash reporting uses this inner version because it needs to be somewhat
15482      * decoupled from the AM-managed cleanup lifecycle
15483      */
15484     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
15485             ApplicationErrorReport.CrashInfo crashInfo) {
15486         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
15487                 UserHandle.getUserId(Binder.getCallingUid()), processName,
15488                 r == null ? -1 : r.info.flags,
15489                 crashInfo.exceptionClassName,
15490                 crashInfo.exceptionMessage,
15491                 crashInfo.throwFileName,
15492                 crashInfo.throwLineNumber);
15493
15494         StatsLog.write(StatsLog.APP_CRASH_OCCURRED,
15495                 Binder.getCallingUid(),
15496                 eventType,
15497                 processName,
15498                 Binder.getCallingPid(),
15499                 (r != null && r.info != null) ? r.info.packageName : "",
15500                 (r != null && r.info != null) ? (r.info.isInstantApp()
15501                         ? StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__TRUE
15502                         : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__FALSE)
15503                         : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__UNAVAILABLE,
15504                 r != null ? (r.isInterestingToUserLocked()
15505                         ? StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__FOREGROUND
15506                         : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__BACKGROUND)
15507                         : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__UNKNOWN
15508         );
15509
15510         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
15511
15512         mAppErrors.crashApplication(r, crashInfo);
15513     }
15514
15515     public void handleApplicationStrictModeViolation(
15516             IBinder app,
15517             int violationMask,
15518             StrictMode.ViolationInfo info) {
15519         // We're okay if the ProcessRecord is missing; it probably means that
15520         // we're reporting a violation from the system process itself.
15521         final ProcessRecord r = findAppProcess(app, "StrictMode");
15522
15523         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
15524             Integer stackFingerprint = info.hashCode();
15525             boolean logIt = true;
15526             synchronized (mAlreadyLoggedViolatedStacks) {
15527                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
15528                     logIt = false;
15529                     // TODO: sub-sample into EventLog for these, with
15530                     // the info.durationMillis?  Then we'd get
15531                     // the relative pain numbers, without logging all
15532                     // the stack traces repeatedly.  We'd want to do
15533                     // likewise in the client code, which also does
15534                     // dup suppression, before the Binder call.
15535                 } else {
15536                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
15537                         mAlreadyLoggedViolatedStacks.clear();
15538                     }
15539                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
15540                 }
15541             }
15542             if (logIt) {
15543                 logStrictModeViolationToDropBox(r, info);
15544             }
15545         }
15546
15547         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
15548             AppErrorResult result = new AppErrorResult();
15549             synchronized (this) {
15550                 final long origId = Binder.clearCallingIdentity();
15551
15552                 Message msg = Message.obtain();
15553                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
15554                 HashMap<String, Object> data = new HashMap<String, Object>();
15555                 data.put("result", result);
15556                 data.put("app", r);
15557                 data.put("violationMask", violationMask);
15558                 data.put("info", info);
15559                 msg.obj = data;
15560                 mUiHandler.sendMessage(msg);
15561
15562                 Binder.restoreCallingIdentity(origId);
15563             }
15564             int res = result.get();
15565             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
15566         }
15567     }
15568
15569     // Depending on the policy in effect, there could be a bunch of
15570     // these in quick succession so we try to batch these together to
15571     // minimize disk writes, number of dropbox entries, and maximize
15572     // compression, by having more fewer, larger records.
15573     private void logStrictModeViolationToDropBox(
15574             ProcessRecord process,
15575             StrictMode.ViolationInfo info) {
15576         if (info == null) {
15577             return;
15578         }
15579         final boolean isSystemApp = process == null ||
15580                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
15581                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
15582         final String processName = process == null ? "unknown" : process.processName;
15583         final DropBoxManager dbox = (DropBoxManager)
15584                 mContext.getSystemService(Context.DROPBOX_SERVICE);
15585
15586         // Exit early if the dropbox isn't configured to accept this report type.
15587         final String dropboxTag = processClass(process) + "_strictmode";
15588         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15589
15590         final StringBuilder sb = new StringBuilder(1024);
15591         synchronized (sb) {
15592             appendDropBoxProcessHeaders(process, processName, sb);
15593             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15594             sb.append("System-App: ").append(isSystemApp).append("\n");
15595             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
15596             if (info.violationNumThisLoop != 0) {
15597                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
15598             }
15599             if (info.numAnimationsRunning != 0) {
15600                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
15601             }
15602             if (info.broadcastIntentAction != null) {
15603                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
15604             }
15605             if (info.durationMillis != -1) {
15606                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
15607             }
15608             if (info.numInstances != -1) {
15609                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
15610             }
15611             if (info.tags != null) {
15612                 for (String tag : info.tags) {
15613                     sb.append("Span-Tag: ").append(tag).append("\n");
15614                 }
15615             }
15616             sb.append("\n");
15617             sb.append(info.getStackTrace());
15618             sb.append("\n");
15619             if (info.getViolationDetails() != null) {
15620                 sb.append(info.getViolationDetails());
15621                 sb.append("\n");
15622             }
15623         }
15624
15625         final String res = sb.toString();
15626         IoThread.getHandler().post(() -> {
15627             dbox.addText(dropboxTag, res);
15628         });
15629     }
15630
15631     /**
15632      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
15633      * @param app object of the crashing app, null for the system server
15634      * @param tag reported by the caller
15635      * @param system whether this wtf is coming from the system
15636      * @param crashInfo describing the context of the error
15637      * @return true if the process should exit immediately (WTF is fatal)
15638      */
15639     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
15640             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15641         final int callingUid = Binder.getCallingUid();
15642         final int callingPid = Binder.getCallingPid();
15643
15644         if (system) {
15645             // If this is coming from the system, we could very well have low-level
15646             // system locks held, so we want to do this all asynchronously.  And we
15647             // never want this to become fatal, so there is that too.
15648             mHandler.post(new Runnable() {
15649                 @Override public void run() {
15650                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
15651                 }
15652             });
15653             return false;
15654         }
15655
15656         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
15657                 crashInfo);
15658
15659         final boolean isFatal = Build.IS_ENG || Settings.Global
15660                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
15661         final boolean isSystem = (r == null) || r.persistent;
15662
15663         if (isFatal && !isSystem) {
15664             mAppErrors.crashApplication(r, crashInfo);
15665             return true;
15666         } else {
15667             return false;
15668         }
15669     }
15670
15671     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
15672             final ApplicationErrorReport.CrashInfo crashInfo) {
15673         final ProcessRecord r = findAppProcess(app, "WTF");
15674         final String processName = app == null ? "system_server"
15675                 : (r == null ? "unknown" : r.processName);
15676
15677         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
15678                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
15679
15680         StatsLog.write(StatsLog.WTF_OCCURRED, callingUid, tag, processName,
15681                 callingPid);
15682
15683         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
15684
15685         return r;
15686     }
15687
15688     /**
15689      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
15690      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
15691      */
15692     private ProcessRecord findAppProcess(IBinder app, String reason) {
15693         if (app == null) {
15694             return null;
15695         }
15696
15697         synchronized (this) {
15698             final int NP = mProcessNames.getMap().size();
15699             for (int ip=0; ip<NP; ip++) {
15700                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
15701                 final int NA = apps.size();
15702                 for (int ia=0; ia<NA; ia++) {
15703                     ProcessRecord p = apps.valueAt(ia);
15704                     if (p.thread != null && p.thread.asBinder() == app) {
15705                         return p;
15706                     }
15707                 }
15708             }
15709
15710             Slog.w(TAG, "Can't find mystery application for " + reason
15711                     + " from pid=" + Binder.getCallingPid()
15712                     + " uid=" + Binder.getCallingUid() + ": " + app);
15713             return null;
15714         }
15715     }
15716
15717     /**
15718      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
15719      * to append various headers to the dropbox log text.
15720      */
15721     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
15722             StringBuilder sb) {
15723         // Watchdog thread ends up invoking this function (with
15724         // a null ProcessRecord) to add the stack file to dropbox.
15725         // Do not acquire a lock on this (am) in such cases, as it
15726         // could cause a potential deadlock, if and when watchdog
15727         // is invoked due to unavailability of lock on am and it
15728         // would prevent watchdog from killing system_server.
15729         if (process == null) {
15730             sb.append("Process: ").append(processName).append("\n");
15731             return;
15732         }
15733         // Note: ProcessRecord 'process' is guarded by the service
15734         // instance.  (notably process.pkgList, which could otherwise change
15735         // concurrently during execution of this method)
15736         synchronized (this) {
15737             sb.append("Process: ").append(processName).append("\n");
15738             sb.append("PID: ").append(process.pid).append("\n");
15739             int flags = process.info.flags;
15740             IPackageManager pm = AppGlobals.getPackageManager();
15741             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
15742             for (int ip=0; ip<process.pkgList.size(); ip++) {
15743                 String pkg = process.pkgList.keyAt(ip);
15744                 sb.append("Package: ").append(pkg);
15745                 try {
15746                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
15747                     if (pi != null) {
15748                         sb.append(" v").append(pi.getLongVersionCode());
15749                         if (pi.versionName != null) {
15750                             sb.append(" (").append(pi.versionName).append(")");
15751                         }
15752                     }
15753                 } catch (RemoteException e) {
15754                     Slog.e(TAG, "Error getting package info: " + pkg, e);
15755                 }
15756                 sb.append("\n");
15757             }
15758             if (process.info.isInstantApp()) {
15759                 sb.append("Instant-App: true\n");
15760             }
15761         }
15762     }
15763
15764     private static String processClass(ProcessRecord process) {
15765         if (process == null || process.pid == MY_PID) {
15766             return "system_server";
15767         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15768             return "system_app";
15769         } else {
15770             return "data_app";
15771         }
15772     }
15773
15774     private volatile long mWtfClusterStart;
15775     private volatile int mWtfClusterCount;
15776
15777     /**
15778      * Write a description of an error (crash, WTF, ANR) to the drop box.
15779      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
15780      * @param process which caused the error, null means the system server
15781      * @param activity which triggered the error, null if unknown
15782      * @param parent activity related to the error, null if unknown
15783      * @param subject line related to the error, null if absent
15784      * @param report in long form describing the error, null if absent
15785      * @param dataFile text file to include in the report, null if none
15786      * @param crashInfo giving an application stack trace, null if absent
15787      */
15788     public void addErrorToDropBox(String eventType,
15789             ProcessRecord process, String processName, ActivityRecord activity,
15790             ActivityRecord parent, String subject,
15791             final String report, final File dataFile,
15792             final ApplicationErrorReport.CrashInfo crashInfo) {
15793         // NOTE -- this must never acquire the ActivityManagerService lock,
15794         // otherwise the watchdog may be prevented from resetting the system.
15795
15796         // Bail early if not published yet
15797         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
15798         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
15799
15800         // Exit early if the dropbox isn't configured to accept this report type.
15801         final String dropboxTag = processClass(process) + "_" + eventType;
15802         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15803
15804         // Rate-limit how often we're willing to do the heavy lifting below to
15805         // collect and record logs; currently 5 logs per 10 second period.
15806         final long now = SystemClock.elapsedRealtime();
15807         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
15808             mWtfClusterStart = now;
15809             mWtfClusterCount = 1;
15810         } else {
15811             if (mWtfClusterCount++ >= 5) return;
15812         }
15813
15814         final StringBuilder sb = new StringBuilder(1024);
15815         appendDropBoxProcessHeaders(process, processName, sb);
15816         if (process != null) {
15817             sb.append("Foreground: ")
15818                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
15819                     .append("\n");
15820         }
15821         if (activity != null) {
15822             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15823         }
15824         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15825             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15826         }
15827         if (parent != null && parent != activity) {
15828             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15829         }
15830         if (subject != null) {
15831             sb.append("Subject: ").append(subject).append("\n");
15832         }
15833         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15834         if (Debug.isDebuggerConnected()) {
15835             sb.append("Debugger: Connected\n");
15836         }
15837         sb.append("\n");
15838
15839         // Do the rest in a worker thread to avoid blocking the caller on I/O
15840         // (After this point, we shouldn't access AMS internal data structures.)
15841         Thread worker = new Thread("Error dump: " + dropboxTag) {
15842             @Override
15843             public void run() {
15844                 if (report != null) {
15845                     sb.append(report);
15846                 }
15847
15848                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
15849                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
15850                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
15851                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
15852
15853                 if (dataFile != null && maxDataFileSize > 0) {
15854                     try {
15855                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15856                                     "\n\n[[TRUNCATED]]"));
15857                     } catch (IOException e) {
15858                         Slog.e(TAG, "Error reading " + dataFile, e);
15859                     }
15860                 }
15861                 if (crashInfo != null && crashInfo.stackTrace != null) {
15862                     sb.append(crashInfo.stackTrace);
15863                 }
15864
15865                 if (lines > 0) {
15866                     sb.append("\n");
15867
15868                     // Merge several logcat streams, and take the last N lines
15869                     InputStreamReader input = null;
15870                     try {
15871                         java.lang.Process logcat = new ProcessBuilder(
15872                                 "/system/bin/timeout", "-k", "15s", "10s",
15873                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
15874                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
15875                                         .redirectErrorStream(true).start();
15876
15877                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
15878                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
15879                         input = new InputStreamReader(logcat.getInputStream());
15880
15881                         int num;
15882                         char[] buf = new char[8192];
15883                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
15884                     } catch (IOException e) {
15885                         Slog.e(TAG, "Error running logcat", e);
15886                     } finally {
15887                         if (input != null) try { input.close(); } catch (IOException e) {}
15888                     }
15889                 }
15890
15891                 dbox.addText(dropboxTag, sb.toString());
15892             }
15893         };
15894
15895         if (process == null) {
15896             // If process is null, we are being called from some internal code
15897             // and may be about to die -- run this synchronously.
15898             final int oldMask = StrictMode.allowThreadDiskWritesMask();
15899             try {
15900                 worker.run();
15901             } finally {
15902                 StrictMode.setThreadPolicyMask(oldMask);
15903             }
15904         } else {
15905             worker.start();
15906         }
15907     }
15908
15909     @Override
15910     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15911         enforceNotIsolatedCaller("getProcessesInErrorState");
15912         // assume our apps are happy - lazy create the list
15913         List<ActivityManager.ProcessErrorStateInfo> errList = null;
15914
15915         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15916                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15917         int userId = UserHandle.getUserId(Binder.getCallingUid());
15918
15919         synchronized (this) {
15920
15921             // iterate across all processes
15922             for (int i=mLruProcesses.size()-1; i>=0; i--) {
15923                 ProcessRecord app = mLruProcesses.get(i);
15924                 if (!allUsers && app.userId != userId) {
15925                     continue;
15926                 }
15927                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
15928                     // This one's in trouble, so we'll generate a report for it
15929                     // crashes are higher priority (in case there's a crash *and* an anr)
15930                     ActivityManager.ProcessErrorStateInfo report = null;
15931                     if (app.crashing) {
15932                         report = app.crashingReport;
15933                     } else if (app.notResponding) {
15934                         report = app.notRespondingReport;
15935                     }
15936
15937                     if (report != null) {
15938                         if (errList == null) {
15939                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15940                         }
15941                         errList.add(report);
15942                     } else {
15943                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
15944                                 " crashing = " + app.crashing +
15945                                 " notResponding = " + app.notResponding);
15946                     }
15947                 }
15948             }
15949         }
15950
15951         return errList;
15952     }
15953
15954     static int procStateToImportance(int procState, int memAdj,
15955             ActivityManager.RunningAppProcessInfo currApp,
15956             int clientTargetSdk) {
15957         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15958                 procState, clientTargetSdk);
15959         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15960             currApp.lru = memAdj;
15961         } else {
15962             currApp.lru = 0;
15963         }
15964         return imp;
15965     }
15966
15967     private void fillInProcMemInfo(ProcessRecord app,
15968             ActivityManager.RunningAppProcessInfo outInfo,
15969             int clientTargetSdk) {
15970         outInfo.pid = app.pid;
15971         outInfo.uid = app.info.uid;
15972         if (mHeavyWeightProcess == app) {
15973             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15974         }
15975         if (app.persistent) {
15976             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15977         }
15978         if (app.activities.size() > 0) {
15979             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15980         }
15981         outInfo.lastTrimLevel = app.trimMemoryLevel;
15982         int adj = app.curAdj;
15983         int procState = app.curProcState;
15984         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15985         outInfo.importanceReasonCode = app.adjTypeCode;
15986         outInfo.processState = app.curProcState;
15987     }
15988
15989     @Override
15990     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15991         enforceNotIsolatedCaller("getRunningAppProcesses");
15992
15993         final int callingUid = Binder.getCallingUid();
15994         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15995
15996         // Lazy instantiation of list
15997         List<ActivityManager.RunningAppProcessInfo> runList = null;
15998         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15999                 callingUid) == PackageManager.PERMISSION_GRANTED;
16000         final int userId = UserHandle.getUserId(callingUid);
16001         final boolean allUids = isGetTasksAllowed(
16002                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
16003
16004         synchronized (this) {
16005             // Iterate across all processes
16006             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16007                 ProcessRecord app = mLruProcesses.get(i);
16008                 if ((!allUsers && app.userId != userId)
16009                         || (!allUids && app.uid != callingUid)) {
16010                     continue;
16011                 }
16012                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
16013                     // Generate process state info for running application
16014                     ActivityManager.RunningAppProcessInfo currApp =
16015                         new ActivityManager.RunningAppProcessInfo(app.processName,
16016                                 app.pid, app.getPackageList());
16017                     fillInProcMemInfo(app, currApp, clientTargetSdk);
16018                     if (app.adjSource instanceof ProcessRecord) {
16019                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
16020                         currApp.importanceReasonImportance =
16021                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
16022                                         app.adjSourceProcState);
16023                     } else if (app.adjSource instanceof ActivityRecord) {
16024                         ActivityRecord r = (ActivityRecord)app.adjSource;
16025                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
16026                     }
16027                     if (app.adjTarget instanceof ComponentName) {
16028                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
16029                     }
16030                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
16031                     //        + " lru=" + currApp.lru);
16032                     if (runList == null) {
16033                         runList = new ArrayList<>();
16034                     }
16035                     runList.add(currApp);
16036                 }
16037             }
16038         }
16039         return runList;
16040     }
16041
16042     @Override
16043     public List<ApplicationInfo> getRunningExternalApplications() {
16044         enforceNotIsolatedCaller("getRunningExternalApplications");
16045         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
16046         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
16047         if (runningApps != null && runningApps.size() > 0) {
16048             Set<String> extList = new HashSet<String>();
16049             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
16050                 if (app.pkgList != null) {
16051                     for (String pkg : app.pkgList) {
16052                         extList.add(pkg);
16053                     }
16054                 }
16055             }
16056             IPackageManager pm = AppGlobals.getPackageManager();
16057             for (String pkg : extList) {
16058                 try {
16059                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
16060                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
16061                         retList.add(info);
16062                     }
16063                 } catch (RemoteException e) {
16064                 }
16065             }
16066         }
16067         return retList;
16068     }
16069
16070     @Override
16071     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outState) {
16072         if (outState == null) {
16073             throw new IllegalArgumentException("outState is null");
16074         }
16075         enforceNotIsolatedCaller("getMyMemoryState");
16076
16077         final int callingUid = Binder.getCallingUid();
16078         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
16079
16080         synchronized (this) {
16081             ProcessRecord proc;
16082             synchronized (mPidsSelfLocked) {
16083                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
16084             }
16085             if (proc != null) {
16086                 fillInProcMemInfo(proc, outState, clientTargetSdk);
16087             }
16088         }
16089     }
16090
16091     @Override
16092     public int getMemoryTrimLevel() {
16093         enforceNotIsolatedCaller("getMyMemoryState");
16094         synchronized (this) {
16095             return mLastMemoryLevel;
16096         }
16097     }
16098
16099     @Override
16100     public void onShellCommand(FileDescriptor in, FileDescriptor out,
16101             FileDescriptor err, String[] args, ShellCallback callback,
16102             ResultReceiver resultReceiver) {
16103         (new ActivityManagerShellCommand(this, false)).exec(
16104                 this, in, out, err, args, callback, resultReceiver);
16105     }
16106
16107     SleepToken acquireSleepToken(String tag, int displayId) {
16108         synchronized (this) {
16109             final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
16110             updateSleepIfNeededLocked();
16111             return token;
16112         }
16113     }
16114
16115     @Override
16116     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
16117         PriorityDump.dump(mPriorityDumper, fd, pw, args);
16118     }
16119
16120     /**
16121      * Wrapper function to print out debug data filtered by specified arguments.
16122     */
16123     private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
16124         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
16125
16126         boolean dumpAll = false;
16127         boolean dumpClient = false;
16128         boolean dumpCheckin = false;
16129         boolean dumpCheckinFormat = false;
16130         boolean dumpNormalPriority = false;
16131         boolean dumpVisibleStacksOnly = false;
16132         boolean dumpFocusedStackOnly = false;
16133         String dumpPackage = null;
16134
16135         int opti = 0;
16136         while (opti < args.length) {
16137             String opt = args[opti];
16138             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16139                 break;
16140             }
16141             opti++;
16142             if ("-a".equals(opt)) {
16143                 dumpAll = true;
16144             } else if ("-c".equals(opt)) {
16145                 dumpClient = true;
16146             } else if ("-v".equals(opt)) {
16147                 dumpVisibleStacksOnly = true;
16148             } else if ("-f".equals(opt)) {
16149                 dumpFocusedStackOnly = true;
16150             } else if ("-p".equals(opt)) {
16151                 if (opti < args.length) {
16152                     dumpPackage = args[opti];
16153                     opti++;
16154                 } else {
16155                     pw.println("Error: -p option requires package argument");
16156                     return;
16157                 }
16158                 dumpClient = true;
16159             } else if ("--checkin".equals(opt)) {
16160                 dumpCheckin = dumpCheckinFormat = true;
16161             } else if ("-C".equals(opt)) {
16162                 dumpCheckinFormat = true;
16163             } else if ("--normal-priority".equals(opt)) {
16164                 dumpNormalPriority = true;
16165             } else if ("-h".equals(opt)) {
16166                 ActivityManagerShellCommand.dumpHelp(pw, true);
16167                 return;
16168             } else {
16169                 pw.println("Unknown argument: " + opt + "; use -h for help");
16170             }
16171         }
16172
16173         long origId = Binder.clearCallingIdentity();
16174
16175         if (useProto) {
16176             final ProtoOutputStream proto = new ProtoOutputStream(fd);
16177             String cmd = opti < args.length ? args[opti] : "";
16178             opti++;
16179
16180             if ("activities".equals(cmd) || "a".equals(cmd)) {
16181                 // output proto is ActivityManagerServiceDumpActivitiesProto
16182                 synchronized (this) {
16183                     writeActivitiesToProtoLocked(proto);
16184                 }
16185             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
16186                 // output proto is ActivityManagerServiceDumpBroadcastsProto
16187                 synchronized (this) {
16188                     writeBroadcastsToProtoLocked(proto);
16189                 }
16190             } else if ("provider".equals(cmd)) {
16191                 String[] newArgs;
16192                 String name;
16193                 if (opti >= args.length) {
16194                     name = null;
16195                     newArgs = EMPTY_STRING_ARRAY;
16196                 } else {
16197                     name = args[opti];
16198                     opti++;
16199                     newArgs = new String[args.length - opti];
16200                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16201                             args.length - opti);
16202                 }
16203                 if (!dumpProviderProto(fd, pw, name, newArgs)) {
16204                     pw.println("No providers match: " + name);
16205                     pw.println("Use -h for help.");
16206                 }
16207             } else if ("service".equals(cmd)) {
16208                 // output proto is ActivityManagerServiceDumpServicesProto
16209                 mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
16210             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
16211                 if (opti < args.length) {
16212                     dumpPackage = args[opti];
16213                     opti++;
16214                 }
16215                 // output proto is ProcessProto
16216                 synchronized (this) {
16217                     writeProcessesToProtoLocked(proto, dumpPackage);
16218                 }
16219             } else {
16220                 // default option, dump everything, output is ActivityManagerServiceProto
16221                 synchronized (this) {
16222                     long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
16223                     writeActivitiesToProtoLocked(proto);
16224                     proto.end(activityToken);
16225
16226                     long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
16227                     writeBroadcastsToProtoLocked(proto);
16228                     proto.end(broadcastToken);
16229
16230                     long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
16231                     mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
16232                     proto.end(serviceToken);
16233
16234                     long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
16235                     writeProcessesToProtoLocked(proto, dumpPackage);
16236                     proto.end(processToken);
16237                 }
16238             }
16239             proto.flush();
16240             Binder.restoreCallingIdentity(origId);
16241             return;
16242         }
16243
16244         int dumpAppId = getAppId(dumpPackage);
16245         boolean more = false;
16246         // Is the caller requesting to dump a particular piece of data?
16247         if (opti < args.length) {
16248             String cmd = args[opti];
16249             opti++;
16250             if ("activities".equals(cmd) || "a".equals(cmd)) {
16251                 synchronized (this) {
16252                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16253                 }
16254             } else if ("lastanr".equals(cmd)) {
16255                 synchronized (this) {
16256                     dumpLastANRLocked(pw);
16257                 }
16258             } else if ("starter".equals(cmd)) {
16259                 synchronized (this) {
16260                     dumpActivityStarterLocked(pw, dumpPackage);
16261                 }
16262             } else if ("containers".equals(cmd)) {
16263                 synchronized (this) {
16264                     dumpActivityContainersLocked(pw);
16265                 }
16266             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
16267                 synchronized (this) {
16268                     if (mRecentTasks != null) {
16269                         mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
16270                     }
16271                 }
16272             } else if ("binder-proxies".equals(cmd)) {
16273                 if (opti >= args.length) {
16274                     dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
16275                             "Counts of Binder Proxies held by SYSTEM");
16276                 } else {
16277                     String uid = args[opti];
16278                     opti++;
16279                     // Ensure Binder Proxy Count is as up to date as possible
16280                     System.gc();
16281                     System.runFinalization();
16282                     System.gc();
16283                     pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
16284                 }
16285             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
16286                 if (opti < args.length) {
16287                     dumpPackage = args[opti];
16288                     opti++;
16289                 }
16290                 synchronized (this) {
16291                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
16292                 }
16293             } else if ("broadcast-stats".equals(cmd)) {
16294                 if (opti < args.length) {
16295                     dumpPackage = args[opti];
16296                     opti++;
16297                 }
16298                 synchronized (this) {
16299                     if (dumpCheckinFormat) {
16300                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
16301                                 dumpPackage);
16302                     } else {
16303                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
16304                     }
16305                 }
16306             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
16307                 if (opti < args.length) {
16308                     dumpPackage = args[opti];
16309                     opti++;
16310                 }
16311                 synchronized (this) {
16312                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
16313                 }
16314             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
16315                 if (opti < args.length) {
16316                     dumpPackage = args[opti];
16317                     opti++;
16318                 }
16319                 synchronized (this) {
16320                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
16321                 }
16322             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
16323                 synchronized (this) {
16324                     dumpOomLocked(fd, pw, args, opti, true);
16325                 }
16326             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
16327                 synchronized (this) {
16328                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
16329                 }
16330             } else if ("provider".equals(cmd)) {
16331                 String[] newArgs;
16332                 String name;
16333                 if (opti >= args.length) {
16334                     name = null;
16335                     newArgs = EMPTY_STRING_ARRAY;
16336                 } else {
16337                     name = args[opti];
16338                     opti++;
16339                     newArgs = new String[args.length - opti];
16340                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16341                 }
16342                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
16343                     pw.println("No providers match: " + name);
16344                     pw.println("Use -h for help.");
16345                 }
16346             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
16347                 synchronized (this) {
16348                     dumpProvidersLocked(fd, pw, args, opti, true, null);
16349                 }
16350             } else if ("service".equals(cmd)) {
16351                 String[] newArgs;
16352                 String name;
16353                 if (opti >= args.length) {
16354                     name = null;
16355                     newArgs = EMPTY_STRING_ARRAY;
16356                 } else {
16357                     name = args[opti];
16358                     opti++;
16359                     newArgs = new String[args.length - opti];
16360                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16361                             args.length - opti);
16362                 }
16363                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
16364                     pw.println("No services match: " + name);
16365                     pw.println("Use -h for help.");
16366                 }
16367             } else if ("package".equals(cmd)) {
16368                 String[] newArgs;
16369                 if (opti >= args.length) {
16370                     pw.println("package: no package name specified");
16371                     pw.println("Use -h for help.");
16372                 } else {
16373                     dumpPackage = args[opti];
16374                     opti++;
16375                     newArgs = new String[args.length - opti];
16376                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16377                             args.length - opti);
16378                     args = newArgs;
16379                     opti = 0;
16380                     more = true;
16381                 }
16382             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
16383                 synchronized (this) {
16384                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16385                 }
16386             } else if ("settings".equals(cmd)) {
16387                 synchronized (this) {
16388                     mConstants.dump(pw);
16389                 }
16390             } else if ("services".equals(cmd) || "s".equals(cmd)) {
16391                 if (dumpClient) {
16392                     ActiveServices.ServiceDumper dumper;
16393                     synchronized (this) {
16394                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16395                                 dumpPackage);
16396                     }
16397                     dumper.dumpWithClient();
16398                 } else {
16399                     synchronized (this) {
16400                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16401                                 dumpPackage).dumpLocked();
16402                     }
16403                 }
16404             } else if ("locks".equals(cmd)) {
16405                 LockGuard.dump(fd, pw, args);
16406             } else {
16407                 // Dumping a single activity?
16408                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
16409                         dumpFocusedStackOnly)) {
16410                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
16411                     int res = shell.exec(this, null, fd, null, args, null,
16412                             new ResultReceiver(null));
16413                     if (res < 0) {
16414                         pw.println("Bad activity command, or no activities match: " + cmd);
16415                         pw.println("Use -h for help.");
16416                     }
16417                 }
16418             }
16419             if (!more) {
16420                 Binder.restoreCallingIdentity(origId);
16421                 return;
16422             }
16423         }
16424
16425         // No piece of data specified, dump everything.
16426         if (dumpCheckinFormat) {
16427             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
16428         } else if (dumpClient) {
16429             ActiveServices.ServiceDumper sdumper;
16430             synchronized (this) {
16431                 mConstants.dump(pw);
16432                 pw.println();
16433                 if (dumpAll) {
16434                     pw.println("-------------------------------------------------------------------------------");
16435                 }
16436                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16437                 pw.println();
16438                 if (dumpAll) {
16439                     pw.println("-------------------------------------------------------------------------------");
16440                 }
16441                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16442                 pw.println();
16443                 if (dumpAll) {
16444                     pw.println("-------------------------------------------------------------------------------");
16445                 }
16446                 if (dumpAll || dumpPackage != null) {
16447                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16448                     pw.println();
16449                     if (dumpAll) {
16450                         pw.println("-------------------------------------------------------------------------------");
16451                     }
16452                 }
16453                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16454                 pw.println();
16455                 if (dumpAll) {
16456                     pw.println("-------------------------------------------------------------------------------");
16457                 }
16458                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16459                 pw.println();
16460                 if (dumpAll) {
16461                     pw.println("-------------------------------------------------------------------------------");
16462                 }
16463                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
16464                         dumpPackage);
16465             }
16466             sdumper.dumpWithClient();
16467             pw.println();
16468             synchronized (this) {
16469                 if (dumpAll) {
16470                     pw.println("-------------------------------------------------------------------------------");
16471                 }
16472                 if (mRecentTasks != null) {
16473                     mRecentTasks.dump(pw, dumpAll, dumpPackage);
16474                 }
16475                 pw.println();
16476                 if (dumpAll) {
16477                     pw.println("-------------------------------------------------------------------------------");
16478                 }
16479                 dumpLastANRLocked(pw);
16480                 pw.println();
16481                 if (dumpAll) {
16482                     pw.println("-------------------------------------------------------------------------------");
16483                 }
16484                 dumpActivityStarterLocked(pw, dumpPackage);
16485                 pw.println();
16486                 if (dumpAll) {
16487                     pw.println("-------------------------------------------------------------------------------");
16488                 }
16489                 dumpActivityContainersLocked(pw);
16490                 pw.println();
16491                 if (dumpAll) {
16492                     pw.println("-------------------------------------------------------------------------------");
16493                 }
16494                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16495                 if (mAssociations.size() > 0) {
16496                     pw.println();
16497                     if (dumpAll) {
16498                         pw.println("-------------------------------------------------------------------------------");
16499                     }
16500                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16501                 }
16502                 pw.println();
16503                 if (dumpAll) {
16504                     pw.println("-------------------------------------------------------------------------------");
16505                 }
16506                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16507             }
16508
16509         } else {
16510             synchronized (this) {
16511                 mConstants.dump(pw);
16512                 pw.println();
16513                 if (dumpAll) {
16514                     pw.println("-------------------------------------------------------------------------------");
16515                 }
16516                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16517                 pw.println();
16518                 if (dumpAll) {
16519                     pw.println("-------------------------------------------------------------------------------");
16520                 }
16521                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16522                 pw.println();
16523                 if (dumpAll) {
16524                     pw.println("-------------------------------------------------------------------------------");
16525                 }
16526                 if (dumpAll || dumpPackage != null) {
16527                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16528                     pw.println();
16529                     if (dumpAll) {
16530                         pw.println("-------------------------------------------------------------------------------");
16531                     }
16532                 }
16533                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16534                 pw.println();
16535                 if (dumpAll) {
16536                     pw.println("-------------------------------------------------------------------------------");
16537                 }
16538                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16539                 pw.println();
16540                 if (dumpAll) {
16541                     pw.println("-------------------------------------------------------------------------------");
16542                 }
16543                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
16544                         .dumpLocked();
16545                 pw.println();
16546                 if (dumpAll) {
16547                     pw.println("-------------------------------------------------------------------------------");
16548                 }
16549                 if (mRecentTasks != null) {
16550                     mRecentTasks.dump(pw, dumpAll, dumpPackage);
16551                 }
16552                 pw.println();
16553                 if (dumpAll) {
16554                     pw.println("-------------------------------------------------------------------------------");
16555                 }
16556                 dumpLastANRLocked(pw);
16557                 pw.println();
16558                 if (dumpAll) {
16559                     pw.println("-------------------------------------------------------------------------------");
16560                 }
16561                 dumpActivityStarterLocked(pw, dumpPackage);
16562                 pw.println();
16563                 if (dumpAll) {
16564                     pw.println("-------------------------------------------------------------------------------");
16565                 }
16566                 dumpActivityContainersLocked(pw);
16567                 // Activities section is dumped as part of the Critical priority dump. Exclude the
16568                 // section if priority is Normal.
16569                 if (!dumpNormalPriority){
16570                     pw.println();
16571                     if (dumpAll) {
16572                         pw.println("-------------------------------------------------------------------------------");
16573                     }
16574                     dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16575                 }
16576                 if (mAssociations.size() > 0) {
16577                     pw.println();
16578                     if (dumpAll) {
16579                         pw.println("-------------------------------------------------------------------------------");
16580                     }
16581                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16582                 }
16583                 pw.println();
16584                 if (dumpAll) {
16585                     pw.println("-------------------------------------------------------------------------------");
16586                 }
16587                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16588             }
16589         }
16590         Binder.restoreCallingIdentity(origId);
16591     }
16592
16593     private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
16594         // The output proto of "activity --proto activities" is ActivityManagerServiceDumpActivitiesProto
16595         mStackSupervisor.writeToProto(proto, ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
16596     }
16597
16598     private void dumpLastANRLocked(PrintWriter pw) {
16599         pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
16600         if (mLastANRState == null) {
16601             pw.println("  <no ANR has occurred since boot>");
16602         } else {
16603             pw.println(mLastANRState);
16604         }
16605     }
16606
16607     private void dumpActivityContainersLocked(PrintWriter pw) {
16608         pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
16609         mStackSupervisor.dumpChildrenNames(pw, " ");
16610         pw.println(" ");
16611     }
16612
16613     private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
16614         pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
16615         mActivityStartController.dump(pw, "", dumpPackage);
16616     }
16617
16618     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16619             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16620         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
16621                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
16622     }
16623
16624     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16625             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
16626         pw.println(header);
16627
16628         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
16629                 dumpPackage);
16630         boolean needSep = printedAnything;
16631
16632         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
16633                 mStackSupervisor.getResumedActivityLocked(),
16634                 dumpPackage, needSep, "  ResumedActivity: ");
16635         if (printed) {
16636             printedAnything = true;
16637             needSep = false;
16638         }
16639
16640         if (dumpPackage == null) {
16641             if (needSep) {
16642                 pw.println();
16643             }
16644             printedAnything = true;
16645             mStackSupervisor.dump(pw, "  ");
16646         }
16647
16648         if (!printedAnything) {
16649             pw.println("  (nothing)");
16650         }
16651     }
16652
16653     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16654             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16655         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
16656
16657         int dumpUid = 0;
16658         if (dumpPackage != null) {
16659             IPackageManager pm = AppGlobals.getPackageManager();
16660             try {
16661                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
16662             } catch (RemoteException e) {
16663             }
16664         }
16665
16666         boolean printedAnything = false;
16667
16668         final long now = SystemClock.uptimeMillis();
16669
16670         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
16671             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
16672                     = mAssociations.valueAt(i1);
16673             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
16674                 SparseArray<ArrayMap<String, Association>> sourceUids
16675                         = targetComponents.valueAt(i2);
16676                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
16677                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
16678                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
16679                         Association ass = sourceProcesses.valueAt(i4);
16680                         if (dumpPackage != null) {
16681                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
16682                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
16683                                 continue;
16684                             }
16685                         }
16686                         printedAnything = true;
16687                         pw.print("  ");
16688                         pw.print(ass.mTargetProcess);
16689                         pw.print("/");
16690                         UserHandle.formatUid(pw, ass.mTargetUid);
16691                         pw.print(" <- ");
16692                         pw.print(ass.mSourceProcess);
16693                         pw.print("/");
16694                         UserHandle.formatUid(pw, ass.mSourceUid);
16695                         pw.println();
16696                         pw.print("    via ");
16697                         pw.print(ass.mTargetComponent.flattenToShortString());
16698                         pw.println();
16699                         pw.print("    ");
16700                         long dur = ass.mTime;
16701                         if (ass.mNesting > 0) {
16702                             dur += now - ass.mStartTime;
16703                         }
16704                         TimeUtils.formatDuration(dur, pw);
16705                         pw.print(" (");
16706                         pw.print(ass.mCount);
16707                         pw.print(" times)");
16708                         pw.print("  ");
16709                         for (int i=0; i<ass.mStateTimes.length; i++) {
16710                             long amt = ass.mStateTimes[i];
16711                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16712                                 amt += now - ass.mLastStateUptime;
16713                             }
16714                             if (amt != 0) {
16715                                 pw.print(" ");
16716                                 pw.print(ProcessList.makeProcStateString(
16717                                             i + ActivityManager.MIN_PROCESS_STATE));
16718                                 pw.print("=");
16719                                 TimeUtils.formatDuration(amt, pw);
16720                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16721                                     pw.print("*");
16722                                 }
16723                             }
16724                         }
16725                         pw.println();
16726                         if (ass.mNesting > 0) {
16727                             pw.print("    Currently active: ");
16728                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
16729                             pw.println();
16730                         }
16731                     }
16732                 }
16733             }
16734
16735         }
16736
16737         if (!printedAnything) {
16738             pw.println("  (nothing)");
16739         }
16740     }
16741
16742     private int getAppId(String dumpPackage) {
16743         if (dumpPackage != null) {
16744             try {
16745                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
16746                         dumpPackage, 0);
16747                 return UserHandle.getAppId(info.uid);
16748             } catch (NameNotFoundException e) {
16749                 e.printStackTrace();
16750             }
16751         }
16752         return -1;
16753     }
16754
16755     boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
16756                 String header, boolean needSep) {
16757         boolean printed = false;
16758         for (int i=0; i<uids.size(); i++) {
16759             UidRecord uidRec = uids.valueAt(i);
16760             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
16761                 continue;
16762             }
16763             if (!printed) {
16764                 printed = true;
16765                 if (needSep) {
16766                     pw.println();
16767                 }
16768                 pw.print("  ");
16769                 pw.println(header);
16770                 needSep = true;
16771             }
16772             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
16773             pw.print(": "); pw.println(uidRec);
16774         }
16775         return printed;
16776     }
16777
16778     boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
16779         if(counts != null) {
16780             pw.println(header);
16781             for (int i = 0; i < counts.size(); i++) {
16782                 final int uid = counts.keyAt(i);
16783                 final int binderCount = counts.valueAt(i);
16784                 pw.print("    UID ");
16785                 pw.print(uid);
16786                 pw.print(", binder count = ");
16787                 pw.print(binderCount);
16788                 pw.print(", package(s)= ");
16789                 final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
16790                 if (pkgNames != null) {
16791                     for (int j = 0; j < pkgNames.length; j++) {
16792                         pw.print(pkgNames[j]);
16793                         pw.print("; ");
16794                     }
16795                 } else {
16796                     pw.print("NO PACKAGE NAME FOUND");
16797                 }
16798                 pw.println();
16799             }
16800             pw.println();
16801             return true;
16802         }
16803         return false;
16804     }
16805
16806     @GuardedBy("this")
16807     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16808             int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
16809         boolean needSep = false;
16810         int numPers = 0;
16811
16812         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
16813
16814         if (dumpAll) {
16815             final int NP = mProcessNames.getMap().size();
16816             for (int ip=0; ip<NP; ip++) {
16817                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16818                 final int NA = procs.size();
16819                 for (int ia=0; ia<NA; ia++) {
16820                     ProcessRecord r = procs.valueAt(ia);
16821                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16822                         continue;
16823                     }
16824                     if (!needSep) {
16825                         pw.println("  All known processes:");
16826                         needSep = true;
16827                     }
16828                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
16829                         pw.print(" UID "); pw.print(procs.keyAt(ia));
16830                         pw.print(" "); pw.println(r);
16831                     r.dump(pw, "    ");
16832                     if (r.persistent) {
16833                         numPers++;
16834                     }
16835                 }
16836             }
16837         }
16838
16839         if (mIsolatedProcesses.size() > 0) {
16840             boolean printed = false;
16841             for (int i=0; i<mIsolatedProcesses.size(); i++) {
16842                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
16843                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16844                     continue;
16845                 }
16846                 if (!printed) {
16847                     if (needSep) {
16848                         pw.println();
16849                     }
16850                     pw.println("  Isolated process list (sorted by uid):");
16851                     printed = true;
16852                     needSep = true;
16853                 }
16854                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
16855                 pw.println(r);
16856             }
16857         }
16858
16859         if (mActiveInstrumentation.size() > 0) {
16860             boolean printed = false;
16861             for (int i=0; i<mActiveInstrumentation.size(); i++) {
16862                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16863                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16864                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16865                     continue;
16866                 }
16867                 if (!printed) {
16868                     if (needSep) {
16869                         pw.println();
16870                     }
16871                     pw.println("  Active instrumentation:");
16872                     printed = true;
16873                     needSep = true;
16874                 }
16875                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
16876                 pw.println(ai);
16877                 ai.dump(pw, "      ");
16878             }
16879         }
16880
16881         if (mActiveUids.size() > 0) {
16882             if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16883                 needSep = true;
16884             }
16885         }
16886         if (dumpAll) {
16887             if (mValidateUids.size() > 0) {
16888                 if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16889                         needSep)) {
16890                     needSep = true;
16891                 }
16892             }
16893         }
16894
16895         if (mLruProcesses.size() > 0) {
16896             if (needSep) {
16897                 pw.println();
16898             }
16899             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16900                     pw.print(" total, non-act at ");
16901                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16902                     pw.print(", non-svc at ");
16903                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16904                     pw.println("):");
16905             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
16906             needSep = true;
16907         }
16908
16909         if (dumpAll || dumpPackage != null) {
16910             synchronized (mPidsSelfLocked) {
16911                 boolean printed = false;
16912                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
16913                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
16914                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16915                         continue;
16916                     }
16917                     if (!printed) {
16918                         if (needSep) pw.println();
16919                         needSep = true;
16920                         pw.println("  PID mappings:");
16921                         printed = true;
16922                     }
16923                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16924                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16925                 }
16926             }
16927         }
16928
16929         if (mImportantProcesses.size() > 0) {
16930             synchronized (mPidsSelfLocked) {
16931                 boolean printed = false;
16932                 for (int i = 0; i< mImportantProcesses.size(); i++) {
16933                     ProcessRecord r = mPidsSelfLocked.get(
16934                             mImportantProcesses.valueAt(i).pid);
16935                     if (dumpPackage != null && (r == null
16936                             || !r.pkgList.containsKey(dumpPackage))) {
16937                         continue;
16938                     }
16939                     if (!printed) {
16940                         if (needSep) pw.println();
16941                         needSep = true;
16942                         pw.println("  Foreground Processes:");
16943                         printed = true;
16944                     }
16945                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
16946                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16947                 }
16948             }
16949         }
16950
16951         if (mPersistentStartingProcesses.size() > 0) {
16952             if (needSep) pw.println();
16953             needSep = true;
16954             pw.println("  Persisent processes that are starting:");
16955             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
16956                     "Starting Norm", "Restarting PERS", dumpPackage);
16957         }
16958
16959         if (mRemovedProcesses.size() > 0) {
16960             if (needSep) pw.println();
16961             needSep = true;
16962             pw.println("  Processes that are being removed:");
16963             dumpProcessList(pw, this, mRemovedProcesses, "    ",
16964                     "Removed Norm", "Removed PERS", dumpPackage);
16965         }
16966
16967         if (mProcessesOnHold.size() > 0) {
16968             if (needSep) pw.println();
16969             needSep = true;
16970             pw.println("  Processes that are on old until the system is ready:");
16971             dumpProcessList(pw, this, mProcessesOnHold, "    ",
16972                     "OnHold Norm", "OnHold PERS", dumpPackage);
16973         }
16974
16975         needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16976
16977         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16978
16979         if (dumpPackage == null) {
16980             pw.println();
16981             needSep = false;
16982             mUserController.dump(pw, dumpAll);
16983         }
16984         if (mHomeProcess != null && (dumpPackage == null
16985                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16986             if (needSep) {
16987                 pw.println();
16988                 needSep = false;
16989             }
16990             pw.println("  mHomeProcess: " + mHomeProcess);
16991         }
16992         if (mPreviousProcess != null && (dumpPackage == null
16993                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16994             if (needSep) {
16995                 pw.println();
16996                 needSep = false;
16997             }
16998             pw.println("  mPreviousProcess: " + mPreviousProcess);
16999         }
17000         if (dumpAll && (mPreviousProcess == null || dumpPackage == null
17001                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
17002             StringBuilder sb = new StringBuilder(128);
17003             sb.append("  mPreviousProcessVisibleTime: ");
17004             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
17005             pw.println(sb);
17006         }
17007         if (mHeavyWeightProcess != null && (dumpPackage == null
17008                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
17009             if (needSep) {
17010                 pw.println();
17011                 needSep = false;
17012             }
17013             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
17014         }
17015         if (dumpAll && mPendingStarts.size() > 0) {
17016             if (needSep) pw.println();
17017             needSep = true;
17018             pw.println("  mPendingStarts: ");
17019             for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
17020                 pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
17021             }
17022         }
17023         if (dumpPackage == null) {
17024             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
17025             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
17026         }
17027         if (dumpAll) {
17028             if (dumpPackage == null) {
17029                 pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
17030             }
17031             if (mCompatModePackages.getPackages().size() > 0) {
17032                 boolean printed = false;
17033                 for (Map.Entry<String, Integer> entry
17034                         : mCompatModePackages.getPackages().entrySet()) {
17035                     String pkg = entry.getKey();
17036                     int mode = entry.getValue();
17037                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
17038                         continue;
17039                     }
17040                     if (!printed) {
17041                         pw.println("  mScreenCompatPackages:");
17042                         printed = true;
17043                     }
17044                     pw.print("    "); pw.print(pkg); pw.print(": ");
17045                             pw.print(mode); pw.println();
17046                 }
17047             }
17048             final int NI = mUidObservers.getRegisteredCallbackCount();
17049             boolean printed = false;
17050             for (int i=0; i<NI; i++) {
17051                 final UidObserverRegistration reg = (UidObserverRegistration)
17052                         mUidObservers.getRegisteredCallbackCookie(i);
17053                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
17054                     if (!printed) {
17055                         pw.println("  mUidObservers:");
17056                         printed = true;
17057                     }
17058                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
17059                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
17060                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
17061                         pw.print(" IDLE");
17062                     }
17063                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
17064                         pw.print(" ACT" );
17065                     }
17066                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
17067                         pw.print(" GONE");
17068                     }
17069                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
17070                         pw.print(" STATE");
17071                         pw.print(" (cut="); pw.print(reg.cutpoint);
17072                         pw.print(")");
17073                     }
17074                     pw.println();
17075                     if (reg.lastProcStates != null) {
17076                         final int NJ = reg.lastProcStates.size();
17077                         for (int j=0; j<NJ; j++) {
17078                             pw.print("      Last ");
17079                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
17080                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
17081                         }
17082                     }
17083                 }
17084             }
17085             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
17086             pw.println("  mDeviceIdleExceptIdleWhitelist="
17087                     + Arrays.toString(mDeviceIdleExceptIdleWhitelist));
17088             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
17089             if (mPendingTempWhitelist.size() > 0) {
17090                 pw.println("  mPendingTempWhitelist:");
17091                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
17092                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
17093                     pw.print("    ");
17094                     UserHandle.formatUid(pw, ptw.targetUid);
17095                     pw.print(": ");
17096                     TimeUtils.formatDuration(ptw.duration, pw);
17097                     pw.print(" ");
17098                     pw.println(ptw.tag);
17099                 }
17100             }
17101         }
17102         if (dumpPackage == null) {
17103             pw.println("  mWakefulness="
17104                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
17105             pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
17106             pw.println("  mSleeping=" + mSleeping);
17107             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
17108             if (mRunningVoice != null) {
17109                 pw.println("  mRunningVoice=" + mRunningVoice);
17110                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
17111             }
17112             pw.println("  mVrController=" + mVrController);
17113         }
17114         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17115                 || mOrigWaitForDebugger) {
17116             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17117                     || dumpPackage.equals(mOrigDebugApp)) {
17118                 if (needSep) {
17119                     pw.println();
17120                     needSep = false;
17121                 }
17122                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
17123                         + " mDebugTransient=" + mDebugTransient
17124                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
17125             }
17126         }
17127         if (mCurAppTimeTracker != null) {
17128             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
17129         }
17130         if (mMemWatchProcesses.getMap().size() > 0) {
17131             pw.println("  Mem watch processes:");
17132             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
17133                     = mMemWatchProcesses.getMap();
17134             for (int i=0; i<procs.size(); i++) {
17135                 final String proc = procs.keyAt(i);
17136                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
17137                 for (int j=0; j<uids.size(); j++) {
17138                     if (needSep) {
17139                         pw.println();
17140                         needSep = false;
17141                     }
17142                     StringBuilder sb = new StringBuilder();
17143                     sb.append("    ").append(proc).append('/');
17144                     UserHandle.formatUid(sb, uids.keyAt(j));
17145                     Pair<Long, String> val = uids.valueAt(j);
17146                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
17147                     if (val.second != null) {
17148                         sb.append(", report to ").append(val.second);
17149                     }
17150                     pw.println(sb.toString());
17151                 }
17152             }
17153             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
17154             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
17155             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
17156                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
17157         }
17158         if (mTrackAllocationApp != null) {
17159             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17160                 if (needSep) {
17161                     pw.println();
17162                     needSep = false;
17163                 }
17164                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
17165             }
17166         }
17167         if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17168                 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17169             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
17170                 if (needSep) {
17171                     pw.println();
17172                     needSep = false;
17173                 }
17174                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
17175                 if (mProfilerInfo != null) {
17176                     pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
17177                             mProfilerInfo.profileFd);
17178                     pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
17179                             " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
17180                             " mStreamingOutput=" + mProfilerInfo.streamingOutput);
17181                     pw.println("  mProfileType=" + mProfileType);
17182                 }
17183             }
17184         }
17185         if (mNativeDebuggingApp != null) {
17186             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17187                 if (needSep) {
17188                     pw.println();
17189                     needSep = false;
17190                 }
17191                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
17192             }
17193         }
17194         if (mAllowAppSwitchUids.size() > 0) {
17195             boolean printed = false;
17196             for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
17197                 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
17198                 for (int j = 0; j < types.size(); j++) {
17199                     if (dumpPackage == null ||
17200                             UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
17201                         if (needSep) {
17202                             pw.println();
17203                             needSep = false;
17204                         }
17205                         if (!printed) {
17206                             pw.println("  mAllowAppSwitchUids:");
17207                             printed = true;
17208                         }
17209                         pw.print("    User ");
17210                         pw.print(mAllowAppSwitchUids.keyAt(i));
17211                         pw.print(": Type ");
17212                         pw.print(types.keyAt(j));
17213                         pw.print(" = ");
17214                         UserHandle.formatUid(pw, types.valueAt(j).intValue());
17215                         pw.println();
17216                     }
17217                 }
17218             }
17219         }
17220         if (dumpPackage == null) {
17221             if (mAlwaysFinishActivities) {
17222                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
17223             }
17224             if (mController != null) {
17225                 pw.println("  mController=" + mController
17226                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
17227             }
17228             if (dumpAll) {
17229                 pw.println("  Total persistent processes: " + numPers);
17230                 pw.println("  mProcessesReady=" + mProcessesReady
17231                         + " mSystemReady=" + mSystemReady
17232                         + " mBooted=" + mBooted
17233                         + " mFactoryTest=" + mFactoryTest);
17234                 pw.println("  mBooting=" + mBooting
17235                         + " mCallFinishBooting=" + mCallFinishBooting
17236                         + " mBootAnimationComplete=" + mBootAnimationComplete);
17237                 pw.print("  mLastPowerCheckUptime=");
17238                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
17239                         pw.println("");
17240                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
17241                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
17242                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
17243                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
17244                         + " (" + mLruProcesses.size() + " total)"
17245                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
17246                         + " mNumServiceProcs=" + mNumServiceProcs
17247                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
17248                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
17249                         + " mLastMemoryLevel=" + mLastMemoryLevel
17250                         + " mLastNumProcesses=" + mLastNumProcesses);
17251                 long now = SystemClock.uptimeMillis();
17252                 pw.print("  mLastIdleTime=");
17253                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
17254                         pw.print(" mLowRamSinceLastIdle=");
17255                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
17256                         pw.println();
17257                 pw.println();
17258                 pw.print("  mUidChangeDispatchCount=");
17259                 pw.print(mUidChangeDispatchCount);
17260                 pw.println();
17261
17262                 pw.println("  Slow UID dispatches:");
17263                 final int N = mUidObservers.beginBroadcast();
17264                 for (int i = 0; i < N; i++) {
17265                     UidObserverRegistration r =
17266                             (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
17267                     pw.print("    ");
17268                     pw.print(mUidObservers.getBroadcastItem(i).getClass().getTypeName());
17269                     pw.print(": ");
17270                     pw.print(r.mSlowDispatchCount);
17271                     pw.print(" / Max ");
17272                     pw.print(r.mMaxDispatchTime);
17273                     pw.println("ms");
17274                 }
17275                 mUidObservers.finishBroadcast();
17276
17277                 pw.println();
17278                 pw.println("  ServiceManager statistics:");
17279                 ServiceManager.sStatLogger.dump(pw, "    ");
17280                 pw.println();
17281             }
17282         }
17283         pw.println("  mForceBackgroundCheck=" + mForceBackgroundCheck);
17284     }
17285
17286     @GuardedBy("this")
17287     void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
17288         int numPers = 0;
17289
17290         final int NP = mProcessNames.getMap().size();
17291         for (int ip=0; ip<NP; ip++) {
17292             SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
17293             final int NA = procs.size();
17294             for (int ia = 0; ia<NA; ia++) {
17295                 ProcessRecord r = procs.valueAt(ia);
17296                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17297                     continue;
17298                 }
17299                 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS);
17300                 if (r.persistent) {
17301                     numPers++;
17302                 }
17303             }
17304         }
17305
17306         for (int i=0; i<mIsolatedProcesses.size(); i++) {
17307             ProcessRecord r = mIsolatedProcesses.valueAt(i);
17308             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17309                 continue;
17310             }
17311             r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS);
17312         }
17313
17314         for (int i=0; i<mActiveInstrumentation.size(); i++) {
17315             ActiveInstrumentation ai = mActiveInstrumentation.get(i);
17316             if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
17317                     && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
17318                 continue;
17319             }
17320             ai.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_INSTRUMENTATIONS);
17321         }
17322
17323         int whichAppId = getAppId(dumpPackage);
17324         for (int i=0; i<mActiveUids.size(); i++) {
17325             UidRecord uidRec = mActiveUids.valueAt(i);
17326             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
17327                 continue;
17328             }
17329             uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
17330         }
17331
17332         for (int i=0; i<mValidateUids.size(); i++) {
17333             UidRecord uidRec = mValidateUids.valueAt(i);
17334             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
17335                 continue;
17336             }
17337             uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
17338         }
17339
17340         if (mLruProcesses.size() > 0) {
17341             long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
17342             int total = mLruProcesses.size();
17343             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
17344             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
17345             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
17346             writeProcessOomListToProto(proto, ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, this,
17347                     mLruProcesses,false, dumpPackage);
17348             proto.end(lruToken);
17349         }
17350
17351         if (dumpPackage != null) {
17352             synchronized (mPidsSelfLocked) {
17353                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
17354                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
17355                     if (!r.pkgList.containsKey(dumpPackage)) {
17356                         continue;
17357                     }
17358                     r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
17359                 }
17360             }
17361         }
17362
17363         if (mImportantProcesses.size() > 0) {
17364             synchronized (mPidsSelfLocked) {
17365                 for (int i=0; i<mImportantProcesses.size(); i++) {
17366                     ImportanceToken it = mImportantProcesses.valueAt(i);
17367                     ProcessRecord r = mPidsSelfLocked.get(it.pid);
17368                     if (dumpPackage != null && (r == null
17369                             || !r.pkgList.containsKey(dumpPackage))) {
17370                         continue;
17371                     }
17372                     it.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
17373                 }
17374             }
17375         }
17376
17377         for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
17378             ProcessRecord r = mPersistentStartingProcesses.get(i);
17379             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17380                 continue;
17381             }
17382             r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
17383         }
17384
17385         for (int i=0; i<mRemovedProcesses.size(); i++) {
17386             ProcessRecord r = mRemovedProcesses.get(i);
17387             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17388                 continue;
17389             }
17390             r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
17391         }
17392
17393         for (int i=0; i<mProcessesOnHold.size(); i++) {
17394             ProcessRecord r = mProcessesOnHold.get(i);
17395             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17396                 continue;
17397             }
17398             r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
17399         }
17400
17401         writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS, dumpPackage);
17402         mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS, dumpPackage);
17403
17404         if (dumpPackage == null) {
17405             mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
17406             getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION);
17407             proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
17408         }
17409
17410         if (mHomeProcess != null && (dumpPackage == null
17411                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
17412             mHomeProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC);
17413         }
17414
17415         if (mPreviousProcess != null && (dumpPackage == null
17416                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
17417             mPreviousProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC);
17418             proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
17419         }
17420
17421         if (mHeavyWeightProcess != null && (dumpPackage == null
17422                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
17423             mHeavyWeightProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
17424         }
17425
17426         for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
17427             String pkg = entry.getKey();
17428             int mode = entry.getValue();
17429             if (dumpPackage == null || dumpPackage.equals(pkg)) {
17430                 long compatToken = proto.start(ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES);
17431                 proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
17432                 proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE, mode);
17433                 proto.end(compatToken);
17434             }
17435         }
17436
17437         final int NI = mUidObservers.getRegisteredCallbackCount();
17438         for (int i=0; i<NI; i++) {
17439             final UidObserverRegistration reg = (UidObserverRegistration)
17440                     mUidObservers.getRegisteredCallbackCookie(i);
17441             if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
17442                 reg.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
17443             }
17444         }
17445
17446         for (int v : mDeviceIdleWhitelist) {
17447             proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_WHITELIST, v);
17448         }
17449
17450         for (int v : mDeviceIdleTempWhitelist) {
17451             proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
17452         }
17453
17454         if (mPendingTempWhitelist.size() > 0) {
17455             for (int i=0; i < mPendingTempWhitelist.size(); i++) {
17456                 mPendingTempWhitelist.valueAt(i).writeToProto(proto,
17457                         ActivityManagerServiceDumpProcessesProto.PENDING_TEMP_WHITELIST);
17458             }
17459         }
17460
17461         if (dumpPackage == null) {
17462             final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
17463             proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
17464                     PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
17465             for (SleepToken st : mStackSupervisor.mSleepTokens) {
17466                 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
17467             }
17468             proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
17469             proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
17470             proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
17471             proto.end(sleepToken);
17472
17473             if (mRunningVoice != null) {
17474                 final long vrToken = proto.start(ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
17475                 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION, mRunningVoice.toString());
17476                 mVoiceWakeLock.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
17477                 proto.end(vrToken);
17478             }
17479
17480             mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
17481         }
17482
17483         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17484                 || mOrigWaitForDebugger) {
17485             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17486                     || dumpPackage.equals(mOrigDebugApp)) {
17487                 final long debugAppToken = proto.start(ActivityManagerServiceDumpProcessesProto.DEBUG);
17488                 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
17489                 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
17490                 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
17491                 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
17492                 proto.end(debugAppToken);
17493             }
17494         }
17495
17496         if (mCurAppTimeTracker != null) {
17497             mCurAppTimeTracker.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
17498         }
17499
17500         if (mMemWatchProcesses.getMap().size() > 0) {
17501             final long token = proto.start(ActivityManagerServiceDumpProcessesProto.MEM_WATCH_PROCESSES);
17502             ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
17503             for (int i=0; i<procs.size(); i++) {
17504                 final String proc = procs.keyAt(i);
17505                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
17506                 final long ptoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.PROCS);
17507                 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.NAME, proc);
17508                 for (int j=0; j<uids.size(); j++) {
17509                     final long utoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MEM_STATS);
17510                     Pair<Long, String> val = uids.valueAt(j);
17511                     proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
17512                     proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
17513                             DebugUtils.sizeValueToString(val.first, new StringBuilder()));
17514                     proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
17515                     proto.end(utoken);
17516                 }
17517                 proto.end(ptoken);
17518             }
17519
17520             final long dtoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.DUMP);
17521             proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
17522             proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
17523             proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
17524             proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
17525             proto.end(dtoken);
17526
17527             proto.end(token);
17528         }
17529
17530         if (mTrackAllocationApp != null) {
17531             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17532                 proto.write(ActivityManagerServiceDumpProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
17533             }
17534         }
17535
17536         if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17537                 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17538             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
17539                 final long token = proto.start(ActivityManagerServiceDumpProcessesProto.PROFILE);
17540                 proto.write(ActivityManagerServiceDumpProcessesProto.Profile.APP_NAME, mProfileApp);
17541                 mProfileProc.writeToProto(proto,ActivityManagerServiceDumpProcessesProto.Profile.PROC);
17542                 if (mProfilerInfo != null) {
17543                     mProfilerInfo.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Profile.INFO);
17544                     proto.write(ActivityManagerServiceDumpProcessesProto.Profile.TYPE, mProfileType);
17545                 }
17546                 proto.end(token);
17547             }
17548         }
17549
17550         if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17551             proto.write(ActivityManagerServiceDumpProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
17552         }
17553
17554         if (dumpPackage == null) {
17555             proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
17556             if (mController != null) {
17557                 final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER);
17558                 proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mController.toString());
17559                 proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
17560                 proto.end(token);
17561             }
17562             proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
17563             proto.write(ActivityManagerServiceDumpProcessesProto.PROCESSES_READY, mProcessesReady);
17564             proto.write(ActivityManagerServiceDumpProcessesProto.SYSTEM_READY, mSystemReady);
17565             proto.write(ActivityManagerServiceDumpProcessesProto.BOOTED, mBooted);
17566             proto.write(ActivityManagerServiceDumpProcessesProto.FACTORY_TEST, mFactoryTest);
17567             proto.write(ActivityManagerServiceDumpProcessesProto.BOOTING, mBooting);
17568             proto.write(ActivityManagerServiceDumpProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
17569             proto.write(ActivityManagerServiceDumpProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
17570             proto.write(ActivityManagerServiceDumpProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
17571             mStackSupervisor.mGoingToSleep.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP);
17572             mStackSupervisor.mLaunchingActivity.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY);
17573             proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq);
17574             proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mLruSeq);
17575             proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
17576             proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
17577             proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
17578             proto.write(ActivityManagerServiceDumpProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
17579             proto.write(ActivityManagerServiceDumpProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
17580             proto.write(ActivityManagerServiceDumpProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
17581             long now = SystemClock.uptimeMillis();
17582             ProtoUtils.toDuration(proto, ActivityManagerServiceDumpProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
17583             proto.write(ActivityManagerServiceDumpProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
17584         }
17585
17586     }
17587
17588     void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
17589         if (mProcessesToGc.size() > 0) {
17590             long now = SystemClock.uptimeMillis();
17591             for (int i=0; i<mProcessesToGc.size(); i++) {
17592                 ProcessRecord r = mProcessesToGc.get(i);
17593                 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17594                     continue;
17595                 }
17596                 final long token = proto.start(fieldId);
17597                 r.writeToProto(proto, ProcessToGcProto.PROC);
17598                 proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
17599                 proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
17600                 proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
17601                 proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
17602                 proto.end(token);
17603             }
17604         }
17605     }
17606
17607     boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
17608         if (mProcessesToGc.size() > 0) {
17609             boolean printed = false;
17610             long now = SystemClock.uptimeMillis();
17611             for (int i=0; i<mProcessesToGc.size(); i++) {
17612                 ProcessRecord proc = mProcessesToGc.get(i);
17613                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
17614                     continue;
17615                 }
17616                 if (!printed) {
17617                     if (needSep) pw.println();
17618                     needSep = true;
17619                     pw.println("  Processes that are waiting to GC:");
17620                     printed = true;
17621                 }
17622                 pw.print("    Process "); pw.println(proc);
17623                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
17624                         pw.print(", last gced=");
17625                         pw.print(now-proc.lastRequestedGc);
17626                         pw.print(" ms ago, last lowMem=");
17627                         pw.print(now-proc.lastLowMemory);
17628                         pw.println(" ms ago");
17629
17630             }
17631         }
17632         return needSep;
17633     }
17634
17635     void printOomLevel(PrintWriter pw, String name, int adj) {
17636         pw.print("    ");
17637         if (adj >= 0) {
17638             pw.print(' ');
17639             if (adj < 10) pw.print(' ');
17640         } else {
17641             if (adj > -10) pw.print(' ');
17642         }
17643         pw.print(adj);
17644         pw.print(": ");
17645         pw.print(name);
17646         pw.print(" (");
17647         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
17648         pw.println(")");
17649     }
17650
17651     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17652             int opti, boolean dumpAll) {
17653         boolean needSep = false;
17654
17655         if (mLruProcesses.size() > 0) {
17656             if (needSep) pw.println();
17657             needSep = true;
17658             pw.println("  OOM levels:");
17659             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
17660             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
17661             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
17662             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
17663             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
17664             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
17665             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
17666             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
17667             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
17668             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
17669             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
17670             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
17671             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
17672             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
17673
17674             if (needSep) pw.println();
17675             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
17676                     pw.print(" total, non-act at ");
17677                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
17678                     pw.print(", non-svc at ");
17679                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
17680                     pw.println("):");
17681             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
17682             needSep = true;
17683         }
17684
17685         dumpProcessesToGc(pw, needSep, null);
17686
17687         pw.println();
17688         pw.println("  mHomeProcess: " + mHomeProcess);
17689         pw.println("  mPreviousProcess: " + mPreviousProcess);
17690         if (mHeavyWeightProcess != null) {
17691             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
17692         }
17693
17694         return true;
17695     }
17696
17697     /**
17698      * There are three ways to call this:
17699      *  - no provider specified: dump all the providers
17700      *  - a flattened component name that matched an existing provider was specified as the
17701      *    first arg: dump that one provider
17702      *  - the first arg isn't the flattened component name of an existing provider:
17703      *    dump all providers whose component contains the first arg as a substring
17704      */
17705     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17706             int opti, boolean dumpAll) {
17707         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
17708     }
17709
17710     /**
17711      * Similar to the dumpProvider, but only dumps the first matching provider.
17712      * The provider is responsible for dumping as proto.
17713      */
17714     protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
17715             String[] args) {
17716         return mProviderMap.dumpProviderProto(fd, pw, name, args);
17717     }
17718
17719     static class ItemMatcher {
17720         ArrayList<ComponentName> components;
17721         ArrayList<String> strings;
17722         ArrayList<Integer> objects;
17723         boolean all;
17724
17725         ItemMatcher() {
17726             all = true;
17727         }
17728
17729         void build(String name) {
17730             ComponentName componentName = ComponentName.unflattenFromString(name);
17731             if (componentName != null) {
17732                 if (components == null) {
17733                     components = new ArrayList<ComponentName>();
17734                 }
17735                 components.add(componentName);
17736                 all = false;
17737             } else {
17738                 int objectId = 0;
17739                 // Not a '/' separated full component name; maybe an object ID?
17740                 try {
17741                     objectId = Integer.parseInt(name, 16);
17742                     if (objects == null) {
17743                         objects = new ArrayList<Integer>();
17744                     }
17745                     objects.add(objectId);
17746                     all = false;
17747                 } catch (RuntimeException e) {
17748                     // Not an integer; just do string match.
17749                     if (strings == null) {
17750                         strings = new ArrayList<String>();
17751                     }
17752                     strings.add(name);
17753                     all = false;
17754                 }
17755             }
17756         }
17757
17758         int build(String[] args, int opti) {
17759             for (; opti<args.length; opti++) {
17760                 String name = args[opti];
17761                 if ("--".equals(name)) {
17762                     return opti+1;
17763                 }
17764                 build(name);
17765             }
17766             return opti;
17767         }
17768
17769         boolean match(Object object, ComponentName comp) {
17770             if (all) {
17771                 return true;
17772             }
17773             if (components != null) {
17774                 for (int i=0; i<components.size(); i++) {
17775                     if (components.get(i).equals(comp)) {
17776                         return true;
17777                     }
17778                 }
17779             }
17780             if (objects != null) {
17781                 for (int i=0; i<objects.size(); i++) {
17782                     if (System.identityHashCode(object) == objects.get(i)) {
17783                         return true;
17784                     }
17785                 }
17786             }
17787             if (strings != null) {
17788                 String flat = comp.flattenToString();
17789                 for (int i=0; i<strings.size(); i++) {
17790                     if (flat.contains(strings.get(i))) {
17791                         return true;
17792                     }
17793                 }
17794             }
17795             return false;
17796         }
17797     }
17798
17799     /**
17800      * There are three things that cmd can be:
17801      *  - a flattened component name that matches an existing activity
17802      *  - the cmd arg isn't the flattened component name of an existing activity:
17803      *    dump all activity whose component contains the cmd as a substring
17804      *  - A hex number of the ActivityRecord object instance.
17805      *
17806      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
17807      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
17808      */
17809     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17810             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
17811         ArrayList<ActivityRecord> activities;
17812
17813         synchronized (this) {
17814             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
17815                     dumpFocusedStackOnly);
17816         }
17817
17818         if (activities.size() <= 0) {
17819             return false;
17820         }
17821
17822         String[] newArgs = new String[args.length - opti];
17823         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
17824
17825         TaskRecord lastTask = null;
17826         boolean needSep = false;
17827         for (int i=activities.size()-1; i>=0; i--) {
17828             ActivityRecord r = activities.get(i);
17829             if (needSep) {
17830                 pw.println();
17831             }
17832             needSep = true;
17833             synchronized (this) {
17834                 final TaskRecord task = r.getTask();
17835                 if (lastTask != task) {
17836                     lastTask = task;
17837                     pw.print("TASK "); pw.print(lastTask.affinity);
17838                             pw.print(" id="); pw.print(lastTask.taskId);
17839                             pw.print(" userId="); pw.println(lastTask.userId);
17840                     if (dumpAll) {
17841                         lastTask.dump(pw, "  ");
17842                     }
17843                 }
17844             }
17845             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
17846         }
17847         return true;
17848     }
17849
17850     /**
17851      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
17852      * there is a thread associated with the activity.
17853      */
17854     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
17855             final ActivityRecord r, String[] args, boolean dumpAll) {
17856         String innerPrefix = prefix + "  ";
17857         synchronized (this) {
17858             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
17859                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
17860                     pw.print(" pid=");
17861                     if (r.app != null) pw.println(r.app.pid);
17862                     else pw.println("(not running)");
17863             if (dumpAll) {
17864                 r.dump(pw, innerPrefix);
17865             }
17866         }
17867         if (r.app != null && r.app.thread != null) {
17868             // flush anything that is already in the PrintWriter since the thread is going
17869             // to write to the file descriptor directly
17870             pw.flush();
17871             try {
17872                 TransferPipe tp = new TransferPipe();
17873                 try {
17874                     r.app.thread.dumpActivity(tp.getWriteFd(),
17875                             r.appToken, innerPrefix, args);
17876                     tp.go(fd);
17877                 } finally {
17878                     tp.kill();
17879                 }
17880             } catch (IOException e) {
17881                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
17882             } catch (RemoteException e) {
17883                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
17884             }
17885         }
17886     }
17887
17888     void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
17889         if (mRegisteredReceivers.size() > 0) {
17890             Iterator it = mRegisteredReceivers.values().iterator();
17891             while (it.hasNext()) {
17892                 ReceiverList r = (ReceiverList)it.next();
17893                 r.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_LIST);
17894             }
17895         }
17896         mReceiverResolver.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
17897         for (BroadcastQueue q : mBroadcastQueues) {
17898             q.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
17899         }
17900         for (int user=0; user<mStickyBroadcasts.size(); user++) {
17901             long token = proto.start(ActivityManagerServiceDumpBroadcastsProto.STICKY_BROADCASTS);
17902             proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
17903             for (Map.Entry<String, ArrayList<Intent>> ent
17904                     : mStickyBroadcasts.valueAt(user).entrySet()) {
17905                 long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
17906                 proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
17907                 for (Intent intent : ent.getValue()) {
17908                     intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
17909                             false, true, true, false);
17910                 }
17911                 proto.end(actionToken);
17912             }
17913             proto.end(token);
17914         }
17915
17916         long handlerToken = proto.start(ActivityManagerServiceDumpBroadcastsProto.HANDLER);
17917         proto.write(ActivityManagerServiceDumpBroadcastsProto.MainHandler.HANDLER, mHandler.toString());
17918         mHandler.getLooper().writeToProto(proto,
17919             ActivityManagerServiceDumpBroadcastsProto.MainHandler.LOOPER);
17920         proto.end(handlerToken);
17921     }
17922
17923     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17924             int opti, boolean dumpAll, String dumpPackage) {
17925         boolean needSep = false;
17926         boolean onlyHistory = false;
17927         boolean printedAnything = false;
17928
17929         if ("history".equals(dumpPackage)) {
17930             if (opti < args.length && "-s".equals(args[opti])) {
17931                 dumpAll = false;
17932             }
17933             onlyHistory = true;
17934             dumpPackage = null;
17935         }
17936
17937         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
17938         if (!onlyHistory && dumpAll) {
17939             if (mRegisteredReceivers.size() > 0) {
17940                 boolean printed = false;
17941                 Iterator it = mRegisteredReceivers.values().iterator();
17942                 while (it.hasNext()) {
17943                     ReceiverList r = (ReceiverList)it.next();
17944                     if (dumpPackage != null && (r.app == null ||
17945                             !dumpPackage.equals(r.app.info.packageName))) {
17946                         continue;
17947                     }
17948                     if (!printed) {
17949                         pw.println("  Registered Receivers:");
17950                         needSep = true;
17951                         printed = true;
17952                         printedAnything = true;
17953                     }
17954                     pw.print("  * "); pw.println(r);
17955                     r.dump(pw, "    ");
17956                 }
17957             }
17958
17959             if (mReceiverResolver.dump(pw, needSep ?
17960                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
17961                     "    ", dumpPackage, false, false)) {
17962                 needSep = true;
17963                 printedAnything = true;
17964             }
17965         }
17966
17967         for (BroadcastQueue q : mBroadcastQueues) {
17968             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17969             printedAnything |= needSep;
17970         }
17971
17972         needSep = true;
17973
17974         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17975             for (int user=0; user<mStickyBroadcasts.size(); user++) {
17976                 if (needSep) {
17977                     pw.println();
17978                 }
17979                 needSep = true;
17980                 printedAnything = true;
17981                 pw.print("  Sticky broadcasts for user ");
17982                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
17983                 StringBuilder sb = new StringBuilder(128);
17984                 for (Map.Entry<String, ArrayList<Intent>> ent
17985                         : mStickyBroadcasts.valueAt(user).entrySet()) {
17986                     pw.print("  * Sticky action "); pw.print(ent.getKey());
17987                     if (dumpAll) {
17988                         pw.println(":");
17989                         ArrayList<Intent> intents = ent.getValue();
17990                         final int N = intents.size();
17991                         for (int i=0; i<N; i++) {
17992                             sb.setLength(0);
17993                             sb.append("    Intent: ");
17994                             intents.get(i).toShortString(sb, false, true, false, false);
17995                             pw.println(sb.toString());
17996                             Bundle bundle = intents.get(i).getExtras();
17997                             if (bundle != null) {
17998                                 pw.print("      ");
17999                                 pw.println(bundle.toString());
18000                             }
18001                         }
18002                     } else {
18003                         pw.println("");
18004                     }
18005                 }
18006             }
18007         }
18008
18009         if (!onlyHistory && dumpAll) {
18010             pw.println();
18011             for (BroadcastQueue queue : mBroadcastQueues) {
18012                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
18013                         + queue.mBroadcastsScheduled);
18014             }
18015             pw.println("  mHandler:");
18016             mHandler.dump(new PrintWriterPrinter(pw), "    ");
18017             needSep = true;
18018             printedAnything = true;
18019         }
18020
18021         if (!printedAnything) {
18022             pw.println("  (nothing)");
18023         }
18024     }
18025
18026     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18027             int opti, boolean dumpAll, String dumpPackage) {
18028         if (mCurBroadcastStats == null) {
18029             return;
18030         }
18031
18032         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
18033         final long now = SystemClock.elapsedRealtime();
18034         if (mLastBroadcastStats != null) {
18035             pw.print("  Last stats (from ");
18036             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
18037             pw.print(" to ");
18038             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
18039             pw.print(", ");
18040             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
18041                     - mLastBroadcastStats.mStartUptime, pw);
18042             pw.println(" uptime):");
18043             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
18044                 pw.println("    (nothing)");
18045             }
18046             pw.println();
18047         }
18048         pw.print("  Current stats (from ");
18049         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
18050         pw.print(" to now, ");
18051         TimeUtils.formatDuration(SystemClock.uptimeMillis()
18052                 - mCurBroadcastStats.mStartUptime, pw);
18053         pw.println(" uptime):");
18054         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
18055             pw.println("    (nothing)");
18056         }
18057     }
18058
18059     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18060             int opti, boolean fullCheckin, String dumpPackage) {
18061         if (mCurBroadcastStats == null) {
18062             return;
18063         }
18064
18065         if (mLastBroadcastStats != null) {
18066             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
18067             if (fullCheckin) {
18068                 mLastBroadcastStats = null;
18069                 return;
18070             }
18071         }
18072         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
18073         if (fullCheckin) {
18074             mCurBroadcastStats = null;
18075         }
18076     }
18077
18078     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18079             int opti, boolean dumpAll, String dumpPackage) {
18080         boolean needSep;
18081         boolean printedAnything = false;
18082
18083         ItemMatcher matcher = new ItemMatcher();
18084         matcher.build(args, opti);
18085
18086         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
18087
18088         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
18089         printedAnything |= needSep;
18090
18091         if (mLaunchingProviders.size() > 0) {
18092             boolean printed = false;
18093             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
18094                 ContentProviderRecord r = mLaunchingProviders.get(i);
18095                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
18096                     continue;
18097                 }
18098                 if (!printed) {
18099                     if (needSep) pw.println();
18100                     needSep = true;
18101                     pw.println("  Launching content providers:");
18102                     printed = true;
18103                     printedAnything = true;
18104                 }
18105                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
18106                         pw.println(r);
18107             }
18108         }
18109
18110         if (!printedAnything) {
18111             pw.println("  (nothing)");
18112         }
18113     }
18114
18115     @GuardedBy("this")
18116     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18117             int opti, boolean dumpAll, String dumpPackage) {
18118         boolean needSep = false;
18119         boolean printedAnything = false;
18120
18121         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
18122
18123         if (mGrantedUriPermissions.size() > 0) {
18124             boolean printed = false;
18125             int dumpUid = -2;
18126             if (dumpPackage != null) {
18127                 try {
18128                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
18129                             MATCH_ANY_USER, 0);
18130                 } catch (NameNotFoundException e) {
18131                     dumpUid = -1;
18132                 }
18133             }
18134             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
18135                 int uid = mGrantedUriPermissions.keyAt(i);
18136                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
18137                     continue;
18138                 }
18139                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
18140                 if (!printed) {
18141                     if (needSep) pw.println();
18142                     needSep = true;
18143                     pw.println("  Granted Uri Permissions:");
18144                     printed = true;
18145                     printedAnything = true;
18146                 }
18147                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
18148                 for (UriPermission perm : perms.values()) {
18149                     pw.print("    "); pw.println(perm);
18150                     if (dumpAll) {
18151                         perm.dump(pw, "      ");
18152                     }
18153                 }
18154             }
18155         }
18156
18157         if (!printedAnything) {
18158             pw.println("  (nothing)");
18159         }
18160     }
18161
18162     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18163             int opti, boolean dumpAll, String dumpPackage) {
18164         boolean printed = false;
18165
18166         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
18167
18168         if (mIntentSenderRecords.size() > 0) {
18169             // Organize these by package name, so they are easier to read.
18170             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
18171             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
18172             final Iterator<WeakReference<PendingIntentRecord>> it
18173                     = mIntentSenderRecords.values().iterator();
18174             while (it.hasNext()) {
18175                 WeakReference<PendingIntentRecord> ref = it.next();
18176                 PendingIntentRecord rec = ref != null ? ref.get() : null;
18177                 if (rec == null) {
18178                     weakRefs.add(ref);
18179                     continue;
18180                 }
18181                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
18182                     continue;
18183                 }
18184                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
18185                 if (list == null) {
18186                     list = new ArrayList<>();
18187                     byPackage.put(rec.key.packageName, list);
18188                 }
18189                 list.add(rec);
18190             }
18191             for (int i = 0; i < byPackage.size(); i++) {
18192                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
18193                 printed = true;
18194                 pw.print("  * "); pw.print(byPackage.keyAt(i));
18195                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
18196                 for (int j = 0; j < intents.size(); j++) {
18197                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
18198                     if (dumpAll) {
18199                         intents.get(j).dump(pw, "      ");
18200                     }
18201                 }
18202             }
18203             if (weakRefs.size() > 0) {
18204                 printed = true;
18205                 pw.println("  * WEAK REFS:");
18206                 for (int i = 0; i < weakRefs.size(); i++) {
18207                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
18208                 }
18209             }
18210         }
18211
18212         if (!printed) {
18213             pw.println("  (nothing)");
18214         }
18215     }
18216
18217     private static final int dumpProcessList(PrintWriter pw,
18218             ActivityManagerService service, List list,
18219             String prefix, String normalLabel, String persistentLabel,
18220             String dumpPackage) {
18221         int numPers = 0;
18222         final int N = list.size()-1;
18223         for (int i=N; i>=0; i--) {
18224             ProcessRecord r = (ProcessRecord)list.get(i);
18225             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
18226                 continue;
18227             }
18228             pw.println(String.format("%s%s #%2d: %s",
18229                     prefix, (r.persistent ? persistentLabel : normalLabel),
18230                     i, r.toString()));
18231             if (r.persistent) {
18232                 numPers++;
18233             }
18234         }
18235         return numPers;
18236     }
18237
18238     private static final ArrayList<Pair<ProcessRecord, Integer>>
18239         sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
18240         ArrayList<Pair<ProcessRecord, Integer>> list
18241                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
18242         for (int i=0; i<origList.size(); i++) {
18243             ProcessRecord r = origList.get(i);
18244             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
18245                 continue;
18246             }
18247             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
18248         }
18249
18250         Comparator<Pair<ProcessRecord, Integer>> comparator
18251                 = new Comparator<Pair<ProcessRecord, Integer>>() {
18252             @Override
18253             public int compare(Pair<ProcessRecord, Integer> object1,
18254                     Pair<ProcessRecord, Integer> object2) {
18255                 if (object1.first.setAdj != object2.first.setAdj) {
18256                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
18257                 }
18258                 if (object1.first.setProcState != object2.first.setProcState) {
18259                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
18260                 }
18261                 if (object1.second.intValue() != object2.second.intValue()) {
18262                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
18263                 }
18264                 return 0;
18265             }
18266         };
18267
18268         Collections.sort(list, comparator);
18269         return list;
18270     }
18271
18272     private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
18273             ActivityManagerService service, List<ProcessRecord> origList,
18274             boolean inclDetails, String dumpPackage) {
18275         ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
18276         if (list.isEmpty()) return false;
18277
18278         final long curUptime = SystemClock.uptimeMillis();
18279
18280         for (int i = list.size() - 1; i >= 0; i--) {
18281             ProcessRecord r = list.get(i).first;
18282             long token = proto.start(fieldId);
18283             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
18284             proto.write(ProcessOomProto.PERSISTENT, r.persistent);
18285             proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
18286             proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
18287             int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
18288             switch (r.setSchedGroup) {
18289                 case ProcessList.SCHED_GROUP_BACKGROUND:
18290                     schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
18291                     break;
18292                 case ProcessList.SCHED_GROUP_DEFAULT:
18293                     schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
18294                     break;
18295                 case ProcessList.SCHED_GROUP_TOP_APP:
18296                     schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
18297                     break;
18298                 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
18299                     schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
18300                     break;
18301             }
18302             if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
18303                 proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
18304             }
18305             if (r.foregroundActivities) {
18306                 proto.write(ProcessOomProto.ACTIVITIES, true);
18307             } else if (r.foregroundServices) {
18308                 proto.write(ProcessOomProto.SERVICES, true);
18309             }
18310             proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
18311             proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
18312             r.writeToProto(proto, ProcessOomProto.PROC);
18313             proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
18314             if (r.adjSource != null || r.adjTarget != null) {
18315                 if (r.adjTarget instanceof  ComponentName) {
18316                     ComponentName cn = (ComponentName) r.adjTarget;
18317                     cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
18318                 } else if (r.adjTarget != null) {
18319                     proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
18320                 }
18321                 if (r.adjSource instanceof ProcessRecord) {
18322                     ProcessRecord p = (ProcessRecord) r.adjSource;
18323                     p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
18324                 } else if (r.adjSource != null) {
18325                     proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
18326                 }
18327             }
18328             if (inclDetails) {
18329                 long detailToken = proto.start(ProcessOomProto.DETAIL);
18330                 proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
18331                 proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
18332                 proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
18333                 proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
18334                 proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
18335                 proto.write(ProcessOomProto.Detail.CURRENT_STATE,
18336                         ProcessList.makeProcStateProtoEnum(r.curProcState));
18337                 proto.write(ProcessOomProto.Detail.SET_STATE,
18338                         ProcessList.makeProcStateProtoEnum(r.setProcState));
18339                 proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
18340                         r.lastPss*1024, new StringBuilder()));
18341                 proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
18342                         r.lastSwapPss*1024, new StringBuilder()));
18343                 proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
18344                         r.lastCachedPss*1024, new StringBuilder()));
18345                 proto.write(ProcessOomProto.Detail.CACHED, r.cached);
18346                 proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
18347                 proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
18348
18349                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18350                     if (r.lastCpuTime != 0) {
18351                         long uptimeSince = curUptime - service.mLastPowerCheckUptime;
18352                         long timeUsed = r.curCpuTime - r.lastCpuTime;
18353                         long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
18354                         proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
18355                         proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
18356                         proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
18357                                 (100.0*timeUsed)/uptimeSince);
18358                         proto.end(cpuTimeToken);
18359                     }
18360                 }
18361                 proto.end(detailToken);
18362             }
18363             proto.end(token);
18364         }
18365
18366         return true;
18367     }
18368
18369     private static final boolean dumpProcessOomList(PrintWriter pw,
18370             ActivityManagerService service, List<ProcessRecord> origList,
18371             String prefix, String normalLabel, String persistentLabel,
18372             boolean inclDetails, String dumpPackage) {
18373
18374         ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
18375         if (list.isEmpty()) return false;
18376
18377         final long curUptime = SystemClock.uptimeMillis();
18378         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
18379
18380         for (int i=list.size()-1; i>=0; i--) {
18381             ProcessRecord r = list.get(i).first;
18382             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
18383             char schedGroup;
18384             switch (r.setSchedGroup) {
18385                 case ProcessList.SCHED_GROUP_BACKGROUND:
18386                     schedGroup = 'B';
18387                     break;
18388                 case ProcessList.SCHED_GROUP_DEFAULT:
18389                     schedGroup = 'F';
18390                     break;
18391                 case ProcessList.SCHED_GROUP_TOP_APP:
18392                     schedGroup = 'T';
18393                     break;
18394                 case ProcessList.SCHED_GROUP_RESTRICTED:
18395                     schedGroup = 'R';
18396                     break;
18397                 default:
18398                     schedGroup = '?';
18399                     break;
18400             }
18401             char foreground;
18402             if (r.foregroundActivities) {
18403                 foreground = 'A';
18404             } else if (r.foregroundServices) {
18405                 foreground = 'S';
18406             } else {
18407                 foreground = ' ';
18408             }
18409             String procState = ProcessList.makeProcStateString(r.curProcState);
18410             pw.print(prefix);
18411             pw.print(r.persistent ? persistentLabel : normalLabel);
18412             pw.print(" #");
18413             int num = (origList.size()-1)-list.get(i).second;
18414             if (num < 10) pw.print(' ');
18415             pw.print(num);
18416             pw.print(": ");
18417             pw.print(oomAdj);
18418             pw.print(' ');
18419             pw.print(schedGroup);
18420             pw.print('/');
18421             pw.print(foreground);
18422             pw.print('/');
18423             pw.print(procState);
18424             pw.print(" trm:");
18425             if (r.trimMemoryLevel < 10) pw.print(' ');
18426             pw.print(r.trimMemoryLevel);
18427             pw.print(' ');
18428             pw.print(r.toShortString());
18429             pw.print(" (");
18430             pw.print(r.adjType);
18431             pw.println(')');
18432             if (r.adjSource != null || r.adjTarget != null) {
18433                 pw.print(prefix);
18434                 pw.print("    ");
18435                 if (r.adjTarget instanceof ComponentName) {
18436                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
18437                 } else if (r.adjTarget != null) {
18438                     pw.print(r.adjTarget.toString());
18439                 } else {
18440                     pw.print("{null}");
18441                 }
18442                 pw.print("<=");
18443                 if (r.adjSource instanceof ProcessRecord) {
18444                     pw.print("Proc{");
18445                     pw.print(((ProcessRecord)r.adjSource).toShortString());
18446                     pw.println("}");
18447                 } else if (r.adjSource != null) {
18448                     pw.println(r.adjSource.toString());
18449                 } else {
18450                     pw.println("{null}");
18451                 }
18452             }
18453             if (inclDetails) {
18454                 pw.print(prefix);
18455                 pw.print("    ");
18456                 pw.print("oom: max="); pw.print(r.maxAdj);
18457                 pw.print(" curRaw="); pw.print(r.curRawAdj);
18458                 pw.print(" setRaw="); pw.print(r.setRawAdj);
18459                 pw.print(" cur="); pw.print(r.curAdj);
18460                 pw.print(" set="); pw.println(r.setAdj);
18461                 pw.print(prefix);
18462                 pw.print("    ");
18463                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
18464                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
18465                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
18466                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
18467                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
18468                 pw.println();
18469                 pw.print(prefix);
18470                 pw.print("    ");
18471                 pw.print("cached="); pw.print(r.cached);
18472                 pw.print(" empty="); pw.print(r.empty);
18473                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
18474
18475                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18476                     if (r.lastCpuTime != 0) {
18477                         long timeUsed = r.curCpuTime - r.lastCpuTime;
18478                         pw.print(prefix);
18479                         pw.print("    ");
18480                         pw.print("run cpu over ");
18481                         TimeUtils.formatDuration(uptimeSince, pw);
18482                         pw.print(" used ");
18483                         TimeUtils.formatDuration(timeUsed, pw);
18484                         pw.print(" (");
18485                         pw.print((timeUsed*100)/uptimeSince);
18486                         pw.println("%)");
18487                     }
18488                 }
18489             }
18490         }
18491         return true;
18492     }
18493
18494     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
18495             String[] args) {
18496         ArrayList<ProcessRecord> procs;
18497         synchronized (this) {
18498             if (args != null && args.length > start
18499                     && args[start].charAt(0) != '-') {
18500                 procs = new ArrayList<ProcessRecord>();
18501                 int pid = -1;
18502                 try {
18503                     pid = Integer.parseInt(args[start]);
18504                 } catch (NumberFormatException e) {
18505                 }
18506                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18507                     ProcessRecord proc = mLruProcesses.get(i);
18508                     if (proc.pid > 0 && proc.pid == pid) {
18509                         procs.add(proc);
18510                     } else if (allPkgs && proc.pkgList != null
18511                             && proc.pkgList.containsKey(args[start])) {
18512                         procs.add(proc);
18513                     } else if (proc.processName.equals(args[start])) {
18514                         procs.add(proc);
18515                     }
18516                 }
18517                 if (procs.size() <= 0) {
18518                     return null;
18519                 }
18520             } else {
18521                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
18522             }
18523         }
18524         return procs;
18525     }
18526
18527     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
18528             PrintWriter pw, String[] args) {
18529         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18530         if (procs == null) {
18531             pw.println("No process found for: " + args[0]);
18532             return;
18533         }
18534
18535         long uptime = SystemClock.uptimeMillis();
18536         long realtime = SystemClock.elapsedRealtime();
18537         pw.println("Applications Graphics Acceleration Info:");
18538         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18539
18540         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18541             ProcessRecord r = procs.get(i);
18542             if (r.thread != null) {
18543                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
18544                 pw.flush();
18545                 try {
18546                     TransferPipe tp = new TransferPipe();
18547                     try {
18548                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
18549                         tp.go(fd);
18550                     } finally {
18551                         tp.kill();
18552                     }
18553                 } catch (IOException e) {
18554                     pw.println("Failure while dumping the app: " + r);
18555                     pw.flush();
18556                 } catch (RemoteException e) {
18557                     pw.println("Got a RemoteException while dumping the app " + r);
18558                     pw.flush();
18559                 }
18560             }
18561         }
18562     }
18563
18564     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
18565         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18566         if (procs == null) {
18567             pw.println("No process found for: " + args[0]);
18568             return;
18569         }
18570
18571         pw.println("Applications Database Info:");
18572
18573         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18574             ProcessRecord r = procs.get(i);
18575             if (r.thread != null) {
18576                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
18577                 pw.flush();
18578                 try {
18579                     TransferPipe tp = new TransferPipe();
18580                     try {
18581                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
18582                         tp.go(fd);
18583                     } finally {
18584                         tp.kill();
18585                     }
18586                 } catch (IOException e) {
18587                     pw.println("Failure while dumping the app: " + r);
18588                     pw.flush();
18589                 } catch (RemoteException e) {
18590                     pw.println("Got a RemoteException while dumping the app " + r);
18591                     pw.flush();
18592                 }
18593             }
18594         }
18595     }
18596
18597     final static class MemItem {
18598         final boolean isProc;
18599         final String label;
18600         final String shortLabel;
18601         final long pss;
18602         final long swapPss;
18603         final int id;
18604         final boolean hasActivities;
18605         ArrayList<MemItem> subitems;
18606
18607         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
18608                 boolean _hasActivities) {
18609             isProc = true;
18610             label = _label;
18611             shortLabel = _shortLabel;
18612             pss = _pss;
18613             swapPss = _swapPss;
18614             id = _id;
18615             hasActivities = _hasActivities;
18616         }
18617
18618         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
18619             isProc = false;
18620             label = _label;
18621             shortLabel = _shortLabel;
18622             pss = _pss;
18623             swapPss = _swapPss;
18624             id = _id;
18625             hasActivities = false;
18626         }
18627     }
18628
18629     private static void sortMemItems(List<MemItem> items) {
18630         Collections.sort(items, new Comparator<MemItem>() {
18631             @Override
18632             public int compare(MemItem lhs, MemItem rhs) {
18633                 if (lhs.pss < rhs.pss) {
18634                     return 1;
18635                 } else if (lhs.pss > rhs.pss) {
18636                     return -1;
18637                 }
18638                 return 0;
18639             }
18640         });
18641     }
18642
18643     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
18644             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
18645         if (sort && !isCompact) {
18646             sortMemItems(items);
18647         }
18648
18649         for (int i=0; i<items.size(); i++) {
18650             MemItem mi = items.get(i);
18651             if (!isCompact) {
18652                 if (dumpSwapPss) {
18653                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
18654                             mi.label, stringifyKBSize(mi.swapPss));
18655                 } else {
18656                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
18657                 }
18658             } else if (mi.isProc) {
18659                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
18660                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
18661                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
18662                 pw.println(mi.hasActivities ? ",a" : ",e");
18663             } else {
18664                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
18665                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
18666             }
18667             if (mi.subitems != null) {
18668                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
18669                         true, isCompact, dumpSwapPss);
18670             }
18671         }
18672     }
18673
18674     static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
18675             ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
18676         if (sort) {
18677             sortMemItems(items);
18678         }
18679
18680         for (int i=0; i<items.size(); i++) {
18681             MemItem mi = items.get(i);
18682             final long token = proto.start(fieldId);
18683
18684             proto.write(MemInfoDumpProto.MemItem.TAG, tag);
18685             proto.write(MemInfoDumpProto.MemItem.LABEL, mi.shortLabel);
18686             proto.write(MemInfoDumpProto.MemItem.IS_PROC, mi.isProc);
18687             proto.write(MemInfoDumpProto.MemItem.ID, mi.id);
18688             proto.write(MemInfoDumpProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
18689             proto.write(MemInfoDumpProto.MemItem.PSS_KB, mi.pss);
18690             if (dumpSwapPss) {
18691                 proto.write(MemInfoDumpProto.MemItem.SWAP_PSS_KB, mi.swapPss);
18692             }
18693             if (mi.subitems != null) {
18694                 dumpMemItems(proto, MemInfoDumpProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
18695                         true, dumpSwapPss);
18696             }
18697             proto.end(token);
18698         }
18699     }
18700
18701     // These are in KB.
18702     static final long[] DUMP_MEM_BUCKETS = new long[] {
18703         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
18704         120*1024, 160*1024, 200*1024,
18705         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
18706         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
18707     };
18708
18709     static final void appendMemBucket(StringBuilder out, long memKB, String label,
18710             boolean stackLike) {
18711         int start = label.lastIndexOf('.');
18712         if (start >= 0) start++;
18713         else start = 0;
18714         int end = label.length();
18715         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
18716             if (DUMP_MEM_BUCKETS[i] >= memKB) {
18717                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
18718                 out.append(bucket);
18719                 out.append(stackLike ? "MB." : "MB ");
18720                 out.append(label, start, end);
18721                 return;
18722             }
18723         }
18724         out.append(memKB/1024);
18725         out.append(stackLike ? "MB." : "MB ");
18726         out.append(label, start, end);
18727     }
18728
18729     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
18730             ProcessList.NATIVE_ADJ,
18731             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
18732             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
18733             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
18734             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
18735             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
18736             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
18737     };
18738     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
18739             "Native",
18740             "System", "Persistent", "Persistent Service", "Foreground",
18741             "Visible", "Perceptible",
18742             "Heavy Weight", "Backup",
18743             "A Services", "Home",
18744             "Previous", "B Services", "Cached"
18745     };
18746     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
18747             "native",
18748             "sys", "pers", "persvc", "fore",
18749             "vis", "percept",
18750             "heavy", "backup",
18751             "servicea", "home",
18752             "prev", "serviceb", "cached"
18753     };
18754
18755     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
18756             long realtime, boolean isCheckinRequest, boolean isCompact) {
18757         if (isCompact) {
18758             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
18759         }
18760         if (isCheckinRequest || isCompact) {
18761             // short checkin version
18762             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
18763         } else {
18764             pw.println("Applications Memory Usage (in Kilobytes):");
18765             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18766         }
18767     }
18768
18769     private static final int KSM_SHARED = 0;
18770     private static final int KSM_SHARING = 1;
18771     private static final int KSM_UNSHARED = 2;
18772     private static final int KSM_VOLATILE = 3;
18773
18774     private final long[] getKsmInfo() {
18775         long[] longOut = new long[4];
18776         final int[] SINGLE_LONG_FORMAT = new int[] {
18777             PROC_SPACE_TERM| PROC_OUT_LONG
18778         };
18779         long[] longTmp = new long[1];
18780         readProcFile("/sys/kernel/mm/ksm/pages_shared",
18781                 SINGLE_LONG_FORMAT, null, longTmp, null);
18782         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18783         longTmp[0] = 0;
18784         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
18785                 SINGLE_LONG_FORMAT, null, longTmp, null);
18786         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18787         longTmp[0] = 0;
18788         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
18789                 SINGLE_LONG_FORMAT, null, longTmp, null);
18790         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18791         longTmp[0] = 0;
18792         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
18793                 SINGLE_LONG_FORMAT, null, longTmp, null);
18794         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18795         return longOut;
18796     }
18797
18798     private static String stringifySize(long size, int order) {
18799         Locale locale = Locale.US;
18800         switch (order) {
18801             case 1:
18802                 return String.format(locale, "%,13d", size);
18803             case 1024:
18804                 return String.format(locale, "%,9dK", size / 1024);
18805             case 1024 * 1024:
18806                 return String.format(locale, "%,5dM", size / 1024 / 1024);
18807             case 1024 * 1024 * 1024:
18808                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
18809             default:
18810                 throw new IllegalArgumentException("Invalid size order");
18811         }
18812     }
18813
18814     private static String stringifyKBSize(long size) {
18815         return stringifySize(size * 1024, 1024);
18816     }
18817
18818     // Update this version number if you change the 'compact' format.
18819     private static final int MEMINFO_COMPACT_VERSION = 1;
18820
18821     private static class MemoryUsageDumpOptions {
18822         boolean dumpDetails;
18823         boolean dumpFullDetails;
18824         boolean dumpDalvik;
18825         boolean dumpSummaryOnly;
18826         boolean dumpUnreachable;
18827         boolean oomOnly;
18828         boolean isCompact;
18829         boolean localOnly;
18830         boolean packages;
18831         boolean isCheckinRequest;
18832         boolean dumpSwapPss;
18833         boolean dumpProto;
18834     }
18835
18836     final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18837             String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
18838         MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
18839         opts.dumpDetails = false;
18840         opts.dumpFullDetails = false;
18841         opts.dumpDalvik = false;
18842         opts.dumpSummaryOnly = false;
18843         opts.dumpUnreachable = false;
18844         opts.oomOnly = false;
18845         opts.isCompact = false;
18846         opts.localOnly = false;
18847         opts.packages = false;
18848         opts.isCheckinRequest = false;
18849         opts.dumpSwapPss = false;
18850         opts.dumpProto = asProto;
18851
18852         int opti = 0;
18853         while (opti < args.length) {
18854             String opt = args[opti];
18855             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18856                 break;
18857             }
18858             opti++;
18859             if ("-a".equals(opt)) {
18860                 opts.dumpDetails = true;
18861                 opts.dumpFullDetails = true;
18862                 opts.dumpDalvik = true;
18863                 opts.dumpSwapPss = true;
18864             } else if ("-d".equals(opt)) {
18865                 opts.dumpDalvik = true;
18866             } else if ("-c".equals(opt)) {
18867                 opts.isCompact = true;
18868             } else if ("-s".equals(opt)) {
18869                 opts.dumpDetails = true;
18870                 opts.dumpSummaryOnly = true;
18871             } else if ("-S".equals(opt)) {
18872                 opts.dumpSwapPss = true;
18873             } else if ("--unreachable".equals(opt)) {
18874                 opts.dumpUnreachable = true;
18875             } else if ("--oom".equals(opt)) {
18876                 opts.oomOnly = true;
18877             } else if ("--local".equals(opt)) {
18878                 opts.localOnly = true;
18879             } else if ("--package".equals(opt)) {
18880                 opts.packages = true;
18881             } else if ("--checkin".equals(opt)) {
18882                 opts.isCheckinRequest = true;
18883             } else if ("--proto".equals(opt)) {
18884                 opts.dumpProto = true;
18885
18886             } else if ("-h".equals(opt)) {
18887                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
18888                 pw.println("  -a: include all available information for each process.");
18889                 pw.println("  -d: include dalvik details.");
18890                 pw.println("  -c: dump in a compact machine-parseable representation.");
18891                 pw.println("  -s: dump only summary of application memory usage.");
18892                 pw.println("  -S: dump also SwapPss.");
18893                 pw.println("  --oom: only show processes organized by oom adj.");
18894                 pw.println("  --local: only collect details locally, don't call process.");
18895                 pw.println("  --package: interpret process arg as package, dumping all");
18896                 pw.println("             processes that have loaded that package.");
18897                 pw.println("  --checkin: dump data for a checkin");
18898                 pw.println("  --proto: dump data to proto");
18899                 pw.println("If [process] is specified it can be the name or ");
18900                 pw.println("pid of a specific process to dump.");
18901                 return;
18902             } else {
18903                 pw.println("Unknown argument: " + opt + "; use -h for help");
18904             }
18905         }
18906
18907         String[] innerArgs = new String[args.length-opti];
18908         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18909
18910         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18911         if (opts.dumpProto) {
18912             dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18913         } else {
18914             dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
18915         }
18916     }
18917
18918     private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18919             MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18920             ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
18921         long uptime = SystemClock.uptimeMillis();
18922         long realtime = SystemClock.elapsedRealtime();
18923         final long[] tmpLong = new long[1];
18924
18925         if (procs == null) {
18926             // No Java processes.  Maybe they want to print a native process.
18927             String proc = "N/A";
18928             if (innerArgs.length > 0) {
18929                 proc = innerArgs[0];
18930                 if (proc.charAt(0) != '-') {
18931                     ArrayList<ProcessCpuTracker.Stats> nativeProcs
18932                             = new ArrayList<ProcessCpuTracker.Stats>();
18933                     updateCpuStatsNow();
18934                     int findPid = -1;
18935                     try {
18936                         findPid = Integer.parseInt(innerArgs[0]);
18937                     } catch (NumberFormatException e) {
18938                     }
18939                     synchronized (mProcessCpuTracker) {
18940                         final int N = mProcessCpuTracker.countStats();
18941                         for (int i=0; i<N; i++) {
18942                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18943                             if (st.pid == findPid || (st.baseName != null
18944                                     && st.baseName.equals(innerArgs[0]))) {
18945                                 nativeProcs.add(st);
18946                             }
18947                         }
18948                     }
18949                     if (nativeProcs.size() > 0) {
18950                         dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
18951                                 opts.isCheckinRequest, opts.isCompact);
18952                         Debug.MemoryInfo mi = null;
18953                         for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18954                             final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18955                             final int pid = r.pid;
18956                             if (!opts.isCheckinRequest && opts.dumpDetails) {
18957                                 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
18958                             }
18959                             if (mi == null) {
18960                                 mi = new Debug.MemoryInfo();
18961                             }
18962                             if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18963                                 Debug.getMemoryInfo(pid, mi);
18964                             } else {
18965                                 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18966                                 mi.dalvikPrivateDirty = (int)tmpLong[0];
18967                             }
18968                             ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
18969                                     opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18970                                     pid, r.baseName, 0, 0, 0, 0, 0, 0);
18971                             if (opts.isCheckinRequest) {
18972                                 pw.println();
18973                             }
18974                         }
18975                         return;
18976                     }
18977                 }
18978             }
18979             pw.println("No process found for: " + proc);
18980             return;
18981         }
18982
18983         if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18984             opts.dumpDetails = true;
18985         }
18986
18987         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
18988
18989         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18990         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18991         long nativePss = 0;
18992         long nativeSwapPss = 0;
18993         long dalvikPss = 0;
18994         long dalvikSwapPss = 0;
18995         long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18996                 EmptyArray.LONG;
18997         long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18998                 EmptyArray.LONG;
18999         long otherPss = 0;
19000         long otherSwapPss = 0;
19001         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19002         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19003
19004         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19005         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19006         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
19007                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
19008
19009         long totalPss = 0;
19010         long totalSwapPss = 0;
19011         long cachedPss = 0;
19012         long cachedSwapPss = 0;
19013         boolean hasSwapPss = false;
19014
19015         Debug.MemoryInfo mi = null;
19016         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
19017             final ProcessRecord r = procs.get(i);
19018             final IApplicationThread thread;
19019             final int pid;
19020             final int oomAdj;
19021             final boolean hasActivities;
19022             synchronized (this) {
19023                 thread = r.thread;
19024                 pid = r.pid;
19025                 oomAdj = r.getSetAdjWithServices();
19026                 hasActivities = r.activities.size() > 0;
19027             }
19028             if (thread != null) {
19029                 if (!opts.isCheckinRequest && opts.dumpDetails) {
19030                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
19031                 }
19032                 if (mi == null) {
19033                     mi = new Debug.MemoryInfo();
19034                 }
19035                 final int reportType;
19036                 final long startTime;
19037                 final long endTime;
19038                 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19039                     reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
19040                     startTime = SystemClock.currentThreadTimeMillis();
19041                     Debug.getMemoryInfo(pid, mi);
19042                     endTime = SystemClock.currentThreadTimeMillis();
19043                     hasSwapPss = mi.hasSwappedOutPss;
19044                 } else {
19045                     reportType = ProcessStats.ADD_PSS_EXTERNAL;
19046                     startTime = SystemClock.currentThreadTimeMillis();
19047                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
19048                     endTime = SystemClock.currentThreadTimeMillis();
19049                     mi.dalvikPrivateDirty = (int)tmpLong[0];
19050                 }
19051                 if (opts.dumpDetails) {
19052                     if (opts.localOnly) {
19053                         ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
19054                                 opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
19055                         if (opts.isCheckinRequest) {
19056                             pw.println();
19057                         }
19058                     } else {
19059                         pw.flush();
19060                         try {
19061                             TransferPipe tp = new TransferPipe();
19062                             try {
19063                                 thread.dumpMemInfo(tp.getWriteFd(),
19064                                         mi, opts.isCheckinRequest, opts.dumpFullDetails,
19065                                         opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
19066                                 tp.go(fd, opts.dumpUnreachable ? 30000 : 5000);
19067                             } finally {
19068                                 tp.kill();
19069                             }
19070                         } catch (IOException e) {
19071                             if (!opts.isCheckinRequest) {
19072                                 pw.println("Got IoException! " + e);
19073                                 pw.flush();
19074                             }
19075                         } catch (RemoteException e) {
19076                             if (!opts.isCheckinRequest) {
19077                                 pw.println("Got RemoteException! " + e);
19078                                 pw.flush();
19079                             }
19080                         }
19081                     }
19082                 }
19083
19084                 final long myTotalPss = mi.getTotalPss();
19085                 final long myTotalUss = mi.getTotalUss();
19086                 final long myTotalRss = mi.getTotalRss();
19087                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19088
19089                 synchronized (this) {
19090                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
19091                         // Record this for posterity if the process has been stable.
19092                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
19093                                 reportType, endTime-startTime, r.pkgList);
19094                     }
19095                 }
19096
19097                 if (!opts.isCheckinRequest && mi != null) {
19098                     totalPss += myTotalPss;
19099                     totalSwapPss += myTotalSwapPss;
19100                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19101                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19102                             myTotalSwapPss, pid, hasActivities);
19103                     procMems.add(pssItem);
19104                     procMemsMap.put(pid, pssItem);
19105
19106                     nativePss += mi.nativePss;
19107                     nativeSwapPss += mi.nativeSwappedOutPss;
19108                     dalvikPss += mi.dalvikPss;
19109                     dalvikSwapPss += mi.dalvikSwappedOutPss;
19110                     for (int j=0; j<dalvikSubitemPss.length; j++) {
19111                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19112                         dalvikSubitemSwapPss[j] +=
19113                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19114                     }
19115                     otherPss += mi.otherPss;
19116                     otherSwapPss += mi.otherSwappedOutPss;
19117                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19118                         long mem = mi.getOtherPss(j);
19119                         miscPss[j] += mem;
19120                         otherPss -= mem;
19121                         mem = mi.getOtherSwappedOutPss(j);
19122                         miscSwapPss[j] += mem;
19123                         otherSwapPss -= mem;
19124                     }
19125
19126                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19127                         cachedPss += myTotalPss;
19128                         cachedSwapPss += myTotalSwapPss;
19129                     }
19130
19131                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19132                         if (oomIndex == (oomPss.length - 1)
19133                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19134                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19135                             oomPss[oomIndex] += myTotalPss;
19136                             oomSwapPss[oomIndex] += myTotalSwapPss;
19137                             if (oomProcs[oomIndex] == null) {
19138                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
19139                             }
19140                             oomProcs[oomIndex].add(pssItem);
19141                             break;
19142                         }
19143                     }
19144                 }
19145             }
19146         }
19147
19148         long nativeProcTotalPss = 0;
19149
19150         if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
19151             // If we are showing aggregations, also look for native processes to
19152             // include so that our aggregations are more accurate.
19153             updateCpuStatsNow();
19154             mi = null;
19155             synchronized (mProcessCpuTracker) {
19156                 final int N = mProcessCpuTracker.countStats();
19157                 for (int i=0; i<N; i++) {
19158                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19159                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19160                         if (mi == null) {
19161                             mi = new Debug.MemoryInfo();
19162                         }
19163                         if (!brief && !opts.oomOnly) {
19164                             Debug.getMemoryInfo(st.pid, mi);
19165                         } else {
19166                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19167                             mi.nativePrivateDirty = (int)tmpLong[0];
19168                         }
19169
19170                         final long myTotalPss = mi.getTotalPss();
19171                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19172                         totalPss += myTotalPss;
19173                         totalSwapPss += myTotalSwapPss;
19174                         nativeProcTotalPss += myTotalPss;
19175
19176                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19177                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19178                         procMems.add(pssItem);
19179
19180                         nativePss += mi.nativePss;
19181                         nativeSwapPss += mi.nativeSwappedOutPss;
19182                         dalvikPss += mi.dalvikPss;
19183                         dalvikSwapPss += mi.dalvikSwappedOutPss;
19184                         for (int j=0; j<dalvikSubitemPss.length; j++) {
19185                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19186                             dalvikSubitemSwapPss[j] +=
19187                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19188                         }
19189                         otherPss += mi.otherPss;
19190                         otherSwapPss += mi.otherSwappedOutPss;
19191                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19192                             long mem = mi.getOtherPss(j);
19193                             miscPss[j] += mem;
19194                             otherPss -= mem;
19195                             mem = mi.getOtherSwappedOutPss(j);
19196                             miscSwapPss[j] += mem;
19197                             otherSwapPss -= mem;
19198                         }
19199                         oomPss[0] += myTotalPss;
19200                         oomSwapPss[0] += myTotalSwapPss;
19201                         if (oomProcs[0] == null) {
19202                             oomProcs[0] = new ArrayList<MemItem>();
19203                         }
19204                         oomProcs[0].add(pssItem);
19205                     }
19206                 }
19207             }
19208
19209             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19210
19211             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19212             final int dalvikId = -2;
19213             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19214             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19215             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19216                 String label = Debug.MemoryInfo.getOtherLabel(j);
19217                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19218             }
19219             if (dalvikSubitemPss.length > 0) {
19220                 // Add dalvik subitems.
19221                 for (MemItem memItem : catMems) {
19222                     int memItemStart = 0, memItemEnd = 0;
19223                     if (memItem.id == dalvikId) {
19224                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19225                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19226                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19227                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19228                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19229                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19230                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19231                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19232                     } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19233                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19234                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19235                     } else {
19236                         continue;  // No subitems, continue.
19237                     }
19238                     memItem.subitems = new ArrayList<MemItem>();
19239                     for (int j=memItemStart; j<=memItemEnd; j++) {
19240                         final String name = Debug.MemoryInfo.getOtherLabel(
19241                                 Debug.MemoryInfo.NUM_OTHER_STATS + j);
19242                         memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19243                                 dalvikSubitemSwapPss[j], j));
19244                     }
19245                 }
19246             }
19247
19248             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19249             for (int j=0; j<oomPss.length; j++) {
19250                 if (oomPss[j] != 0) {
19251                     String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19252                             : DUMP_MEM_OOM_LABEL[j];
19253                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19254                             DUMP_MEM_OOM_ADJ[j]);
19255                     item.subitems = oomProcs[j];
19256                     oomMems.add(item);
19257                 }
19258             }
19259
19260             opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19261             if (!brief && !opts.oomOnly && !opts.isCompact) {
19262                 pw.println();
19263                 pw.println("Total PSS by process:");
19264                 dumpMemItems(pw, "  ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
19265                 pw.println();
19266             }
19267             if (!opts.isCompact) {
19268                 pw.println("Total PSS by OOM adjustment:");
19269             }
19270             dumpMemItems(pw, "  ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
19271             if (!brief && !opts.oomOnly) {
19272                 PrintWriter out = categoryPw != null ? categoryPw : pw;
19273                 if (!opts.isCompact) {
19274                     out.println();
19275                     out.println("Total PSS by category:");
19276                 }
19277                 dumpMemItems(out, "  ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
19278             }
19279             if (!opts.isCompact) {
19280                 pw.println();
19281             }
19282             MemInfoReader memInfo = new MemInfoReader();
19283             memInfo.readMemInfo();
19284             if (nativeProcTotalPss > 0) {
19285                 synchronized (this) {
19286                     final long cachedKb = memInfo.getCachedSizeKb();
19287                     final long freeKb = memInfo.getFreeSizeKb();
19288                     final long zramKb = memInfo.getZramTotalSizeKb();
19289                     final long kernelKb = memInfo.getKernelUsedSizeKb();
19290                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19291                             kernelKb*1024, nativeProcTotalPss*1024);
19292                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19293                             nativeProcTotalPss);
19294                 }
19295             }
19296             if (!brief) {
19297                 if (!opts.isCompact) {
19298                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
19299                     pw.print(" (status ");
19300                     switch (mLastMemoryLevel) {
19301                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
19302                             pw.println("normal)");
19303                             break;
19304                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
19305                             pw.println("moderate)");
19306                             break;
19307                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
19308                             pw.println("low)");
19309                             break;
19310                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19311                             pw.println("critical)");
19312                             break;
19313                         default:
19314                             pw.print(mLastMemoryLevel);
19315                             pw.println(")");
19316                             break;
19317                     }
19318                     pw.print(" Free RAM: ");
19319                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19320                             + memInfo.getFreeSizeKb()));
19321                     pw.print(" (");
19322                     pw.print(stringifyKBSize(cachedPss));
19323                     pw.print(" cached pss + ");
19324                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
19325                     pw.print(" cached kernel + ");
19326                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
19327                     pw.println(" free)");
19328                 } else {
19329                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
19330                     pw.print(cachedPss + memInfo.getCachedSizeKb()
19331                             + memInfo.getFreeSizeKb()); pw.print(",");
19332                     pw.println(totalPss - cachedPss);
19333                 }
19334             }
19335             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19336                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19337                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19338             if (!opts.isCompact) {
19339                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
19340                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
19341                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
19342                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
19343                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
19344             } else {
19345                 pw.print("lostram,"); pw.println(lostRAM);
19346             }
19347             if (!brief) {
19348                 if (memInfo.getZramTotalSizeKb() != 0) {
19349                     if (!opts.isCompact) {
19350                         pw.print("     ZRAM: ");
19351                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
19352                                 pw.print(" physical used for ");
19353                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
19354                                         - memInfo.getSwapFreeSizeKb()));
19355                                 pw.print(" in swap (");
19356                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
19357                                 pw.println(" total swap)");
19358                     } else {
19359                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
19360                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
19361                                 pw.println(memInfo.getSwapFreeSizeKb());
19362                     }
19363                 }
19364                 final long[] ksm = getKsmInfo();
19365                 if (!opts.isCompact) {
19366                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19367                             || ksm[KSM_VOLATILE] != 0) {
19368                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
19369                                 pw.print(" saved from shared ");
19370                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
19371                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
19372                                 pw.print(" unshared; ");
19373                                 pw.print(stringifyKBSize(
19374                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
19375                     }
19376                     pw.print("   Tuning: ");
19377                     pw.print(ActivityManager.staticGetMemoryClass());
19378                     pw.print(" (large ");
19379                     pw.print(ActivityManager.staticGetLargeMemoryClass());
19380                     pw.print("), oom ");
19381                     pw.print(stringifySize(
19382                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
19383                     pw.print(", restore limit ");
19384                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
19385                     if (ActivityManager.isLowRamDeviceStatic()) {
19386                         pw.print(" (low-ram)");
19387                     }
19388                     if (ActivityManager.isHighEndGfx()) {
19389                         pw.print(" (high-end-gfx)");
19390                     }
19391                     pw.println();
19392                 } else {
19393                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
19394                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
19395                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
19396                     pw.print("tuning,");
19397                     pw.print(ActivityManager.staticGetMemoryClass());
19398                     pw.print(',');
19399                     pw.print(ActivityManager.staticGetLargeMemoryClass());
19400                     pw.print(',');
19401                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
19402                     if (ActivityManager.isLowRamDeviceStatic()) {
19403                         pw.print(",low-ram");
19404                     }
19405                     if (ActivityManager.isHighEndGfx()) {
19406                         pw.print(",high-end-gfx");
19407                     }
19408                     pw.println();
19409                 }
19410             }
19411         }
19412     }
19413
19414     private final void dumpApplicationMemoryUsage(FileDescriptor fd,
19415             MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
19416             ArrayList<ProcessRecord> procs) {
19417         final long uptimeMs = SystemClock.uptimeMillis();
19418         final long realtimeMs = SystemClock.elapsedRealtime();
19419         final long[] tmpLong = new long[1];
19420
19421         if (procs == null) {
19422             // No Java processes.  Maybe they want to print a native process.
19423             String proc = "N/A";
19424             if (innerArgs.length > 0) {
19425                 proc = innerArgs[0];
19426                 if (proc.charAt(0) != '-') {
19427                     ArrayList<ProcessCpuTracker.Stats> nativeProcs
19428                             = new ArrayList<ProcessCpuTracker.Stats>();
19429                     updateCpuStatsNow();
19430                     int findPid = -1;
19431                     try {
19432                         findPid = Integer.parseInt(innerArgs[0]);
19433                     } catch (NumberFormatException e) {
19434                     }
19435                     synchronized (mProcessCpuTracker) {
19436                         final int N = mProcessCpuTracker.countStats();
19437                         for (int i=0; i<N; i++) {
19438                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19439                             if (st.pid == findPid || (st.baseName != null
19440                                     && st.baseName.equals(innerArgs[0]))) {
19441                                 nativeProcs.add(st);
19442                             }
19443                         }
19444                     }
19445                     if (nativeProcs.size() > 0) {
19446                         ProtoOutputStream proto = new ProtoOutputStream(fd);
19447
19448                         proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19449                         proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19450                         Debug.MemoryInfo mi = null;
19451                         for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
19452                             final ProcessCpuTracker.Stats r = nativeProcs.get(i);
19453                             final int pid = r.pid;
19454                             final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES);
19455
19456                             proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19457                             proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName);
19458
19459                             if (mi == null) {
19460                                 mi = new Debug.MemoryInfo();
19461                             }
19462                             if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19463                                 Debug.getMemoryInfo(pid, mi);
19464                             } else {
19465                                 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
19466                                 mi.dalvikPrivateDirty = (int)tmpLong[0];
19467                             }
19468                             ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19469                                     opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19470
19471                             proto.end(nToken);
19472                         }
19473
19474                         proto.flush();
19475                         return;
19476                     }
19477                 }
19478             }
19479             Log.d(TAG, "No process found for: " + innerArgs[0]);
19480             return;
19481         }
19482
19483         if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
19484             opts.dumpDetails = true;
19485         }
19486
19487         ProtoOutputStream proto = new ProtoOutputStream(fd);
19488
19489         proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19490         proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19491
19492         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
19493         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
19494         long nativePss = 0;
19495         long nativeSwapPss = 0;
19496         long dalvikPss = 0;
19497         long dalvikSwapPss = 0;
19498         long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19499                 EmptyArray.LONG;
19500         long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19501                 EmptyArray.LONG;
19502         long otherPss = 0;
19503         long otherSwapPss = 0;
19504         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19505         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19506
19507         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19508         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19509         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
19510                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
19511
19512         long totalPss = 0;
19513         long totalSwapPss = 0;
19514         long cachedPss = 0;
19515         long cachedSwapPss = 0;
19516         boolean hasSwapPss = false;
19517
19518         Debug.MemoryInfo mi = null;
19519         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
19520             final ProcessRecord r = procs.get(i);
19521             final IApplicationThread thread;
19522             final int pid;
19523             final int oomAdj;
19524             final boolean hasActivities;
19525             synchronized (this) {
19526                 thread = r.thread;
19527                 pid = r.pid;
19528                 oomAdj = r.getSetAdjWithServices();
19529                 hasActivities = r.activities.size() > 0;
19530             }
19531             if (thread == null) {
19532                 continue;
19533             }
19534             if (mi == null) {
19535                 mi = new Debug.MemoryInfo();
19536             }
19537             final int reportType;
19538             final long startTime;
19539             final long endTime;
19540             if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19541                 reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
19542                 startTime = SystemClock.currentThreadTimeMillis();
19543                 Debug.getMemoryInfo(pid, mi);
19544                 endTime = SystemClock.currentThreadTimeMillis();
19545                 hasSwapPss = mi.hasSwappedOutPss;
19546             } else {
19547                 reportType = ProcessStats.ADD_PSS_EXTERNAL;
19548                 startTime = SystemClock.currentThreadTimeMillis();
19549                 mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
19550                 endTime = SystemClock.currentThreadTimeMillis();
19551                 mi.dalvikPrivateDirty = (int) tmpLong[0];
19552             }
19553             if (opts.dumpDetails) {
19554                 if (opts.localOnly) {
19555                     final long aToken = proto.start(MemInfoDumpProto.APP_PROCESSES);
19556                     final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
19557                     proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19558                     proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.processName);
19559                     ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19560                             opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19561                     proto.end(mToken);
19562                     proto.end(aToken);
19563                 } else {
19564                     try {
19565                         ByteTransferPipe tp = new ByteTransferPipe();
19566                         try {
19567                             thread.dumpMemInfoProto(tp.getWriteFd(),
19568                                 mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
19569                                 opts.dumpUnreachable, innerArgs);
19570                             proto.write(MemInfoDumpProto.APP_PROCESSES, tp.get());
19571                         } finally {
19572                             tp.kill();
19573                         }
19574                     } catch (IOException e) {
19575                         Log.e(TAG, "Got IOException!", e);
19576                     } catch (RemoteException e) {
19577                         Log.e(TAG, "Got RemoteException!", e);
19578                     }
19579                 }
19580             }
19581
19582             final long myTotalPss = mi.getTotalPss();
19583             final long myTotalUss = mi.getTotalUss();
19584             final long myTotalRss = mi.getTotalRss();
19585             final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19586
19587             synchronized (this) {
19588                 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
19589                     // Record this for posterity if the process has been stable.
19590                     r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
19591                             reportType, endTime-startTime, r.pkgList);
19592                 }
19593             }
19594
19595             if (!opts.isCheckinRequest && mi != null) {
19596                 totalPss += myTotalPss;
19597                 totalSwapPss += myTotalSwapPss;
19598                 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19599                         (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19600                         myTotalSwapPss, pid, hasActivities);
19601                 procMems.add(pssItem);
19602                 procMemsMap.put(pid, pssItem);
19603
19604                 nativePss += mi.nativePss;
19605                 nativeSwapPss += mi.nativeSwappedOutPss;
19606                 dalvikPss += mi.dalvikPss;
19607                 dalvikSwapPss += mi.dalvikSwappedOutPss;
19608                 for (int j=0; j<dalvikSubitemPss.length; j++) {
19609                     dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19610                     dalvikSubitemSwapPss[j] +=
19611                             mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19612                 }
19613                 otherPss += mi.otherPss;
19614                 otherSwapPss += mi.otherSwappedOutPss;
19615                 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19616                     long mem = mi.getOtherPss(j);
19617                     miscPss[j] += mem;
19618                     otherPss -= mem;
19619                     mem = mi.getOtherSwappedOutPss(j);
19620                     miscSwapPss[j] += mem;
19621                     otherSwapPss -= mem;
19622                 }
19623
19624                 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19625                     cachedPss += myTotalPss;
19626                     cachedSwapPss += myTotalSwapPss;
19627                 }
19628
19629                 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19630                     if (oomIndex == (oomPss.length - 1)
19631                             || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19632                                     && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19633                         oomPss[oomIndex] += myTotalPss;
19634                         oomSwapPss[oomIndex] += myTotalSwapPss;
19635                         if (oomProcs[oomIndex] == null) {
19636                             oomProcs[oomIndex] = new ArrayList<MemItem>();
19637                         }
19638                         oomProcs[oomIndex].add(pssItem);
19639                         break;
19640                     }
19641                 }
19642             }
19643         }
19644
19645         long nativeProcTotalPss = 0;
19646
19647         if (procs.size() > 1 && !opts.packages) {
19648             // If we are showing aggregations, also look for native processes to
19649             // include so that our aggregations are more accurate.
19650             updateCpuStatsNow();
19651             mi = null;
19652             synchronized (mProcessCpuTracker) {
19653                 final int N = mProcessCpuTracker.countStats();
19654                 for (int i=0; i<N; i++) {
19655                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19656                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19657                         if (mi == null) {
19658                             mi = new Debug.MemoryInfo();
19659                         }
19660                         if (!brief && !opts.oomOnly) {
19661                             Debug.getMemoryInfo(st.pid, mi);
19662                         } else {
19663                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19664                             mi.nativePrivateDirty = (int)tmpLong[0];
19665                         }
19666
19667                         final long myTotalPss = mi.getTotalPss();
19668                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19669                         totalPss += myTotalPss;
19670                         nativeProcTotalPss += myTotalPss;
19671
19672                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19673                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19674                         procMems.add(pssItem);
19675
19676                         nativePss += mi.nativePss;
19677                         nativeSwapPss += mi.nativeSwappedOutPss;
19678                         dalvikPss += mi.dalvikPss;
19679                         dalvikSwapPss += mi.dalvikSwappedOutPss;
19680                         for (int j=0; j<dalvikSubitemPss.length; j++) {
19681                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19682                             dalvikSubitemSwapPss[j] +=
19683                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19684                         }
19685                         otherPss += mi.otherPss;
19686                         otherSwapPss += mi.otherSwappedOutPss;
19687                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19688                             long mem = mi.getOtherPss(j);
19689                             miscPss[j] += mem;
19690                             otherPss -= mem;
19691                             mem = mi.getOtherSwappedOutPss(j);
19692                             miscSwapPss[j] += mem;
19693                             otherSwapPss -= mem;
19694                         }
19695                         oomPss[0] += myTotalPss;
19696                         oomSwapPss[0] += myTotalSwapPss;
19697                         if (oomProcs[0] == null) {
19698                             oomProcs[0] = new ArrayList<MemItem>();
19699                         }
19700                         oomProcs[0].add(pssItem);
19701                     }
19702                 }
19703             }
19704
19705             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19706
19707             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19708             final int dalvikId = -2;
19709             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19710             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19711             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19712                 String label = Debug.MemoryInfo.getOtherLabel(j);
19713                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19714             }
19715             if (dalvikSubitemPss.length > 0) {
19716                 // Add dalvik subitems.
19717                 for (MemItem memItem : catMems) {
19718                     int memItemStart = 0, memItemEnd = 0;
19719                     if (memItem.id == dalvikId) {
19720                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19721                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19722                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19723                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19724                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19725                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19726                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19727                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19728                     } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19729                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19730                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19731                     } else {
19732                         continue;  // No subitems, continue.
19733                     }
19734                     memItem.subitems = new ArrayList<MemItem>();
19735                     for (int j=memItemStart; j<=memItemEnd; j++) {
19736                         final String name = Debug.MemoryInfo.getOtherLabel(
19737                                 Debug.MemoryInfo.NUM_OTHER_STATS + j);
19738                         memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19739                                 dalvikSubitemSwapPss[j], j));
19740                     }
19741                 }
19742             }
19743
19744             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19745             for (int j=0; j<oomPss.length; j++) {
19746                 if (oomPss[j] != 0) {
19747                     String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19748                             : DUMP_MEM_OOM_LABEL[j];
19749                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19750                             DUMP_MEM_OOM_ADJ[j]);
19751                     item.subitems = oomProcs[j];
19752                     oomMems.add(item);
19753                 }
19754             }
19755
19756             opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19757             if (!opts.oomOnly) {
19758                 dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_PROCESS, "proc",
19759                         procMems, true, opts.dumpSwapPss);
19760             }
19761             dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
19762                     oomMems, false, opts.dumpSwapPss);
19763             if (!brief && !opts.oomOnly) {
19764                 dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_CATEGORY, "cat",
19765                         catMems, true, opts.dumpSwapPss);
19766             }
19767             MemInfoReader memInfo = new MemInfoReader();
19768             memInfo.readMemInfo();
19769             if (nativeProcTotalPss > 0) {
19770                 synchronized (this) {
19771                     final long cachedKb = memInfo.getCachedSizeKb();
19772                     final long freeKb = memInfo.getFreeSizeKb();
19773                     final long zramKb = memInfo.getZramTotalSizeKb();
19774                     final long kernelKb = memInfo.getKernelUsedSizeKb();
19775                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19776                             kernelKb*1024, nativeProcTotalPss*1024);
19777                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19778                             nativeProcTotalPss);
19779                 }
19780             }
19781             if (!brief) {
19782                 proto.write(MemInfoDumpProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
19783                 proto.write(MemInfoDumpProto.STATUS, mLastMemoryLevel);
19784                 proto.write(MemInfoDumpProto.CACHED_PSS_KB, cachedPss);
19785                 proto.write(MemInfoDumpProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
19786                 proto.write(MemInfoDumpProto.FREE_KB, memInfo.getFreeSizeKb());
19787             }
19788             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19789                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19790                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19791             proto.write(MemInfoDumpProto.USED_PSS_KB, totalPss - cachedPss);
19792             proto.write(MemInfoDumpProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
19793             proto.write(MemInfoDumpProto.LOST_RAM_KB, lostRAM);
19794             if (!brief) {
19795                 if (memInfo.getZramTotalSizeKb() != 0) {
19796                     proto.write(MemInfoDumpProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
19797                     proto.write(MemInfoDumpProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
19798                             memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
19799                     proto.write(MemInfoDumpProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
19800                 }
19801                 final long[] ksm = getKsmInfo();
19802                 proto.write(MemInfoDumpProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
19803                 proto.write(MemInfoDumpProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
19804                 proto.write(MemInfoDumpProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
19805                 proto.write(MemInfoDumpProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
19806
19807                 proto.write(MemInfoDumpProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
19808                 proto.write(MemInfoDumpProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
19809                 proto.write(MemInfoDumpProto.OOM_KB,
19810                         mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
19811                 proto.write(MemInfoDumpProto.RESTORE_LIMIT_KB,
19812                         mProcessList.getCachedRestoreThresholdKb());
19813
19814                 proto.write(MemInfoDumpProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
19815                 proto.write(MemInfoDumpProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
19816             }
19817         }
19818
19819         proto.flush();
19820     }
19821
19822     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
19823             long memtrack, String name) {
19824         sb.append("  ");
19825         sb.append(ProcessList.makeOomAdjString(oomAdj));
19826         sb.append(' ');
19827         sb.append(ProcessList.makeProcStateString(procState));
19828         sb.append(' ');
19829         ProcessList.appendRamKb(sb, pss);
19830         sb.append(": ");
19831         sb.append(name);
19832         if (memtrack > 0) {
19833             sb.append(" (");
19834             sb.append(stringifyKBSize(memtrack));
19835             sb.append(" memtrack)");
19836         }
19837     }
19838
19839     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
19840         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
19841         sb.append(" (pid ");
19842         sb.append(mi.pid);
19843         sb.append(") ");
19844         sb.append(mi.adjType);
19845         sb.append('\n');
19846         if (mi.adjReason != null) {
19847             sb.append("                      ");
19848             sb.append(mi.adjReason);
19849             sb.append('\n');
19850         }
19851     }
19852
19853     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
19854         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
19855         for (int i=0, N=memInfos.size(); i<N; i++) {
19856             ProcessMemInfo mi = memInfos.get(i);
19857             infoMap.put(mi.pid, mi);
19858         }
19859         updateCpuStatsNow();
19860         long[] memtrackTmp = new long[1];
19861         final List<ProcessCpuTracker.Stats> stats;
19862         // Get a list of Stats that have vsize > 0
19863         synchronized (mProcessCpuTracker) {
19864             stats = mProcessCpuTracker.getStats((st) -> {
19865                 return st.vsize > 0;
19866             });
19867         }
19868         final int statsCount = stats.size();
19869         for (int i = 0; i < statsCount; i++) {
19870             ProcessCpuTracker.Stats st = stats.get(i);
19871             long pss = Debug.getPss(st.pid, null, memtrackTmp);
19872             if (pss > 0) {
19873                 if (infoMap.indexOfKey(st.pid) < 0) {
19874                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19875                             ProcessList.NATIVE_ADJ, -1, "native", null);
19876                     mi.pss = pss;
19877                     mi.memtrack = memtrackTmp[0];
19878                     memInfos.add(mi);
19879                 }
19880             }
19881         }
19882
19883         long totalPss = 0;
19884         long totalMemtrack = 0;
19885         for (int i=0, N=memInfos.size(); i<N; i++) {
19886             ProcessMemInfo mi = memInfos.get(i);
19887             if (mi.pss == 0) {
19888                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19889                 mi.memtrack = memtrackTmp[0];
19890             }
19891             totalPss += mi.pss;
19892             totalMemtrack += mi.memtrack;
19893         }
19894         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
19895             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
19896                 if (lhs.oomAdj != rhs.oomAdj) {
19897                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
19898                 }
19899                 if (lhs.pss != rhs.pss) {
19900                     return lhs.pss < rhs.pss ? 1 : -1;
19901                 }
19902                 return 0;
19903             }
19904         });
19905
19906         StringBuilder tag = new StringBuilder(128);
19907         StringBuilder stack = new StringBuilder(128);
19908         tag.append("Low on memory -- ");
19909         appendMemBucket(tag, totalPss, "total", false);
19910         appendMemBucket(stack, totalPss, "total", true);
19911
19912         StringBuilder fullNativeBuilder = new StringBuilder(1024);
19913         StringBuilder shortNativeBuilder = new StringBuilder(1024);
19914         StringBuilder fullJavaBuilder = new StringBuilder(1024);
19915
19916         boolean firstLine = true;
19917         int lastOomAdj = Integer.MIN_VALUE;
19918         long extraNativeRam = 0;
19919         long extraNativeMemtrack = 0;
19920         long cachedPss = 0;
19921         for (int i=0, N=memInfos.size(); i<N; i++) {
19922             ProcessMemInfo mi = memInfos.get(i);
19923
19924             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19925                 cachedPss += mi.pss;
19926             }
19927
19928             if (mi.oomAdj != ProcessList.NATIVE_ADJ
19929                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
19930                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
19931                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
19932                 if (lastOomAdj != mi.oomAdj) {
19933                     lastOomAdj = mi.oomAdj;
19934                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19935                         tag.append(" / ");
19936                     }
19937                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19938                         if (firstLine) {
19939                             stack.append(":");
19940                             firstLine = false;
19941                         }
19942                         stack.append("\n\t at ");
19943                     } else {
19944                         stack.append("$");
19945                     }
19946                 } else {
19947                     tag.append(" ");
19948                     stack.append("$");
19949                 }
19950                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19951                     appendMemBucket(tag, mi.pss, mi.name, false);
19952                 }
19953                 appendMemBucket(stack, mi.pss, mi.name, true);
19954                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
19955                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
19956                     stack.append("(");
19957                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
19958                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
19959                             stack.append(DUMP_MEM_OOM_LABEL[k]);
19960                             stack.append(":");
19961                             stack.append(DUMP_MEM_OOM_ADJ[k]);
19962                         }
19963                     }
19964                     stack.append(")");
19965                 }
19966             }
19967
19968             appendMemInfo(fullNativeBuilder, mi);
19969             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
19970                 // The short form only has native processes that are >= 512K.
19971                 if (mi.pss >= 512) {
19972                     appendMemInfo(shortNativeBuilder, mi);
19973                 } else {
19974                     extraNativeRam += mi.pss;
19975                     extraNativeMemtrack += mi.memtrack;
19976                 }
19977             } else {
19978                 // Short form has all other details, but if we have collected RAM
19979                 // from smaller native processes let's dump a summary of that.
19980                 if (extraNativeRam > 0) {
19981                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
19982                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
19983                     shortNativeBuilder.append('\n');
19984                     extraNativeRam = 0;
19985                 }
19986                 appendMemInfo(fullJavaBuilder, mi);
19987             }
19988         }
19989
19990         fullJavaBuilder.append("           ");
19991         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
19992         fullJavaBuilder.append(": TOTAL");
19993         if (totalMemtrack > 0) {
19994             fullJavaBuilder.append(" (");
19995             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
19996             fullJavaBuilder.append(" memtrack)");
19997         } else {
19998         }
19999         fullJavaBuilder.append("\n");
20000
20001         MemInfoReader memInfo = new MemInfoReader();
20002         memInfo.readMemInfo();
20003         final long[] infos = memInfo.getRawInfo();
20004
20005         StringBuilder memInfoBuilder = new StringBuilder(1024);
20006         Debug.getMemInfo(infos);
20007         memInfoBuilder.append("  MemInfo: ");
20008         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
20009         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
20010         memInfoBuilder.append(stringifyKBSize(
20011                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
20012         memInfoBuilder.append(stringifyKBSize(
20013                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
20014         memInfoBuilder.append(stringifyKBSize(
20015                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
20016         memInfoBuilder.append("           ");
20017         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
20018         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
20019         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
20020         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
20021         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
20022             memInfoBuilder.append("  ZRAM: ");
20023             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
20024             memInfoBuilder.append(" RAM, ");
20025             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
20026             memInfoBuilder.append(" swap total, ");
20027             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
20028             memInfoBuilder.append(" swap free\n");
20029         }
20030         final long[] ksm = getKsmInfo();
20031         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
20032                 || ksm[KSM_VOLATILE] != 0) {
20033             memInfoBuilder.append("  KSM: ");
20034             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
20035             memInfoBuilder.append(" saved from shared ");
20036             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
20037             memInfoBuilder.append("\n       ");
20038             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
20039             memInfoBuilder.append(" unshared; ");
20040             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
20041             memInfoBuilder.append(" volatile\n");
20042         }
20043         memInfoBuilder.append("  Free RAM: ");
20044         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
20045                 + memInfo.getFreeSizeKb()));
20046         memInfoBuilder.append("\n");
20047         memInfoBuilder.append("  Used RAM: ");
20048         memInfoBuilder.append(stringifyKBSize(
20049                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
20050         memInfoBuilder.append("\n");
20051         memInfoBuilder.append("  Lost RAM: ");
20052         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
20053                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
20054                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
20055         memInfoBuilder.append("\n");
20056         Slog.i(TAG, "Low on memory:");
20057         Slog.i(TAG, shortNativeBuilder.toString());
20058         Slog.i(TAG, fullJavaBuilder.toString());
20059         Slog.i(TAG, memInfoBuilder.toString());
20060
20061         StringBuilder dropBuilder = new StringBuilder(1024);
20062         /*
20063         StringWriter oomSw = new StringWriter();
20064         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
20065         StringWriter catSw = new StringWriter();
20066         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
20067         String[] emptyArgs = new String[] { };
20068         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
20069         oomPw.flush();
20070         String oomString = oomSw.toString();
20071         */
20072         dropBuilder.append("Low on memory:");
20073         dropBuilder.append(stack);
20074         dropBuilder.append('\n');
20075         dropBuilder.append(fullNativeBuilder);
20076         dropBuilder.append(fullJavaBuilder);
20077         dropBuilder.append('\n');
20078         dropBuilder.append(memInfoBuilder);
20079         dropBuilder.append('\n');
20080         /*
20081         dropBuilder.append(oomString);
20082         dropBuilder.append('\n');
20083         */
20084         StringWriter catSw = new StringWriter();
20085         synchronized (ActivityManagerService.this) {
20086             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
20087             String[] emptyArgs = new String[] { };
20088             catPw.println();
20089             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
20090             catPw.println();
20091             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
20092                     false, null).dumpLocked();
20093             catPw.println();
20094             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
20095             catPw.flush();
20096         }
20097         dropBuilder.append(catSw.toString());
20098         StatsLog.write(StatsLog.LOW_MEM_REPORTED);
20099         addErrorToDropBox("lowmem", null, "system_server", null,
20100                 null, tag.toString(), dropBuilder.toString(), null, null);
20101         //Slog.i(TAG, "Sent to dropbox:");
20102         //Slog.i(TAG, dropBuilder.toString());
20103         synchronized (ActivityManagerService.this) {
20104             long now = SystemClock.uptimeMillis();
20105             if (mLastMemUsageReportTime < now) {
20106                 mLastMemUsageReportTime = now;
20107             }
20108         }
20109     }
20110
20111     /**
20112      * Searches array of arguments for the specified string
20113      * @param args array of argument strings
20114      * @param value value to search for
20115      * @return true if the value is contained in the array
20116      */
20117     private static boolean scanArgs(String[] args, String value) {
20118         if (args != null) {
20119             for (String arg : args) {
20120                 if (value.equals(arg)) {
20121                     return true;
20122                 }
20123             }
20124         }
20125         return false;
20126     }
20127
20128     private final boolean removeDyingProviderLocked(ProcessRecord proc,
20129             ContentProviderRecord cpr, boolean always) {
20130         final boolean inLaunching = mLaunchingProviders.contains(cpr);
20131
20132         if (!inLaunching || always) {
20133             synchronized (cpr) {
20134                 cpr.launchingApp = null;
20135                 cpr.notifyAll();
20136             }
20137             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
20138             String names[] = cpr.info.authority.split(";");
20139             for (int j = 0; j < names.length; j++) {
20140                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
20141             }
20142         }
20143
20144         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
20145             ContentProviderConnection conn = cpr.connections.get(i);
20146             if (conn.waiting) {
20147                 // If this connection is waiting for the provider, then we don't
20148                 // need to mess with its process unless we are always removing
20149                 // or for some reason the provider is not currently launching.
20150                 if (inLaunching && !always) {
20151                     continue;
20152                 }
20153             }
20154             ProcessRecord capp = conn.client;
20155             conn.dead = true;
20156             if (conn.stableCount > 0) {
20157                 if (!capp.persistent && capp.thread != null
20158                         && capp.pid != 0
20159                         && capp.pid != MY_PID) {
20160                     capp.kill("depends on provider "
20161                             + cpr.name.flattenToShortString()
20162                             + " in dying proc " + (proc != null ? proc.processName : "??")
20163                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
20164                 }
20165             } else if (capp.thread != null && conn.provider.provider != null) {
20166                 try {
20167                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
20168                 } catch (RemoteException e) {
20169                 }
20170                 // In the protocol here, we don't expect the client to correctly
20171                 // clean up this connection, we'll just remove it.
20172                 cpr.connections.remove(i);
20173                 if (conn.client.conProviders.remove(conn)) {
20174                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
20175                 }
20176             }
20177         }
20178
20179         if (inLaunching && always) {
20180             mLaunchingProviders.remove(cpr);
20181         }
20182         return inLaunching;
20183     }
20184
20185     /**
20186      * Main code for cleaning up a process when it has gone away.  This is
20187      * called both as a result of the process dying, or directly when stopping
20188      * a process when running in single process mode.
20189      *
20190      * @return Returns true if the given process has been restarted, so the
20191      * app that was passed in must remain on the process lists.
20192      */
20193     @GuardedBy("this")
20194     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
20195             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
20196         if (index >= 0) {
20197             removeLruProcessLocked(app);
20198             ProcessList.remove(app.pid);
20199         }
20200
20201         mProcessesToGc.remove(app);
20202         mPendingPssProcesses.remove(app);
20203         ProcessList.abortNextPssTime(app.procStateMemTracker);
20204
20205         // Dismiss any open dialogs.
20206         if (app.crashDialog != null && !app.forceCrashReport) {
20207             app.crashDialog.dismiss();
20208             app.crashDialog = null;
20209         }
20210         if (app.anrDialog != null) {
20211             app.anrDialog.dismiss();
20212             app.anrDialog = null;
20213         }
20214         if (app.waitDialog != null) {
20215             app.waitDialog.dismiss();
20216             app.waitDialog = null;
20217         }
20218
20219         app.crashing = false;
20220         app.notResponding = false;
20221
20222         app.resetPackageList(mProcessStats);
20223         app.unlinkDeathRecipient();
20224         app.makeInactive(mProcessStats);
20225         app.waitingToKill = null;
20226         app.forcingToImportant = null;
20227         updateProcessForegroundLocked(app, false, false);
20228         app.foregroundActivities = false;
20229         app.hasShownUi = false;
20230         app.treatLikeActivity = false;
20231         app.hasAboveClient = false;
20232         app.hasClientActivities = false;
20233
20234         mServices.killServicesLocked(app, allowRestart);
20235
20236         boolean restart = false;
20237
20238         // Remove published content providers.
20239         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
20240             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
20241             final boolean always = app.bad || !allowRestart;
20242             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
20243             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
20244                 // We left the provider in the launching list, need to
20245                 // restart it.
20246                 restart = true;
20247             }
20248
20249             cpr.provider = null;
20250             cpr.proc = null;
20251         }
20252         app.pubProviders.clear();
20253
20254         // Take care of any launching providers waiting for this process.
20255         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
20256             restart = true;
20257         }
20258
20259         // Unregister from connected content providers.
20260         if (!app.conProviders.isEmpty()) {
20261             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
20262                 ContentProviderConnection conn = app.conProviders.get(i);
20263                 conn.provider.connections.remove(conn);
20264                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
20265                         conn.provider.name);
20266             }
20267             app.conProviders.clear();
20268         }
20269
20270         // At this point there may be remaining entries in mLaunchingProviders
20271         // where we were the only one waiting, so they are no longer of use.
20272         // Look for these and clean up if found.
20273         // XXX Commented out for now.  Trying to figure out a way to reproduce
20274         // the actual situation to identify what is actually going on.
20275         if (false) {
20276             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20277                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
20278                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
20279                     synchronized (cpr) {
20280                         cpr.launchingApp = null;
20281                         cpr.notifyAll();
20282                     }
20283                 }
20284             }
20285         }
20286
20287         skipCurrentReceiverLocked(app);
20288
20289         // Unregister any receivers.
20290         for (int i = app.receivers.size() - 1; i >= 0; i--) {
20291             removeReceiverLocked(app.receivers.valueAt(i));
20292         }
20293         app.receivers.clear();
20294
20295         // If the app is undergoing backup, tell the backup manager about it
20296         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
20297             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
20298                     + mBackupTarget.appInfo + " died during backup");
20299             mHandler.post(new Runnable() {
20300                 @Override
20301                 public void run(){
20302                     try {
20303                         IBackupManager bm = IBackupManager.Stub.asInterface(
20304                                 ServiceManager.getService(Context.BACKUP_SERVICE));
20305                         bm.agentDisconnected(app.info.packageName);
20306                     } catch (RemoteException e) {
20307                         // can't happen; backup manager is local
20308                     }
20309                 }
20310             });
20311         }
20312
20313         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
20314             ProcessChangeItem item = mPendingProcessChanges.get(i);
20315             if (app.pid > 0 && item.pid == app.pid) {
20316                 mPendingProcessChanges.remove(i);
20317                 mAvailProcessChanges.add(item);
20318             }
20319         }
20320         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
20321                 null).sendToTarget();
20322
20323         // If the caller is restarting this app, then leave it in its
20324         // current lists and let the caller take care of it.
20325         if (restarting) {
20326             return false;
20327         }
20328
20329         if (!app.persistent || app.isolated) {
20330             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
20331                     "Removing non-persistent process during cleanup: " + app);
20332             if (!replacingPid) {
20333                 removeProcessNameLocked(app.processName, app.uid, app);
20334             }
20335             if (mHeavyWeightProcess == app) {
20336                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
20337                         mHeavyWeightProcess.userId, 0));
20338                 mHeavyWeightProcess = null;
20339             }
20340         } else if (!app.removed) {
20341             // This app is persistent, so we need to keep its record around.
20342             // If it is not already on the pending app list, add it there
20343             // and start a new process for it.
20344             if (mPersistentStartingProcesses.indexOf(app) < 0) {
20345                 mPersistentStartingProcesses.add(app);
20346                 restart = true;
20347             }
20348         }
20349         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
20350                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
20351         mProcessesOnHold.remove(app);
20352
20353         if (app == mHomeProcess) {
20354             mHomeProcess = null;
20355         }
20356         if (app == mPreviousProcess) {
20357             mPreviousProcess = null;
20358         }
20359
20360         if (restart && !app.isolated) {
20361             // We have components that still need to be running in the
20362             // process, so re-launch it.
20363             if (index < 0) {
20364                 ProcessList.remove(app.pid);
20365             }
20366             addProcessNameLocked(app);
20367             app.pendingStart = false;
20368             startProcessLocked(app, "restart", app.processName);
20369             return true;
20370         } else if (app.pid > 0 && app.pid != MY_PID) {
20371             // Goodbye!
20372             boolean removed;
20373             synchronized (mPidsSelfLocked) {
20374                 mPidsSelfLocked.remove(app.pid);
20375                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
20376             }
20377             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
20378             if (app.isolated) {
20379                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
20380             }
20381             app.setPid(0);
20382         }
20383         return false;
20384     }
20385
20386     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
20387         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20388             ContentProviderRecord cpr = mLaunchingProviders.get(i);
20389             if (cpr.launchingApp == app) {
20390                 return true;
20391             }
20392         }
20393         return false;
20394     }
20395
20396     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
20397         // Look through the content providers we are waiting to have launched,
20398         // and if any run in this process then either schedule a restart of
20399         // the process or kill the client waiting for it if this process has
20400         // gone bad.
20401         boolean restart = false;
20402         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20403             ContentProviderRecord cpr = mLaunchingProviders.get(i);
20404             if (cpr.launchingApp == app) {
20405                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
20406                     restart = true;
20407                 } else {
20408                     removeDyingProviderLocked(app, cpr, true);
20409                 }
20410             }
20411         }
20412         return restart;
20413     }
20414
20415     // =========================================================
20416     // SERVICES
20417     // =========================================================
20418
20419     @Override
20420     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
20421         enforceNotIsolatedCaller("getServices");
20422
20423         final int callingUid = Binder.getCallingUid();
20424         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
20425             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
20426         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
20427             callingUid);
20428         synchronized (this) {
20429             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
20430                 allowed, canInteractAcrossUsers);
20431         }
20432     }
20433
20434     @Override
20435     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
20436         enforceNotIsolatedCaller("getRunningServiceControlPanel");
20437         synchronized (this) {
20438             return mServices.getRunningServiceControlPanelLocked(name);
20439         }
20440     }
20441
20442     @Override
20443     public ComponentName startService(IApplicationThread caller, Intent service,
20444             String resolvedType, boolean requireForeground, String callingPackage, int userId)
20445             throws TransactionTooLargeException {
20446         enforceNotIsolatedCaller("startService");
20447         // Refuse possible leaked file descriptors
20448         if (service != null && service.hasFileDescriptors() == true) {
20449             throw new IllegalArgumentException("File descriptors passed in Intent");
20450         }
20451
20452         if (callingPackage == null) {
20453             throw new IllegalArgumentException("callingPackage cannot be null");
20454         }
20455
20456         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20457                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
20458         synchronized(this) {
20459             final int callingPid = Binder.getCallingPid();
20460             final int callingUid = Binder.getCallingUid();
20461             final long origId = Binder.clearCallingIdentity();
20462             ComponentName res;
20463             try {
20464                 res = mServices.startServiceLocked(caller, service,
20465                         resolvedType, callingPid, callingUid,
20466                         requireForeground, callingPackage, userId);
20467             } finally {
20468                 Binder.restoreCallingIdentity(origId);
20469             }
20470             return res;
20471         }
20472     }
20473
20474     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
20475             boolean fgRequired, String callingPackage, int userId)
20476             throws TransactionTooLargeException {
20477         synchronized(this) {
20478             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20479                     "startServiceInPackage: " + service + " type=" + resolvedType);
20480             final long origId = Binder.clearCallingIdentity();
20481             ComponentName res;
20482             try {
20483                 res = mServices.startServiceLocked(null, service,
20484                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
20485             } finally {
20486                 Binder.restoreCallingIdentity(origId);
20487             }
20488             return res;
20489         }
20490     }
20491
20492     @Override
20493     public int stopService(IApplicationThread caller, Intent service,
20494             String resolvedType, int userId) {
20495         enforceNotIsolatedCaller("stopService");
20496         // Refuse possible leaked file descriptors
20497         if (service != null && service.hasFileDescriptors() == true) {
20498             throw new IllegalArgumentException("File descriptors passed in Intent");
20499         }
20500
20501         synchronized(this) {
20502             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
20503         }
20504     }
20505
20506     @Override
20507     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
20508         enforceNotIsolatedCaller("peekService");
20509         // Refuse possible leaked file descriptors
20510         if (service != null && service.hasFileDescriptors() == true) {
20511             throw new IllegalArgumentException("File descriptors passed in Intent");
20512         }
20513
20514         if (callingPackage == null) {
20515             throw new IllegalArgumentException("callingPackage cannot be null");
20516         }
20517
20518         synchronized(this) {
20519             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
20520         }
20521     }
20522
20523     @Override
20524     public boolean stopServiceToken(ComponentName className, IBinder token,
20525             int startId) {
20526         synchronized(this) {
20527             return mServices.stopServiceTokenLocked(className, token, startId);
20528         }
20529     }
20530
20531     @Override
20532     public void setServiceForeground(ComponentName className, IBinder token,
20533             int id, Notification notification, int flags) {
20534         synchronized(this) {
20535             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
20536         }
20537     }
20538
20539     @Override
20540     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
20541             boolean requireFull, String name, String callerPackage) {
20542         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
20543                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
20544     }
20545
20546     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
20547             String className, int flags) {
20548         boolean result = false;
20549         // For apps that don't have pre-defined UIDs, check for permission
20550         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
20551             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20552                 if (ActivityManager.checkUidPermission(
20553                         INTERACT_ACROSS_USERS,
20554                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
20555                     ComponentName comp = new ComponentName(aInfo.packageName, className);
20556                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
20557                             + " requests FLAG_SINGLE_USER, but app does not hold "
20558                             + INTERACT_ACROSS_USERS;
20559                     Slog.w(TAG, msg);
20560                     throw new SecurityException(msg);
20561                 }
20562                 // Permission passed
20563                 result = true;
20564             }
20565         } else if ("system".equals(componentProcessName)) {
20566             result = true;
20567         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20568             // Phone app and persistent apps are allowed to export singleuser providers.
20569             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
20570                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
20571         }
20572         if (DEBUG_MU) Slog.v(TAG_MU,
20573                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
20574                 + Integer.toHexString(flags) + ") = " + result);
20575         return result;
20576     }
20577
20578     /**
20579      * Checks to see if the caller is in the same app as the singleton
20580      * component, or the component is in a special app. It allows special apps
20581      * to export singleton components but prevents exporting singleton
20582      * components for regular apps.
20583      */
20584     boolean isValidSingletonCall(int callingUid, int componentUid) {
20585         int componentAppId = UserHandle.getAppId(componentUid);
20586         return UserHandle.isSameApp(callingUid, componentUid)
20587                 || componentAppId == SYSTEM_UID
20588                 || componentAppId == PHONE_UID
20589                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
20590                         == PackageManager.PERMISSION_GRANTED;
20591     }
20592
20593     public int bindService(IApplicationThread caller, IBinder token, Intent service,
20594             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
20595             int userId) throws TransactionTooLargeException {
20596         enforceNotIsolatedCaller("bindService");
20597
20598         // Refuse possible leaked file descriptors
20599         if (service != null && service.hasFileDescriptors() == true) {
20600             throw new IllegalArgumentException("File descriptors passed in Intent");
20601         }
20602
20603         if (callingPackage == null) {
20604             throw new IllegalArgumentException("callingPackage cannot be null");
20605         }
20606
20607         synchronized(this) {
20608             return mServices.bindServiceLocked(caller, token, service,
20609                     resolvedType, connection, flags, callingPackage, userId);
20610         }
20611     }
20612
20613     public boolean unbindService(IServiceConnection connection) {
20614         synchronized (this) {
20615             return mServices.unbindServiceLocked(connection);
20616         }
20617     }
20618
20619     public void publishService(IBinder token, Intent intent, IBinder service) {
20620         // Refuse possible leaked file descriptors
20621         if (intent != null && intent.hasFileDescriptors() == true) {
20622             throw new IllegalArgumentException("File descriptors passed in Intent");
20623         }
20624
20625         synchronized(this) {
20626             if (!(token instanceof ServiceRecord)) {
20627                 throw new IllegalArgumentException("Invalid service token");
20628             }
20629             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
20630         }
20631     }
20632
20633     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
20634         // Refuse possible leaked file descriptors
20635         if (intent != null && intent.hasFileDescriptors() == true) {
20636             throw new IllegalArgumentException("File descriptors passed in Intent");
20637         }
20638
20639         synchronized(this) {
20640             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
20641         }
20642     }
20643
20644     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
20645         synchronized(this) {
20646             if (!(token instanceof ServiceRecord)) {
20647                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
20648                 throw new IllegalArgumentException("Invalid service token");
20649             }
20650             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
20651         }
20652     }
20653
20654     // =========================================================
20655     // BACKUP AND RESTORE
20656     // =========================================================
20657
20658     // Cause the target app to be launched if necessary and its backup agent
20659     // instantiated.  The backup agent will invoke backupAgentCreated() on the
20660     // activity manager to announce its creation.
20661     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
20662         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
20663         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
20664
20665         IPackageManager pm = AppGlobals.getPackageManager();
20666         ApplicationInfo app = null;
20667         try {
20668             app = pm.getApplicationInfo(packageName, STOCK_PM_FLAGS, userId);
20669         } catch (RemoteException e) {
20670             // can't happen; package manager is process-local
20671         }
20672         if (app == null) {
20673             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
20674             return false;
20675         }
20676
20677         int oldBackupUid;
20678         int newBackupUid;
20679
20680         synchronized(this) {
20681             // !!! TODO: currently no check here that we're already bound
20682             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
20683             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20684             synchronized (stats) {
20685                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
20686             }
20687
20688             // Backup agent is now in use, its package can't be stopped.
20689             try {
20690                 AppGlobals.getPackageManager().setPackageStoppedState(
20691                         app.packageName, false, UserHandle.getUserId(app.uid));
20692             } catch (RemoteException e) {
20693             } catch (IllegalArgumentException e) {
20694                 Slog.w(TAG, "Failed trying to unstop package "
20695                         + app.packageName + ": " + e);
20696             }
20697
20698             BackupRecord r = new BackupRecord(ss, app, backupMode);
20699             ComponentName hostingName =
20700                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
20701                             ? new ComponentName(app.packageName, app.backupAgentName)
20702                             : new ComponentName("android", "FullBackupAgent");
20703             // startProcessLocked() returns existing proc's record if it's already running
20704             ProcessRecord proc = startProcessLocked(app.processName, app,
20705                     false, 0, "backup", hostingName, false, false, false);
20706             if (proc == null) {
20707                 Slog.e(TAG, "Unable to start backup agent process " + r);
20708                 return false;
20709             }
20710
20711             // If the app is a regular app (uid >= 10000) and not the system server or phone
20712             // process, etc, then mark it as being in full backup so that certain calls to the
20713             // process can be blocked. This is not reset to false anywhere because we kill the
20714             // process after the full backup is done and the ProcessRecord will vaporize anyway.
20715             if (UserHandle.isApp(app.uid) &&
20716                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
20717                 proc.inFullBackup = true;
20718             }
20719             r.app = proc;
20720             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20721             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
20722             mBackupTarget = r;
20723             mBackupAppName = app.packageName;
20724
20725             // Try not to kill the process during backup
20726             updateOomAdjLocked(proc, true);
20727
20728             // If the process is already attached, schedule the creation of the backup agent now.
20729             // If it is not yet live, this will be done when it attaches to the framework.
20730             if (proc.thread != null) {
20731                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
20732                 try {
20733                     proc.thread.scheduleCreateBackupAgent(app,
20734                             compatibilityInfoForPackageLocked(app), backupMode);
20735                 } catch (RemoteException e) {
20736                     // Will time out on the backup manager side
20737                 }
20738             } else {
20739                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
20740             }
20741             // Invariants: at this point, the target app process exists and the application
20742             // is either already running or in the process of coming up.  mBackupTarget and
20743             // mBackupAppName describe the app, so that when it binds back to the AM we
20744             // know that it's scheduled for a backup-agent operation.
20745         }
20746
20747         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20748         if (oldBackupUid != -1) {
20749             js.removeBackingUpUid(oldBackupUid);
20750         }
20751         if (newBackupUid != -1) {
20752             js.addBackingUpUid(newBackupUid);
20753         }
20754
20755         return true;
20756     }
20757
20758     @Override
20759     public void clearPendingBackup() {
20760         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
20761         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
20762
20763         synchronized (this) {
20764             mBackupTarget = null;
20765             mBackupAppName = null;
20766         }
20767
20768         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20769         js.clearAllBackingUpUids();
20770     }
20771
20772     // A backup agent has just come up
20773     public void backupAgentCreated(String agentPackageName, IBinder agent) {
20774         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
20775                 + " = " + agent);
20776
20777         synchronized(this) {
20778             if (!agentPackageName.equals(mBackupAppName)) {
20779                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
20780                 return;
20781             }
20782         }
20783
20784         long oldIdent = Binder.clearCallingIdentity();
20785         try {
20786             IBackupManager bm = IBackupManager.Stub.asInterface(
20787                     ServiceManager.getService(Context.BACKUP_SERVICE));
20788             bm.agentConnected(agentPackageName, agent);
20789         } catch (RemoteException e) {
20790             // can't happen; the backup manager service is local
20791         } catch (Exception e) {
20792             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
20793             e.printStackTrace();
20794         } finally {
20795             Binder.restoreCallingIdentity(oldIdent);
20796         }
20797     }
20798
20799     // done with this agent
20800     public void unbindBackupAgent(ApplicationInfo appInfo) {
20801         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
20802         if (appInfo == null) {
20803             Slog.w(TAG, "unbind backup agent for null app");
20804             return;
20805         }
20806
20807         int oldBackupUid;
20808
20809         synchronized(this) {
20810             try {
20811                 if (mBackupAppName == null) {
20812                     Slog.w(TAG, "Unbinding backup agent with no active backup");
20813                     return;
20814                 }
20815
20816                 if (!mBackupAppName.equals(appInfo.packageName)) {
20817                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
20818                     return;
20819                 }
20820
20821                 // Not backing this app up any more; reset its OOM adjustment
20822                 final ProcessRecord proc = mBackupTarget.app;
20823                 updateOomAdjLocked(proc, true);
20824                 proc.inFullBackup = false;
20825
20826                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20827
20828                 // If the app crashed during backup, 'thread' will be null here
20829                 if (proc.thread != null) {
20830                     try {
20831                         proc.thread.scheduleDestroyBackupAgent(appInfo,
20832                                 compatibilityInfoForPackageLocked(appInfo));
20833                     } catch (Exception e) {
20834                         Slog.e(TAG, "Exception when unbinding backup agent:");
20835                         e.printStackTrace();
20836                     }
20837                 }
20838             } finally {
20839                 mBackupTarget = null;
20840                 mBackupAppName = null;
20841             }
20842         }
20843
20844         if (oldBackupUid != -1) {
20845             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20846             js.removeBackingUpUid(oldBackupUid);
20847         }
20848     }
20849
20850     // =========================================================
20851     // BROADCASTS
20852     // =========================================================
20853
20854     private boolean isInstantApp(ProcessRecord record, @Nullable String callerPackage, int uid) {
20855         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
20856             return false;
20857         }
20858         // Easy case -- we have the app's ProcessRecord.
20859         if (record != null) {
20860             return record.info.isInstantApp();
20861         }
20862         // Otherwise check with PackageManager.
20863         IPackageManager pm = AppGlobals.getPackageManager();
20864         try {
20865             if (callerPackage == null) {
20866                 final String[] packageNames = pm.getPackagesForUid(uid);
20867                 if (packageNames == null || packageNames.length == 0) {
20868                     throw new IllegalArgumentException("Unable to determine caller package name");
20869                 }
20870                 // Instant Apps can't use shared uids, so its safe to only check the first package.
20871                 callerPackage = packageNames[0];
20872             }
20873             mAppOpsService.checkPackage(uid, callerPackage);
20874             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
20875         } catch (RemoteException e) {
20876             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
20877             return true;
20878         }
20879     }
20880
20881     boolean isPendingBroadcastProcessLocked(int pid) {
20882         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20883                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
20884     }
20885
20886     void skipPendingBroadcastLocked(int pid) {
20887             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
20888             for (BroadcastQueue queue : mBroadcastQueues) {
20889                 queue.skipPendingBroadcastLocked(pid);
20890             }
20891     }
20892
20893     // The app just attached; send any pending broadcasts that it should receive
20894     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
20895         boolean didSomething = false;
20896         for (BroadcastQueue queue : mBroadcastQueues) {
20897             didSomething |= queue.sendPendingBroadcastsLocked(app);
20898         }
20899         return didSomething;
20900     }
20901
20902     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20903             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
20904             int flags) {
20905         enforceNotIsolatedCaller("registerReceiver");
20906         ArrayList<Intent> stickyIntents = null;
20907         ProcessRecord callerApp = null;
20908         final boolean visibleToInstantApps
20909                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
20910         int callingUid;
20911         int callingPid;
20912         boolean instantApp;
20913         synchronized(this) {
20914             if (caller != null) {
20915                 callerApp = getRecordForAppLocked(caller);
20916                 if (callerApp == null) {
20917                     throw new SecurityException(
20918                             "Unable to find app for caller " + caller
20919                             + " (pid=" + Binder.getCallingPid()
20920                             + ") when registering receiver " + receiver);
20921                 }
20922                 if (callerApp.info.uid != SYSTEM_UID &&
20923                         !callerApp.pkgList.containsKey(callerPackage) &&
20924                         !"android".equals(callerPackage)) {
20925                     throw new SecurityException("Given caller package " + callerPackage
20926                             + " is not running in process " + callerApp);
20927                 }
20928                 callingUid = callerApp.info.uid;
20929                 callingPid = callerApp.pid;
20930             } else {
20931                 callerPackage = null;
20932                 callingUid = Binder.getCallingUid();
20933                 callingPid = Binder.getCallingPid();
20934             }
20935
20936             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20937             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20938                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
20939
20940             Iterator<String> actions = filter.actionsIterator();
20941             if (actions == null) {
20942                 ArrayList<String> noAction = new ArrayList<String>(1);
20943                 noAction.add(null);
20944                 actions = noAction.iterator();
20945             }
20946
20947             // Collect stickies of users
20948             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
20949             while (actions.hasNext()) {
20950                 String action = actions.next();
20951                 for (int id : userIds) {
20952                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
20953                     if (stickies != null) {
20954                         ArrayList<Intent> intents = stickies.get(action);
20955                         if (intents != null) {
20956                             if (stickyIntents == null) {
20957                                 stickyIntents = new ArrayList<Intent>();
20958                             }
20959                             stickyIntents.addAll(intents);
20960                         }
20961                     }
20962                 }
20963             }
20964         }
20965
20966         ArrayList<Intent> allSticky = null;
20967         if (stickyIntents != null) {
20968             final ContentResolver resolver = mContext.getContentResolver();
20969             // Look for any matching sticky broadcasts...
20970             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
20971                 Intent intent = stickyIntents.get(i);
20972                 // Don't provided intents that aren't available to instant apps.
20973                 if (instantApp &&
20974                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
20975                     continue;
20976                 }
20977                 // If intent has scheme "content", it will need to acccess
20978                 // provider that needs to lock mProviderMap in ActivityThread
20979                 // and also it may need to wait application response, so we
20980                 // cannot lock ActivityManagerService here.
20981                 if (filter.match(resolver, intent, true, TAG) >= 0) {
20982                     if (allSticky == null) {
20983                         allSticky = new ArrayList<Intent>();
20984                     }
20985                     allSticky.add(intent);
20986                 }
20987             }
20988         }
20989
20990         // The first sticky in the list is returned directly back to the client.
20991         Intent sticky = allSticky != null ? allSticky.get(0) : null;
20992         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
20993         if (receiver == null) {
20994             return sticky;
20995         }
20996
20997         synchronized (this) {
20998             if (callerApp != null && (callerApp.thread == null
20999                     || callerApp.thread.asBinder() != caller.asBinder())) {
21000                 // Original caller already died
21001                 return null;
21002             }
21003             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
21004             if (rl == null) {
21005                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
21006                         userId, receiver);
21007                 if (rl.app != null) {
21008                     final int totalReceiversForApp = rl.app.receivers.size();
21009                     if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
21010                         throw new IllegalStateException("Too many receivers, total of "
21011                                 + totalReceiversForApp + ", registered for pid: "
21012                                 + rl.pid + ", callerPackage: " + callerPackage);
21013                     }
21014                     rl.app.receivers.add(rl);
21015                 } else {
21016                     try {
21017                         receiver.asBinder().linkToDeath(rl, 0);
21018                     } catch (RemoteException e) {
21019                         return sticky;
21020                     }
21021                     rl.linkedToDeath = true;
21022                 }
21023                 mRegisteredReceivers.put(receiver.asBinder(), rl);
21024             } else if (rl.uid != callingUid) {
21025                 throw new IllegalArgumentException(
21026                         "Receiver requested to register for uid " + callingUid
21027                         + " was previously registered for uid " + rl.uid
21028                         + " callerPackage is " + callerPackage);
21029             } else if (rl.pid != callingPid) {
21030                 throw new IllegalArgumentException(
21031                         "Receiver requested to register for pid " + callingPid
21032                         + " was previously registered for pid " + rl.pid
21033                         + " callerPackage is " + callerPackage);
21034             } else if (rl.userId != userId) {
21035                 throw new IllegalArgumentException(
21036                         "Receiver requested to register for user " + userId
21037                         + " was previously registered for user " + rl.userId
21038                         + " callerPackage is " + callerPackage);
21039             }
21040             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
21041                     permission, callingUid, userId, instantApp, visibleToInstantApps);
21042             if (rl.containsFilter(filter)) {
21043                 Slog.w(TAG, "Receiver with filter " + filter
21044                         + " already registered for pid " + rl.pid
21045                         + ", callerPackage is " + callerPackage);
21046             } else {
21047                 rl.add(bf);
21048                 if (!bf.debugCheck()) {
21049                     Slog.w(TAG, "==> For Dynamic broadcast");
21050                 }
21051                 mReceiverResolver.addFilter(bf);
21052             }
21053
21054             // Enqueue broadcasts for all existing stickies that match
21055             // this filter.
21056             if (allSticky != null) {
21057                 ArrayList receivers = new ArrayList();
21058                 receivers.add(bf);
21059
21060                 final int stickyCount = allSticky.size();
21061                 for (int i = 0; i < stickyCount; i++) {
21062                     Intent intent = allSticky.get(i);
21063                     BroadcastQueue queue = broadcastQueueForIntent(intent);
21064                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
21065                             null, -1, -1, false, null, null, OP_NONE, null, receivers,
21066                             null, 0, null, null, false, true, true, -1);
21067                     queue.enqueueParallelBroadcastLocked(r);
21068                     queue.scheduleBroadcastsLocked();
21069                 }
21070             }
21071
21072             return sticky;
21073         }
21074     }
21075
21076     public void unregisterReceiver(IIntentReceiver receiver) {
21077         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
21078
21079         final long origId = Binder.clearCallingIdentity();
21080         try {
21081             boolean doTrim = false;
21082
21083             synchronized(this) {
21084                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
21085                 if (rl != null) {
21086                     final BroadcastRecord r = rl.curBroadcast;
21087                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
21088                         final boolean doNext = r.queue.finishReceiverLocked(
21089                                 r, r.resultCode, r.resultData, r.resultExtras,
21090                                 r.resultAbort, false);
21091                         if (doNext) {
21092                             doTrim = true;
21093                             r.queue.processNextBroadcast(false);
21094                         }
21095                     }
21096
21097                     if (rl.app != null) {
21098                         rl.app.receivers.remove(rl);
21099                     }
21100                     removeReceiverLocked(rl);
21101                     if (rl.linkedToDeath) {
21102                         rl.linkedToDeath = false;
21103                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
21104                     }
21105                 }
21106             }
21107
21108             // If we actually concluded any broadcasts, we might now be able
21109             // to trim the recipients' apps from our working set
21110             if (doTrim) {
21111                 trimApplications();
21112                 return;
21113             }
21114
21115         } finally {
21116             Binder.restoreCallingIdentity(origId);
21117         }
21118     }
21119
21120     void removeReceiverLocked(ReceiverList rl) {
21121         mRegisteredReceivers.remove(rl.receiver.asBinder());
21122         for (int i = rl.size() - 1; i >= 0; i--) {
21123             mReceiverResolver.removeFilter(rl.get(i));
21124         }
21125     }
21126
21127     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
21128         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21129             ProcessRecord r = mLruProcesses.get(i);
21130             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
21131                 try {
21132                     r.thread.dispatchPackageBroadcast(cmd, packages);
21133                 } catch (RemoteException ex) {
21134                 }
21135             }
21136         }
21137     }
21138
21139     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
21140             int callingUid, int[] users) {
21141         // TODO: come back and remove this assumption to triage all broadcasts
21142         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
21143
21144         List<ResolveInfo> receivers = null;
21145         try {
21146             HashSet<ComponentName> singleUserReceivers = null;
21147             boolean scannedFirstReceivers = false;
21148             for (int user : users) {
21149                 // Skip users that have Shell restrictions, with exception of always permitted
21150                 // Shell broadcasts
21151                 if (callingUid == SHELL_UID
21152                         && mUserController.hasUserRestriction(
21153                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
21154                         && !isPermittedShellBroadcast(intent)) {
21155                     continue;
21156                 }
21157                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
21158                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
21159                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
21160                     // If this is not the system user, we need to check for
21161                     // any receivers that should be filtered out.
21162                     for (int i=0; i<newReceivers.size(); i++) {
21163                         ResolveInfo ri = newReceivers.get(i);
21164                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
21165                             newReceivers.remove(i);
21166                             i--;
21167                         }
21168                     }
21169                 }
21170                 if (newReceivers != null && newReceivers.size() == 0) {
21171                     newReceivers = null;
21172                 }
21173                 if (receivers == null) {
21174                     receivers = newReceivers;
21175                 } else if (newReceivers != null) {
21176                     // We need to concatenate the additional receivers
21177                     // found with what we have do far.  This would be easy,
21178                     // but we also need to de-dup any receivers that are
21179                     // singleUser.
21180                     if (!scannedFirstReceivers) {
21181                         // Collect any single user receivers we had already retrieved.
21182                         scannedFirstReceivers = true;
21183                         for (int i=0; i<receivers.size(); i++) {
21184                             ResolveInfo ri = receivers.get(i);
21185                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
21186                                 ComponentName cn = new ComponentName(
21187                                         ri.activityInfo.packageName, ri.activityInfo.name);
21188                                 if (singleUserReceivers == null) {
21189                                     singleUserReceivers = new HashSet<ComponentName>();
21190                                 }
21191                                 singleUserReceivers.add(cn);
21192                             }
21193                         }
21194                     }
21195                     // Add the new results to the existing results, tracking
21196                     // and de-dupping single user receivers.
21197                     for (int i=0; i<newReceivers.size(); i++) {
21198                         ResolveInfo ri = newReceivers.get(i);
21199                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
21200                             ComponentName cn = new ComponentName(
21201                                     ri.activityInfo.packageName, ri.activityInfo.name);
21202                             if (singleUserReceivers == null) {
21203                                 singleUserReceivers = new HashSet<ComponentName>();
21204                             }
21205                             if (!singleUserReceivers.contains(cn)) {
21206                                 singleUserReceivers.add(cn);
21207                                 receivers.add(ri);
21208                             }
21209                         } else {
21210                             receivers.add(ri);
21211                         }
21212                     }
21213                 }
21214             }
21215         } catch (RemoteException ex) {
21216             // pm is in same process, this will never happen.
21217         }
21218         return receivers;
21219     }
21220
21221     private boolean isPermittedShellBroadcast(Intent intent) {
21222         // remote bugreport should always be allowed to be taken
21223         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
21224     }
21225
21226     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
21227             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
21228         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21229             // Don't yell about broadcasts sent via shell
21230             return;
21231         }
21232
21233         final String action = intent.getAction();
21234         if (isProtectedBroadcast
21235                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
21236                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
21237                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
21238                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
21239                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
21240                 || Intent.ACTION_MASTER_CLEAR.equals(action)
21241                 || Intent.ACTION_FACTORY_RESET.equals(action)
21242                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
21243                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
21244                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
21245                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
21246                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
21247                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
21248                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
21249             // Broadcast is either protected, or it's a public action that
21250             // we've relaxed, so it's fine for system internals to send.
21251             return;
21252         }
21253
21254         // This broadcast may be a problem...  but there are often system components that
21255         // want to send an internal broadcast to themselves, which is annoying to have to
21256         // explicitly list each action as a protected broadcast, so we will check for that
21257         // one safe case and allow it: an explicit broadcast, only being received by something
21258         // that has protected itself.
21259         if (intent.getPackage() != null || intent.getComponent() != null) {
21260             if (receivers == null || receivers.size() == 0) {
21261                 // Intent is explicit and there's no receivers.
21262                 // This happens, e.g. , when a system component sends a broadcast to
21263                 // its own runtime receiver, and there's no manifest receivers for it,
21264                 // because this method is called twice for each broadcast,
21265                 // for runtime receivers and manifest receivers and the later check would find
21266                 // no receivers.
21267                 return;
21268             }
21269             boolean allProtected = true;
21270             for (int i = receivers.size()-1; i >= 0; i--) {
21271                 Object target = receivers.get(i);
21272                 if (target instanceof ResolveInfo) {
21273                     ResolveInfo ri = (ResolveInfo)target;
21274                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
21275                         allProtected = false;
21276                         break;
21277                     }
21278                 } else {
21279                     BroadcastFilter bf = (BroadcastFilter)target;
21280                     if (bf.requiredPermission == null) {
21281                         allProtected = false;
21282                         break;
21283                     }
21284                 }
21285             }
21286             if (allProtected) {
21287                 // All safe!
21288                 return;
21289             }
21290         }
21291
21292         // The vast majority of broadcasts sent from system internals
21293         // should be protected to avoid security holes, so yell loudly
21294         // to ensure we examine these cases.
21295         if (callerApp != null) {
21296             Log.wtf(TAG, "Sending non-protected broadcast " + action
21297                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
21298                     new Throwable());
21299         } else {
21300             Log.wtf(TAG, "Sending non-protected broadcast " + action
21301                             + " from system uid " + UserHandle.formatUid(callingUid)
21302                             + " pkg " + callerPackage,
21303                     new Throwable());
21304         }
21305     }
21306
21307     @GuardedBy("this")
21308     final int broadcastIntentLocked(ProcessRecord callerApp,
21309             String callerPackage, Intent intent, String resolvedType,
21310             IIntentReceiver resultTo, int resultCode, String resultData,
21311             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
21312             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
21313         intent = new Intent(intent);
21314
21315         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
21316         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
21317         if (callerInstantApp) {
21318             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21319         }
21320
21321         // By default broadcasts do not go to stopped apps.
21322         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
21323
21324         // If we have not finished booting, don't allow this to launch new processes.
21325         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
21326             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21327         }
21328
21329         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
21330                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
21331                 + " ordered=" + ordered + " userid=" + userId);
21332         if ((resultTo != null) && !ordered) {
21333             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
21334         }
21335
21336         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
21337                 ALLOW_NON_FULL, "broadcast", callerPackage);
21338
21339         // Make sure that the user who is receiving this broadcast or its parent is running.
21340         // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
21341         if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
21342             if ((callingUid != SYSTEM_UID
21343                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
21344                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
21345                 Slog.w(TAG, "Skipping broadcast of " + intent
21346                         + ": user " + userId + " and its parent (if any) are stopped");
21347                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
21348             }
21349         }
21350
21351         final String action = intent.getAction();
21352         BroadcastOptions brOptions = null;
21353         if (bOptions != null) {
21354             brOptions = new BroadcastOptions(bOptions);
21355             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
21356                 // See if the caller is allowed to do this.  Note we are checking against
21357                 // the actual real caller (not whoever provided the operation as say a
21358                 // PendingIntent), because that who is actually supplied the arguments.
21359                 if (checkComponentPermission(
21360                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
21361                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
21362                         != PackageManager.PERMISSION_GRANTED) {
21363                     String msg = "Permission Denial: " + intent.getAction()
21364                             + " broadcast from " + callerPackage + " (pid=" + callingPid
21365                             + ", uid=" + callingUid + ")"
21366                             + " requires "
21367                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21368                     Slog.w(TAG, msg);
21369                     throw new SecurityException(msg);
21370                 }
21371             }
21372             if (brOptions.isDontSendToRestrictedApps()
21373                     && !isUidActiveLocked(callingUid)
21374                     && isBackgroundRestrictedNoCheck(callingUid, callerPackage)) {
21375                 Slog.i(TAG, "Not sending broadcast " + action + " - app " + callerPackage
21376                         + " has background restrictions");
21377                 return ActivityManager.START_CANCELED;
21378             }
21379         }
21380
21381         // Verify that protected broadcasts are only being sent by system code,
21382         // and that system code is only sending protected broadcasts.
21383         final boolean isProtectedBroadcast;
21384         try {
21385             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
21386         } catch (RemoteException e) {
21387             Slog.w(TAG, "Remote exception", e);
21388             return ActivityManager.BROADCAST_SUCCESS;
21389         }
21390
21391         final boolean isCallerSystem;
21392         switch (UserHandle.getAppId(callingUid)) {
21393             case ROOT_UID:
21394             case SYSTEM_UID:
21395             case PHONE_UID:
21396             case BLUETOOTH_UID:
21397             case NFC_UID:
21398             case SE_UID:
21399                 isCallerSystem = true;
21400                 break;
21401             default:
21402                 isCallerSystem = (callerApp != null) && callerApp.persistent;
21403                 break;
21404         }
21405
21406         // First line security check before anything else: stop non-system apps from
21407         // sending protected broadcasts.
21408         if (!isCallerSystem) {
21409             if (isProtectedBroadcast) {
21410                 String msg = "Permission Denial: not allowed to send broadcast "
21411                         + action + " from pid="
21412                         + callingPid + ", uid=" + callingUid;
21413                 Slog.w(TAG, msg);
21414                 throw new SecurityException(msg);
21415
21416             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
21417                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
21418                 // Special case for compatibility: we don't want apps to send this,
21419                 // but historically it has not been protected and apps may be using it
21420                 // to poke their own app widget.  So, instead of making it protected,
21421                 // just limit it to the caller.
21422                 if (callerPackage == null) {
21423                     String msg = "Permission Denial: not allowed to send broadcast "
21424                             + action + " from unknown caller.";
21425                     Slog.w(TAG, msg);
21426                     throw new SecurityException(msg);
21427                 } else if (intent.getComponent() != null) {
21428                     // They are good enough to send to an explicit component...  verify
21429                     // it is being sent to the calling app.
21430                     if (!intent.getComponent().getPackageName().equals(
21431                             callerPackage)) {
21432                         String msg = "Permission Denial: not allowed to send broadcast "
21433                                 + action + " to "
21434                                 + intent.getComponent().getPackageName() + " from "
21435                                 + callerPackage;
21436                         Slog.w(TAG, msg);
21437                         throw new SecurityException(msg);
21438                     }
21439                 } else {
21440                     // Limit broadcast to their own package.
21441                     intent.setPackage(callerPackage);
21442                 }
21443             }
21444         }
21445
21446         if (action != null) {
21447             if (getBackgroundLaunchBroadcasts().contains(action)) {
21448                 if (DEBUG_BACKGROUND_CHECK) {
21449                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
21450                 }
21451                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
21452             }
21453
21454             switch (action) {
21455                 case Intent.ACTION_UID_REMOVED:
21456                 case Intent.ACTION_PACKAGE_REMOVED:
21457                 case Intent.ACTION_PACKAGE_CHANGED:
21458                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21459                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21460                 case Intent.ACTION_PACKAGES_SUSPENDED:
21461                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
21462                     // Handle special intents: if this broadcast is from the package
21463                     // manager about a package being removed, we need to remove all of
21464                     // its activities from the history stack.
21465                     if (checkComponentPermission(
21466                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
21467                             callingPid, callingUid, -1, true)
21468                             != PackageManager.PERMISSION_GRANTED) {
21469                         String msg = "Permission Denial: " + intent.getAction()
21470                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
21471                                 + ", uid=" + callingUid + ")"
21472                                 + " requires "
21473                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
21474                         Slog.w(TAG, msg);
21475                         throw new SecurityException(msg);
21476                     }
21477                     switch (action) {
21478                         case Intent.ACTION_UID_REMOVED:
21479                             final int uid = getUidFromIntent(intent);
21480                             if (uid >= 0) {
21481                                 mBatteryStatsService.removeUid(uid);
21482                                 mAppOpsService.uidRemoved(uid);
21483                             }
21484                             break;
21485                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21486                             // If resources are unavailable just force stop all those packages
21487                             // and flush the attribute cache as well.
21488                             String list[] =
21489                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21490                             if (list != null && list.length > 0) {
21491                                 for (int i = 0; i < list.length; i++) {
21492                                     forceStopPackageLocked(list[i], -1, false, true, true,
21493                                             false, false, userId, "storage unmount");
21494                                 }
21495                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21496                                 sendPackageBroadcastLocked(
21497                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
21498                                         list, userId);
21499                             }
21500                             break;
21501                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21502                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21503                             break;
21504                         case Intent.ACTION_PACKAGE_REMOVED:
21505                         case Intent.ACTION_PACKAGE_CHANGED:
21506                             Uri data = intent.getData();
21507                             String ssp;
21508                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
21509                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
21510                                 final boolean replacing =
21511                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21512                                 final boolean killProcess =
21513                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
21514                                 final boolean fullUninstall = removed && !replacing;
21515                                 if (removed) {
21516                                     if (killProcess) {
21517                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
21518                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
21519                                                 false, true, true, false, fullUninstall, userId,
21520                                                 removed ? "pkg removed" : "pkg changed");
21521                                     }
21522                                     final int cmd = killProcess
21523                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
21524                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
21525                                     sendPackageBroadcastLocked(cmd,
21526                                             new String[] {ssp}, userId);
21527                                     if (fullUninstall) {
21528                                         mAppOpsService.packageRemoved(
21529                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
21530
21531                                         // Remove all permissions granted from/to this package
21532                                         removeUriPermissionsForPackageLocked(ssp, userId, true,
21533                                                 false);
21534
21535                                         mRecentTasks.removeTasksByPackageName(ssp, userId);
21536
21537                                         mServices.forceStopPackageLocked(ssp, userId);
21538                                         mAppWarnings.onPackageUninstalled(ssp);
21539                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
21540                                         mBatteryStatsService.notePackageUninstalled(ssp);
21541                                     }
21542                                 } else {
21543                                     if (killProcess) {
21544                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
21545                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
21546                                                 userId, ProcessList.INVALID_ADJ,
21547                                                 false, true, true, false, "change " + ssp);
21548                                     }
21549                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
21550                                             intent.getStringArrayExtra(
21551                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
21552                                 }
21553                             }
21554                             break;
21555                         case Intent.ACTION_PACKAGES_SUSPENDED:
21556                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
21557                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
21558                                     intent.getAction());
21559                             final String[] packageNames = intent.getStringArrayExtra(
21560                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
21561                             final int userHandle = intent.getIntExtra(
21562                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
21563
21564                             synchronized(ActivityManagerService.this) {
21565                                 mRecentTasks.onPackagesSuspendedChanged(
21566                                         packageNames, suspended, userHandle);
21567                             }
21568                             break;
21569                     }
21570                     break;
21571                 case Intent.ACTION_PACKAGE_REPLACED:
21572                 {
21573                     final Uri data = intent.getData();
21574                     final String ssp;
21575                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21576                         ApplicationInfo aInfo = null;
21577                         try {
21578                             aInfo = AppGlobals.getPackageManager()
21579                                     .getApplicationInfo(ssp, STOCK_PM_FLAGS, userId);
21580                         } catch (RemoteException ignore) {}
21581                         if (aInfo == null) {
21582                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
21583                                     + " ssp=" + ssp + " data=" + data);
21584                             return ActivityManager.BROADCAST_SUCCESS;
21585                         }
21586                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
21587                         mServices.updateServiceApplicationInfoLocked(aInfo);
21588                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
21589                                 new String[] {ssp}, userId);
21590                     }
21591                     break;
21592                 }
21593                 case Intent.ACTION_PACKAGE_ADDED:
21594                 {
21595                     // Special case for adding a package: by default turn on compatibility mode.
21596                     Uri data = intent.getData();
21597                     String ssp;
21598                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21599                         final boolean replacing =
21600                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21601                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
21602
21603                         try {
21604                             ApplicationInfo ai = AppGlobals.getPackageManager().
21605                                     getApplicationInfo(ssp, STOCK_PM_FLAGS, 0);
21606                             mBatteryStatsService.notePackageInstalled(ssp,
21607                                     ai != null ? ai.versionCode : 0);
21608                         } catch (RemoteException e) {
21609                         }
21610                     }
21611                     break;
21612                 }
21613                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
21614                 {
21615                     Uri data = intent.getData();
21616                     String ssp;
21617                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21618                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
21619                         mAppWarnings.onPackageDataCleared(ssp);
21620                     }
21621                     break;
21622                 }
21623                 case Intent.ACTION_TIMEZONE_CHANGED:
21624                     // If this is the time zone changed action, queue up a message that will reset
21625                     // the timezone of all currently running processes. This message will get
21626                     // queued up before the broadcast happens.
21627                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
21628                     break;
21629                 case Intent.ACTION_TIME_CHANGED:
21630                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
21631                     // the tri-state value it may contain and "unknown".
21632                     // For convenience we re-use the Intent extra values.
21633                     final int NO_EXTRA_VALUE_FOUND = -1;
21634                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
21635                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
21636                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
21637                     // Only send a message if the time preference is available.
21638                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
21639                         Message updateTimePreferenceMsg =
21640                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
21641                                         timeFormatPreferenceMsgValue, 0);
21642                         mHandler.sendMessage(updateTimePreferenceMsg);
21643                     }
21644                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21645                     synchronized (stats) {
21646                         stats.noteCurrentTimeChangedLocked();
21647                     }
21648                     break;
21649                 case Intent.ACTION_CLEAR_DNS_CACHE:
21650                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
21651                     break;
21652                 case Proxy.PROXY_CHANGE_ACTION:
21653                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
21654                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
21655                     break;
21656                 case android.hardware.Camera.ACTION_NEW_PICTURE:
21657                 case android.hardware.Camera.ACTION_NEW_VIDEO:
21658                     // In N we just turned these off; in O we are turing them back on partly,
21659                     // only for registered receivers.  This will still address the main problem
21660                     // (a spam of apps waking up when a picture is taken putting significant
21661                     // memory pressure on the system at a bad point), while still allowing apps
21662                     // that are already actively running to know about this happening.
21663                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21664                     break;
21665                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
21666                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
21667                     break;
21668                 case "com.android.launcher.action.INSTALL_SHORTCUT":
21669                     // As of O, we no longer support this broadcasts, even for pre-O apps.
21670                     // Apps should now be using ShortcutManager.pinRequestShortcut().
21671                     Log.w(TAG, "Broadcast " + action
21672                             + " no longer supported. It will not be delivered.");
21673                     return ActivityManager.BROADCAST_SUCCESS;
21674             }
21675
21676             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
21677                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
21678                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
21679                 final int uid = getUidFromIntent(intent);
21680                 if (uid != -1) {
21681                     final UidRecord uidRec = mActiveUids.get(uid);
21682                     if (uidRec != null) {
21683                         uidRec.updateHasInternetPermission();
21684                     }
21685                 }
21686             }
21687         }
21688
21689         // Add to the sticky list if requested.
21690         if (sticky) {
21691             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
21692                     callingPid, callingUid)
21693                     != PackageManager.PERMISSION_GRANTED) {
21694                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
21695                         + callingPid + ", uid=" + callingUid
21696                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21697                 Slog.w(TAG, msg);
21698                 throw new SecurityException(msg);
21699             }
21700             if (requiredPermissions != null && requiredPermissions.length > 0) {
21701                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
21702                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
21703                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
21704             }
21705             if (intent.getComponent() != null) {
21706                 throw new SecurityException(
21707                         "Sticky broadcasts can't target a specific component");
21708             }
21709             // We use userId directly here, since the "all" target is maintained
21710             // as a separate set of sticky broadcasts.
21711             if (userId != UserHandle.USER_ALL) {
21712                 // But first, if this is not a broadcast to all users, then
21713                 // make sure it doesn't conflict with an existing broadcast to
21714                 // all users.
21715                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
21716                         UserHandle.USER_ALL);
21717                 if (stickies != null) {
21718                     ArrayList<Intent> list = stickies.get(intent.getAction());
21719                     if (list != null) {
21720                         int N = list.size();
21721                         int i;
21722                         for (i=0; i<N; i++) {
21723                             if (intent.filterEquals(list.get(i))) {
21724                                 throw new IllegalArgumentException(
21725                                         "Sticky broadcast " + intent + " for user "
21726                                         + userId + " conflicts with existing global broadcast");
21727                             }
21728                         }
21729                     }
21730                 }
21731             }
21732             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21733             if (stickies == null) {
21734                 stickies = new ArrayMap<>();
21735                 mStickyBroadcasts.put(userId, stickies);
21736             }
21737             ArrayList<Intent> list = stickies.get(intent.getAction());
21738             if (list == null) {
21739                 list = new ArrayList<>();
21740                 stickies.put(intent.getAction(), list);
21741             }
21742             final int stickiesCount = list.size();
21743             int i;
21744             for (i = 0; i < stickiesCount; i++) {
21745                 if (intent.filterEquals(list.get(i))) {
21746                     // This sticky already exists, replace it.
21747                     list.set(i, new Intent(intent));
21748                     break;
21749                 }
21750             }
21751             if (i >= stickiesCount) {
21752                 list.add(new Intent(intent));
21753             }
21754         }
21755
21756         int[] users;
21757         if (userId == UserHandle.USER_ALL) {
21758             // Caller wants broadcast to go to all started users.
21759             users = mUserController.getStartedUserArray();
21760         } else {
21761             // Caller wants broadcast to go to one specific user.
21762             users = new int[] {userId};
21763         }
21764
21765         // Figure out who all will receive this broadcast.
21766         List receivers = null;
21767         List<BroadcastFilter> registeredReceivers = null;
21768         // Need to resolve the intent to interested receivers...
21769         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
21770                  == 0) {
21771             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
21772         }
21773         if (intent.getComponent() == null) {
21774             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
21775                 // Query one target user at a time, excluding shell-restricted users
21776                 for (int i = 0; i < users.length; i++) {
21777                     if (mUserController.hasUserRestriction(
21778                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
21779                         continue;
21780                     }
21781                     List<BroadcastFilter> registeredReceiversForUser =
21782                             mReceiverResolver.queryIntent(intent,
21783                                     resolvedType, false /*defaultOnly*/, users[i]);
21784                     if (registeredReceivers == null) {
21785                         registeredReceivers = registeredReceiversForUser;
21786                     } else if (registeredReceiversForUser != null) {
21787                         registeredReceivers.addAll(registeredReceiversForUser);
21788                     }
21789                 }
21790             } else {
21791                 registeredReceivers = mReceiverResolver.queryIntent(intent,
21792                         resolvedType, false /*defaultOnly*/, userId);
21793             }
21794         }
21795
21796         final boolean replacePending =
21797                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
21798
21799         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
21800                 + " replacePending=" + replacePending);
21801
21802         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
21803         if (!ordered && NR > 0) {
21804             // If we are not serializing this broadcast, then send the
21805             // registered receivers separately so they don't wait for the
21806             // components to be launched.
21807             if (isCallerSystem) {
21808                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21809                         isProtectedBroadcast, registeredReceivers);
21810             }
21811             final BroadcastQueue queue = broadcastQueueForIntent(intent);
21812             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21813                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21814                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
21815                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
21816             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
21817             final boolean replaced = replacePending
21818                     && (queue.replaceParallelBroadcastLocked(r) != null);
21819             // Note: We assume resultTo is null for non-ordered broadcasts.
21820             if (!replaced) {
21821                 queue.enqueueParallelBroadcastLocked(r);
21822                 queue.scheduleBroadcastsLocked();
21823             }
21824             registeredReceivers = null;
21825             NR = 0;
21826         }
21827
21828         // Merge into one list.
21829         int ir = 0;
21830         if (receivers != null) {
21831             // A special case for PACKAGE_ADDED: do not allow the package
21832             // being added to see this broadcast.  This prevents them from
21833             // using this as a back door to get run as soon as they are
21834             // installed.  Maybe in the future we want to have a special install
21835             // broadcast or such for apps, but we'd like to deliberately make
21836             // this decision.
21837             String skipPackages[] = null;
21838             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
21839                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
21840                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
21841                 Uri data = intent.getData();
21842                 if (data != null) {
21843                     String pkgName = data.getSchemeSpecificPart();
21844                     if (pkgName != null) {
21845                         skipPackages = new String[] { pkgName };
21846                     }
21847                 }
21848             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
21849                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21850             }
21851             if (skipPackages != null && (skipPackages.length > 0)) {
21852                 for (String skipPackage : skipPackages) {
21853                     if (skipPackage != null) {
21854                         int NT = receivers.size();
21855                         for (int it=0; it<NT; it++) {
21856                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
21857                             if (curt.activityInfo.packageName.equals(skipPackage)) {
21858                                 receivers.remove(it);
21859                                 it--;
21860                                 NT--;
21861                             }
21862                         }
21863                     }
21864                 }
21865             }
21866
21867             int NT = receivers != null ? receivers.size() : 0;
21868             int it = 0;
21869             ResolveInfo curt = null;
21870             BroadcastFilter curr = null;
21871             while (it < NT && ir < NR) {
21872                 if (curt == null) {
21873                     curt = (ResolveInfo)receivers.get(it);
21874                 }
21875                 if (curr == null) {
21876                     curr = registeredReceivers.get(ir);
21877                 }
21878                 if (curr.getPriority() >= curt.priority) {
21879                     // Insert this broadcast record into the final list.
21880                     receivers.add(it, curr);
21881                     ir++;
21882                     curr = null;
21883                     it++;
21884                     NT++;
21885                 } else {
21886                     // Skip to the next ResolveInfo in the final list.
21887                     it++;
21888                     curt = null;
21889                 }
21890             }
21891         }
21892         while (ir < NR) {
21893             if (receivers == null) {
21894                 receivers = new ArrayList();
21895             }
21896             receivers.add(registeredReceivers.get(ir));
21897             ir++;
21898         }
21899
21900         if (isCallerSystem) {
21901             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21902                     isProtectedBroadcast, receivers);
21903         }
21904
21905         if ((receivers != null && receivers.size() > 0)
21906                 || resultTo != null) {
21907             BroadcastQueue queue = broadcastQueueForIntent(intent);
21908             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21909                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21910                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
21911                     resultData, resultExtras, ordered, sticky, false, userId);
21912
21913             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
21914                     + ": prev had " + queue.mOrderedBroadcasts.size());
21915             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
21916                     "Enqueueing broadcast " + r.intent.getAction());
21917
21918             final BroadcastRecord oldRecord =
21919                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
21920             if (oldRecord != null) {
21921                 // Replaced, fire the result-to receiver.
21922                 if (oldRecord.resultTo != null) {
21923                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
21924                     try {
21925                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
21926                                 oldRecord.intent,
21927                                 Activity.RESULT_CANCELED, null, null,
21928                                 false, false, oldRecord.userId);
21929                     } catch (RemoteException e) {
21930                         Slog.w(TAG, "Failure ["
21931                                 + queue.mQueueName + "] sending broadcast result of "
21932                                 + intent, e);
21933
21934                     }
21935                 }
21936             } else {
21937                 queue.enqueueOrderedBroadcastLocked(r);
21938                 queue.scheduleBroadcastsLocked();
21939             }
21940         } else {
21941             // There was nobody interested in the broadcast, but we still want to record
21942             // that it happened.
21943             if (intent.getComponent() == null && intent.getPackage() == null
21944                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21945                 // This was an implicit broadcast... let's record it for posterity.
21946                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
21947             }
21948         }
21949
21950         return ActivityManager.BROADCAST_SUCCESS;
21951     }
21952
21953     /**
21954      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21955      */
21956     private int getUidFromIntent(Intent intent) {
21957         if (intent == null) {
21958             return -1;
21959         }
21960         final Bundle intentExtras = intent.getExtras();
21961         return intent.hasExtra(Intent.EXTRA_UID)
21962                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
21963     }
21964
21965     final void rotateBroadcastStatsIfNeededLocked() {
21966         final long now = SystemClock.elapsedRealtime();
21967         if (mCurBroadcastStats == null ||
21968                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
21969             mLastBroadcastStats = mCurBroadcastStats;
21970             if (mLastBroadcastStats != null) {
21971                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
21972                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
21973             }
21974             mCurBroadcastStats = new BroadcastStats();
21975         }
21976     }
21977
21978     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
21979             int skipCount, long dispatchTime) {
21980         rotateBroadcastStatsIfNeededLocked();
21981         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
21982     }
21983
21984     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21985         rotateBroadcastStatsIfNeededLocked();
21986         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
21987     }
21988
21989     final Intent verifyBroadcastLocked(Intent intent) {
21990         // Refuse possible leaked file descriptors
21991         if (intent != null && intent.hasFileDescriptors() == true) {
21992             throw new IllegalArgumentException("File descriptors passed in Intent");
21993         }
21994
21995         int flags = intent.getFlags();
21996
21997         if (!mProcessesReady) {
21998             // if the caller really truly claims to know what they're doing, go
21999             // ahead and allow the broadcast without launching any receivers
22000             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
22001                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
22002             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
22003                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
22004                         + " before boot completion");
22005                 throw new IllegalStateException("Cannot broadcast before boot completed");
22006             }
22007         }
22008
22009         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
22010             throw new IllegalArgumentException(
22011                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
22012         }
22013
22014         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
22015             switch (Binder.getCallingUid()) {
22016                 case ROOT_UID:
22017                 case SHELL_UID:
22018                     break;
22019                 default:
22020                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
22021                             + Binder.getCallingUid());
22022                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
22023                     break;
22024             }
22025         }
22026
22027         return intent;
22028     }
22029
22030     public final int broadcastIntent(IApplicationThread caller,
22031             Intent intent, String resolvedType, IIntentReceiver resultTo,
22032             int resultCode, String resultData, Bundle resultExtras,
22033             String[] requiredPermissions, int appOp, Bundle bOptions,
22034             boolean serialized, boolean sticky, int userId) {
22035         enforceNotIsolatedCaller("broadcastIntent");
22036         synchronized(this) {
22037             intent = verifyBroadcastLocked(intent);
22038
22039             final ProcessRecord callerApp = getRecordForAppLocked(caller);
22040             final int callingPid = Binder.getCallingPid();
22041             final int callingUid = Binder.getCallingUid();
22042             final long origId = Binder.clearCallingIdentity();
22043             int res = broadcastIntentLocked(callerApp,
22044                     callerApp != null ? callerApp.info.packageName : null,
22045                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
22046                     requiredPermissions, appOp, bOptions, serialized, sticky,
22047                     callingPid, callingUid, userId);
22048             Binder.restoreCallingIdentity(origId);
22049             return res;
22050         }
22051     }
22052
22053
22054     int broadcastIntentInPackage(String packageName, int uid,
22055             Intent intent, String resolvedType, IIntentReceiver resultTo,
22056             int resultCode, String resultData, Bundle resultExtras,
22057             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
22058             int userId) {
22059         synchronized(this) {
22060             intent = verifyBroadcastLocked(intent);
22061
22062             final long origId = Binder.clearCallingIdentity();
22063             String[] requiredPermissions = requiredPermission == null ? null
22064                     : new String[] {requiredPermission};
22065             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
22066                     resultTo, resultCode, resultData, resultExtras,
22067                     requiredPermissions, OP_NONE, bOptions, serialized,
22068                     sticky, -1, uid, userId);
22069             Binder.restoreCallingIdentity(origId);
22070             return res;
22071         }
22072     }
22073
22074     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
22075         // Refuse possible leaked file descriptors
22076         if (intent != null && intent.hasFileDescriptors() == true) {
22077             throw new IllegalArgumentException("File descriptors passed in Intent");
22078         }
22079
22080         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22081                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
22082
22083         synchronized(this) {
22084             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
22085                     != PackageManager.PERMISSION_GRANTED) {
22086                 String msg = "Permission Denial: unbroadcastIntent() from pid="
22087                         + Binder.getCallingPid()
22088                         + ", uid=" + Binder.getCallingUid()
22089                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
22090                 Slog.w(TAG, msg);
22091                 throw new SecurityException(msg);
22092             }
22093             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
22094             if (stickies != null) {
22095                 ArrayList<Intent> list = stickies.get(intent.getAction());
22096                 if (list != null) {
22097                     int N = list.size();
22098                     int i;
22099                     for (i=0; i<N; i++) {
22100                         if (intent.filterEquals(list.get(i))) {
22101                             list.remove(i);
22102                             break;
22103                         }
22104                     }
22105                     if (list.size() <= 0) {
22106                         stickies.remove(intent.getAction());
22107                     }
22108                 }
22109                 if (stickies.size() <= 0) {
22110                     mStickyBroadcasts.remove(userId);
22111                 }
22112             }
22113         }
22114     }
22115
22116     void backgroundServicesFinishedLocked(int userId) {
22117         for (BroadcastQueue queue : mBroadcastQueues) {
22118             queue.backgroundServicesFinishedLocked(userId);
22119         }
22120     }
22121
22122     public void finishReceiver(IBinder who, int resultCode, String resultData,
22123             Bundle resultExtras, boolean resultAbort, int flags) {
22124         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
22125
22126         // Refuse possible leaked file descriptors
22127         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
22128             throw new IllegalArgumentException("File descriptors passed in Bundle");
22129         }
22130
22131         final long origId = Binder.clearCallingIdentity();
22132         try {
22133             boolean doNext = false;
22134             BroadcastRecord r;
22135
22136             synchronized(this) {
22137                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
22138                         ? mFgBroadcastQueue : mBgBroadcastQueue;
22139                 r = queue.getMatchingOrderedReceiver(who);
22140                 if (r != null) {
22141                     doNext = r.queue.finishReceiverLocked(r, resultCode,
22142                         resultData, resultExtras, resultAbort, true);
22143                 }
22144                 if (doNext) {
22145                     r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
22146                 }
22147                 // updateOomAdjLocked() will be done here
22148                 trimApplicationsLocked();
22149             }
22150
22151         } finally {
22152             Binder.restoreCallingIdentity(origId);
22153         }
22154     }
22155
22156     // =========================================================
22157     // INSTRUMENTATION
22158     // =========================================================
22159
22160     public boolean startInstrumentation(ComponentName className,
22161             String profileFile, int flags, Bundle arguments,
22162             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
22163             int userId, String abiOverride) {
22164         enforceNotIsolatedCaller("startInstrumentation");
22165         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22166                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
22167         // Refuse possible leaked file descriptors
22168         if (arguments != null && arguments.hasFileDescriptors()) {
22169             throw new IllegalArgumentException("File descriptors passed in Bundle");
22170         }
22171
22172         synchronized(this) {
22173             InstrumentationInfo ii = null;
22174             ApplicationInfo ai = null;
22175             try {
22176                 ii = mContext.getPackageManager().getInstrumentationInfo(
22177                     className, STOCK_PM_FLAGS);
22178                 ai = AppGlobals.getPackageManager().getApplicationInfo(
22179                         ii.targetPackage, STOCK_PM_FLAGS, userId);
22180             } catch (PackageManager.NameNotFoundException e) {
22181             } catch (RemoteException e) {
22182             }
22183             if (ii == null) {
22184                 reportStartInstrumentationFailureLocked(watcher, className,
22185                         "Unable to find instrumentation info for: " + className);
22186                 return false;
22187             }
22188             if (ai == null) {
22189                 reportStartInstrumentationFailureLocked(watcher, className,
22190                         "Unable to find instrumentation target package: " + ii.targetPackage);
22191                 return false;
22192             }
22193             if (!ai.hasCode()) {
22194                 reportStartInstrumentationFailureLocked(watcher, className,
22195                         "Instrumentation target has no code: " + ii.targetPackage);
22196                 return false;
22197             }
22198
22199             int match = mContext.getPackageManager().checkSignatures(
22200                     ii.targetPackage, ii.packageName);
22201             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
22202                 String msg = "Permission Denial: starting instrumentation "
22203                         + className + " from pid="
22204                         + Binder.getCallingPid()
22205                         + ", uid=" + Binder.getCallingPid()
22206                         + " not allowed because package " + ii.packageName
22207                         + " does not have a signature matching the target "
22208                         + ii.targetPackage;
22209                 reportStartInstrumentationFailureLocked(watcher, className, msg);
22210                 throw new SecurityException(msg);
22211             }
22212
22213             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
22214             activeInstr.mClass = className;
22215             String defProcess = ai.processName;;
22216             if (ii.targetProcesses == null) {
22217                 activeInstr.mTargetProcesses = new String[]{ai.processName};
22218             } else if (ii.targetProcesses.equals("*")) {
22219                 activeInstr.mTargetProcesses = new String[0];
22220             } else {
22221                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
22222                 defProcess = activeInstr.mTargetProcesses[0];
22223             }
22224             activeInstr.mTargetInfo = ai;
22225             activeInstr.mProfileFile = profileFile;
22226             activeInstr.mArguments = arguments;
22227             activeInstr.mWatcher = watcher;
22228             activeInstr.mUiAutomationConnection = uiAutomationConnection;
22229             activeInstr.mResultClass = className;
22230
22231             boolean disableHiddenApiChecks =
22232                     (flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
22233             if (disableHiddenApiChecks) {
22234                 enforceCallingPermission(android.Manifest.permission.DISABLE_HIDDEN_API_CHECKS,
22235                         "disable hidden API checks");
22236             }
22237
22238             final long origId = Binder.clearCallingIdentity();
22239             // Instrumentation can kill and relaunch even persistent processes
22240             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
22241                     "start instr");
22242             // Inform usage stats to make the target package active
22243             if (mUsageStatsService != null) {
22244                 mUsageStatsService.reportEvent(ii.targetPackage, userId,
22245                         UsageEvents.Event.SYSTEM_INTERACTION);
22246             }
22247
22248             ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
22249                     abiOverride);
22250             app.instr = activeInstr;
22251             activeInstr.mFinished = false;
22252             activeInstr.mRunningProcesses.add(app);
22253             if (!mActiveInstrumentation.contains(activeInstr)) {
22254                 mActiveInstrumentation.add(activeInstr);
22255             }
22256             Binder.restoreCallingIdentity(origId);
22257         }
22258
22259         return true;
22260     }
22261
22262     /**
22263      * Report errors that occur while attempting to start Instrumentation.  Always writes the
22264      * error to the logs, but if somebody is watching, send the report there too.  This enables
22265      * the "am" command to report errors with more information.
22266      *
22267      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
22268      * @param cn The component name of the instrumentation.
22269      * @param report The error report.
22270      */
22271     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
22272             ComponentName cn, String report) {
22273         Slog.w(TAG, report);
22274         if (watcher != null) {
22275             Bundle results = new Bundle();
22276             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
22277             results.putString("Error", report);
22278             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
22279         }
22280     }
22281
22282     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
22283         if (app.instr == null) {
22284             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
22285             return;
22286         }
22287
22288         if (!app.instr.mFinished && results != null) {
22289             if (app.instr.mCurResults == null) {
22290                 app.instr.mCurResults = new Bundle(results);
22291             } else {
22292                 app.instr.mCurResults.putAll(results);
22293             }
22294         }
22295     }
22296
22297     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
22298         int userId = UserHandle.getCallingUserId();
22299         // Refuse possible leaked file descriptors
22300         if (results != null && results.hasFileDescriptors()) {
22301             throw new IllegalArgumentException("File descriptors passed in Intent");
22302         }
22303
22304         synchronized(this) {
22305             ProcessRecord app = getRecordForAppLocked(target);
22306             if (app == null) {
22307                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
22308                 return;
22309             }
22310             final long origId = Binder.clearCallingIdentity();
22311             addInstrumentationResultsLocked(app, results);
22312             Binder.restoreCallingIdentity(origId);
22313         }
22314     }
22315
22316     @GuardedBy("this")
22317     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
22318         if (app.instr == null) {
22319             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
22320             return;
22321         }
22322
22323         if (!app.instr.mFinished) {
22324             if (app.instr.mWatcher != null) {
22325                 Bundle finalResults = app.instr.mCurResults;
22326                 if (finalResults != null) {
22327                     if (app.instr.mCurResults != null && results != null) {
22328                         finalResults.putAll(results);
22329                     }
22330                 } else {
22331                     finalResults = results;
22332                 }
22333                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
22334                         app.instr.mClass, resultCode, finalResults);
22335             }
22336
22337             // Can't call out of the system process with a lock held, so post a message.
22338             if (app.instr.mUiAutomationConnection != null) {
22339                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
22340                         app.instr.mUiAutomationConnection).sendToTarget();
22341             }
22342             app.instr.mFinished = true;
22343         }
22344
22345         app.instr.removeProcess(app);
22346         app.instr = null;
22347
22348         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
22349                 "finished inst");
22350     }
22351
22352     public void finishInstrumentation(IApplicationThread target,
22353             int resultCode, Bundle results) {
22354         int userId = UserHandle.getCallingUserId();
22355         // Refuse possible leaked file descriptors
22356         if (results != null && results.hasFileDescriptors()) {
22357             throw new IllegalArgumentException("File descriptors passed in Intent");
22358         }
22359
22360         synchronized(this) {
22361             ProcessRecord app = getRecordForAppLocked(target);
22362             if (app == null) {
22363                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
22364                 return;
22365             }
22366             final long origId = Binder.clearCallingIdentity();
22367             finishInstrumentationLocked(app, resultCode, results);
22368             Binder.restoreCallingIdentity(origId);
22369         }
22370     }
22371
22372     // =========================================================
22373     // CONFIGURATION
22374     // =========================================================
22375
22376     public ConfigurationInfo getDeviceConfigurationInfo() {
22377         ConfigurationInfo config = new ConfigurationInfo();
22378         synchronized (this) {
22379             final Configuration globalConfig = getGlobalConfiguration();
22380             config.reqTouchScreen = globalConfig.touchscreen;
22381             config.reqKeyboardType = globalConfig.keyboard;
22382             config.reqNavigation = globalConfig.navigation;
22383             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
22384                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
22385                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
22386             }
22387             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
22388                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
22389                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
22390             }
22391             config.reqGlEsVersion = GL_ES_VERSION;
22392         }
22393         return config;
22394     }
22395
22396     ActivityStack getFocusedStack() {
22397         return mStackSupervisor.getFocusedStack();
22398     }
22399
22400     @Override
22401     public StackInfo getFocusedStackInfo() throws RemoteException {
22402         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
22403         long ident = Binder.clearCallingIdentity();
22404         try {
22405             synchronized (this) {
22406                 ActivityStack focusedStack = getFocusedStack();
22407                 if (focusedStack != null) {
22408                     return mStackSupervisor.getStackInfo(focusedStack.mStackId);
22409                 }
22410                 return null;
22411             }
22412         } finally {
22413             Binder.restoreCallingIdentity(ident);
22414         }
22415     }
22416
22417     public Configuration getConfiguration() {
22418         Configuration ci;
22419         synchronized(this) {
22420             ci = new Configuration(getGlobalConfiguration());
22421             ci.userSetLocale = false;
22422         }
22423         return ci;
22424     }
22425
22426     @Override
22427     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
22428         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
22429         synchronized (this) {
22430             mSuppressResizeConfigChanges = suppress;
22431         }
22432     }
22433
22434     /**
22435      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
22436      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
22437      *       activity and clearing the task at the same time.
22438      */
22439     @Override
22440     // TODO: API should just be about changing windowing modes...
22441     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
22442         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
22443                 "moveTasksToFullscreenStack()");
22444         synchronized (this) {
22445             final long origId = Binder.clearCallingIdentity();
22446             try {
22447                 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
22448                 if (stack != null){
22449                     if (!stack.isActivityTypeStandardOrUndefined()) {
22450                         throw new IllegalArgumentException(
22451                                 "You can't move tasks from non-standard stacks.");
22452                     }
22453                     mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
22454                 }
22455             } finally {
22456                 Binder.restoreCallingIdentity(origId);
22457             }
22458         }
22459     }
22460
22461     @Override
22462     public void updatePersistentConfiguration(Configuration values) {
22463         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
22464         enforceWriteSettingsPermission("updatePersistentConfiguration()");
22465         if (values == null) {
22466             throw new NullPointerException("Configuration must not be null");
22467         }
22468
22469         int userId = UserHandle.getCallingUserId();
22470
22471         synchronized(this) {
22472             updatePersistentConfigurationLocked(values, userId);
22473         }
22474     }
22475
22476     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
22477         final long origId = Binder.clearCallingIdentity();
22478         try {
22479             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
22480         } finally {
22481             Binder.restoreCallingIdentity(origId);
22482         }
22483     }
22484
22485     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
22486         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
22487                 FONT_SCALE, 1.0f, userId);
22488
22489         synchronized (this) {
22490             if (getGlobalConfiguration().fontScale == scaleFactor) {
22491                 return;
22492             }
22493
22494             final Configuration configuration
22495                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22496             configuration.fontScale = scaleFactor;
22497             updatePersistentConfigurationLocked(configuration, userId);
22498         }
22499     }
22500
22501     private void enforceWriteSettingsPermission(String func) {
22502         int uid = Binder.getCallingUid();
22503         if (uid == ROOT_UID) {
22504             return;
22505         }
22506
22507         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
22508                 Settings.getPackageNameForUid(mContext, uid), false)) {
22509             return;
22510         }
22511
22512         String msg = "Permission Denial: " + func + " from pid="
22513                 + Binder.getCallingPid()
22514                 + ", uid=" + uid
22515                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
22516         Slog.w(TAG, msg);
22517         throw new SecurityException(msg);
22518     }
22519
22520     @Override
22521     public boolean updateConfiguration(Configuration values) {
22522         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
22523
22524         synchronized(this) {
22525             if (values == null && mWindowManager != null) {
22526                 // sentinel: fetch the current configuration from the window manager
22527                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22528             }
22529
22530             if (mWindowManager != null) {
22531                 // Update OOM levels based on display size.
22532                 mProcessList.applyDisplaySize(mWindowManager);
22533             }
22534
22535             final long origId = Binder.clearCallingIdentity();
22536             try {
22537                 if (values != null) {
22538                     Settings.System.clearConfiguration(values);
22539                 }
22540                 updateConfigurationLocked(values, null, false, false /* persistent */,
22541                         UserHandle.USER_NULL, false /* deferResume */,
22542                         mTmpUpdateConfigurationResult);
22543                 return mTmpUpdateConfigurationResult.changes != 0;
22544             } finally {
22545                 Binder.restoreCallingIdentity(origId);
22546             }
22547         }
22548     }
22549
22550     void updateUserConfigurationLocked() {
22551         final Configuration configuration = new Configuration(getGlobalConfiguration());
22552         final int currentUserId = mUserController.getCurrentUserId();
22553         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
22554                 currentUserId, Settings.System.canWrite(mContext));
22555         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
22556                 false /* persistent */, currentUserId, false /* deferResume */);
22557     }
22558
22559     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22560             boolean initLocale) {
22561         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
22562     }
22563
22564     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22565             boolean initLocale, boolean deferResume) {
22566         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
22567         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
22568                 UserHandle.USER_NULL, deferResume);
22569     }
22570
22571     // To cache the list of supported system locales
22572     private String[] mSupportedSystemLocales = null;
22573
22574     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22575             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
22576         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
22577                 deferResume, null /* result */);
22578     }
22579
22580     /**
22581      * Do either or both things: (1) change the current configuration, and (2)
22582      * make sure the given activity is running with the (now) current
22583      * configuration.  Returns true if the activity has been left running, or
22584      * false if <var>starting</var> is being destroyed to match the new
22585      * configuration.
22586      *
22587      * @param userId is only used when persistent parameter is set to true to persist configuration
22588      *               for that particular user
22589      */
22590     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22591             boolean initLocale, boolean persistent, int userId, boolean deferResume,
22592             UpdateConfigurationResult result) {
22593         int changes = 0;
22594         boolean kept = true;
22595
22596         if (mWindowManager != null) {
22597             mWindowManager.deferSurfaceLayout();
22598         }
22599         try {
22600             if (values != null) {
22601                 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
22602                         deferResume);
22603             }
22604
22605             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22606         } finally {
22607             if (mWindowManager != null) {
22608                 mWindowManager.continueSurfaceLayout();
22609             }
22610         }
22611
22612         if (result != null) {
22613             result.changes = changes;
22614             result.activityRelaunched = !kept;
22615         }
22616         return kept;
22617     }
22618
22619     /**
22620      * Returns true if this configuration change is interesting enough to send an
22621      * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
22622      */
22623     private static boolean isSplitConfigurationChange(int configDiff) {
22624         return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
22625     }
22626
22627     /** Update default (global) configuration and notify listeners about changes. */
22628     private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
22629             boolean persistent, int userId, boolean deferResume) {
22630         mTempConfig.setTo(getGlobalConfiguration());
22631         final int changes = mTempConfig.updateFrom(values);
22632         if (changes == 0) {
22633             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
22634             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
22635             // performDisplayOverrideConfigUpdate in order to send the new display configuration
22636             // (even if there are no actual changes) to unfreeze the window.
22637             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
22638             return 0;
22639         }
22640
22641         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
22642                 "Updating global configuration to: " + values);
22643
22644         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
22645         StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
22646                 values.colorMode,
22647                 values.densityDpi,
22648                 values.fontScale,
22649                 values.hardKeyboardHidden,
22650                 values.keyboard,
22651                 values.keyboardHidden,
22652                 values.mcc,
22653                 values.mnc,
22654                 values.navigation,
22655                 values.navigationHidden,
22656                 values.orientation,
22657                 values.screenHeightDp,
22658                 values.screenLayout,
22659                 values.screenWidthDp,
22660                 values.smallestScreenWidthDp,
22661                 values.touchscreen,
22662                 values.uiMode);
22663
22664
22665         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
22666             final LocaleList locales = values.getLocales();
22667             int bestLocaleIndex = 0;
22668             if (locales.size() > 1) {
22669                 if (mSupportedSystemLocales == null) {
22670                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
22671                 }
22672                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
22673             }
22674             SystemProperties.set("persist.sys.locale",
22675                     locales.get(bestLocaleIndex).toLanguageTag());
22676             LocaleList.setDefault(locales, bestLocaleIndex);
22677             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
22678                     locales.get(bestLocaleIndex)));
22679         }
22680
22681         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
22682         mTempConfig.seq = mConfigurationSeq;
22683
22684         // Update stored global config and notify everyone about the change.
22685         mStackSupervisor.onConfigurationChanged(mTempConfig);
22686
22687         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
22688         // TODO(multi-display): Update UsageEvents#Event to include displayId.
22689         mUsageStatsService.reportConfigurationChange(mTempConfig,
22690                 mUserController.getCurrentUserId());
22691
22692         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
22693         updateShouldShowDialogsLocked(mTempConfig);
22694
22695         AttributeCache ac = AttributeCache.instance();
22696         if (ac != null) {
22697             ac.updateConfiguration(mTempConfig);
22698         }
22699
22700         // Make sure all resources in our process are updated right now, so that anyone who is going
22701         // to retrieve resource values after we return will be sure to get the new ones. This is
22702         // especially important during boot, where the first config change needs to guarantee all
22703         // resources have that config before following boot code is executed.
22704         mSystemThread.applyConfigurationToResources(mTempConfig);
22705
22706         // We need another copy of global config because we're scheduling some calls instead of
22707         // running them in place. We need to be sure that object we send will be handled unchanged.
22708         final Configuration configCopy = new Configuration(mTempConfig);
22709         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
22710             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
22711             msg.obj = configCopy;
22712             msg.arg1 = userId;
22713             mHandler.sendMessage(msg);
22714         }
22715
22716         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22717             ProcessRecord app = mLruProcesses.get(i);
22718             try {
22719                 if (app.thread != null) {
22720                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
22721                             + app.processName + " new config " + configCopy);
22722                     mLifecycleManager.scheduleTransaction(app.thread,
22723                             ConfigurationChangeItem.obtain(configCopy));
22724                 }
22725             } catch (Exception e) {
22726                 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
22727             }
22728         }
22729
22730         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
22731         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
22732                 | Intent.FLAG_RECEIVER_FOREGROUND
22733                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22734         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22735                 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22736                 UserHandle.USER_ALL);
22737         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
22738             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
22739             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
22740                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
22741                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22742             if (initLocale || !mProcessesReady) {
22743                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
22744             }
22745             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22746                     OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22747                     UserHandle.USER_ALL);
22748         }
22749
22750         // Send a broadcast to PackageInstallers if the configuration change is interesting
22751         // for the purposes of installing additional splits.
22752         if (!initLocale && isSplitConfigurationChange(changes)) {
22753             intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
22754             intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
22755                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
22756
22757             // Typically only app stores will have this permission.
22758             String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
22759             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
22760                     OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
22761         }
22762
22763         // Override configuration of the default display duplicates global config, so we need to
22764         // update it also. This will also notify WindowManager about changes.
22765         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
22766                 DEFAULT_DISPLAY);
22767
22768         return changes;
22769     }
22770
22771     @Override
22772     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
22773         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
22774
22775         synchronized (this) {
22776             // Check if display is initialized in AM.
22777             if (!mStackSupervisor.isDisplayAdded(displayId)) {
22778                 // Call might come when display is not yet added or has already been removed.
22779                 if (DEBUG_CONFIGURATION) {
22780                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
22781                             + displayId);
22782                 }
22783                 return false;
22784             }
22785
22786             if (values == null && mWindowManager != null) {
22787                 // sentinel: fetch the current configuration from the window manager
22788                 values = mWindowManager.computeNewConfiguration(displayId);
22789             }
22790
22791             if (mWindowManager != null) {
22792                 // Update OOM levels based on display size.
22793                 mProcessList.applyDisplaySize(mWindowManager);
22794             }
22795
22796             final long origId = Binder.clearCallingIdentity();
22797             try {
22798                 if (values != null) {
22799                     Settings.System.clearConfiguration(values);
22800                 }
22801                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
22802                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
22803                 return mTmpUpdateConfigurationResult.changes != 0;
22804             } finally {
22805                 Binder.restoreCallingIdentity(origId);
22806             }
22807         }
22808     }
22809
22810     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
22811             boolean deferResume, int displayId) {
22812         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
22813                 displayId, null /* result */);
22814     }
22815
22816     /**
22817      * Updates override configuration specific for the selected display. If no config is provided,
22818      * new one will be computed in WM based on current display info.
22819      */
22820     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
22821             ActivityRecord starting, boolean deferResume, int displayId,
22822             UpdateConfigurationResult result) {
22823         int changes = 0;
22824         boolean kept = true;
22825
22826         if (mWindowManager != null) {
22827             mWindowManager.deferSurfaceLayout();
22828         }
22829         try {
22830             if (values != null) {
22831                 if (displayId == DEFAULT_DISPLAY) {
22832                     // Override configuration of the default display duplicates global config, so
22833                     // we're calling global config update instead for default display. It will also
22834                     // apply the correct override config.
22835                     changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
22836                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
22837                 } else {
22838                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
22839                 }
22840             }
22841
22842             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22843         } finally {
22844             if (mWindowManager != null) {
22845                 mWindowManager.continueSurfaceLayout();
22846             }
22847         }
22848
22849         if (result != null) {
22850             result.changes = changes;
22851             result.activityRelaunched = !kept;
22852         }
22853         return kept;
22854     }
22855
22856     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
22857             int displayId) {
22858         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
22859         final int changes = mTempConfig.updateFrom(values);
22860         if (changes != 0) {
22861             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
22862                     + mTempConfig + " for displayId=" + displayId);
22863             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
22864
22865             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
22866             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
22867                 mAppWarnings.onDensityChanged();
22868
22869                 killAllBackgroundProcessesExcept(N,
22870                         ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
22871             }
22872         }
22873
22874         // Update the configuration with WM first and check if any of the stacks need to be resized
22875         // due to the configuration change. If so, resize the stacks now and do any relaunches if
22876         // necessary. This way we don't need to relaunch again afterwards in
22877         // ensureActivityConfiguration().
22878         if (mWindowManager != null) {
22879             final int[] resizedStacks =
22880                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
22881             if (resizedStacks != null) {
22882                 for (int stackId : resizedStacks) {
22883                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
22884                 }
22885             }
22886         }
22887
22888         return changes;
22889     }
22890
22891     /** Applies latest configuration and/or visibility updates if needed. */
22892     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
22893         boolean kept = true;
22894         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
22895         // mainStack is null during startup.
22896         if (mainStack != null) {
22897             if (changes != 0 && starting == null) {
22898                 // If the configuration changed, and the caller is not already
22899                 // in the process of starting an activity, then find the top
22900                 // activity to check if its configuration needs to change.
22901                 starting = mainStack.topRunningActivityLocked();
22902             }
22903
22904             if (starting != null) {
22905                 kept = starting.ensureActivityConfiguration(changes,
22906                         false /* preserveWindow */);
22907                 // And we need to make sure at this point that all other activities
22908                 // are made visible with the correct configuration.
22909                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
22910                         !PRESERVE_WINDOWS);
22911             }
22912         }
22913
22914         return kept;
22915     }
22916
22917     /** Helper method that requests bounds from WM and applies them to stack. */
22918     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
22919         final Rect newStackBounds = new Rect();
22920         final ActivityStack stack = mStackSupervisor.getStack(stackId);
22921
22922         // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
22923         if (stack == null) {
22924             final StringWriter writer = new StringWriter();
22925             final PrintWriter printWriter = new PrintWriter(writer);
22926             mStackSupervisor.dumpDisplays(printWriter);
22927             printWriter.flush();
22928
22929             Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
22930         }
22931
22932         stack.getBoundsForNewConfiguration(newStackBounds);
22933         mStackSupervisor.resizeStackLocked(
22934                 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
22935                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
22936                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
22937     }
22938
22939     /**
22940      * Decide based on the configuration whether we should show the ANR,
22941      * crash, etc dialogs.  The idea is that if there is no affordance to
22942      * press the on-screen buttons, or the user experience would be more
22943      * greatly impacted than the crash itself, we shouldn't show the dialog.
22944      *
22945      * A thought: SystemUI might also want to get told about this, the Power
22946      * dialog / global actions also might want different behaviors.
22947      */
22948     private void updateShouldShowDialogsLocked(Configuration config) {
22949         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
22950                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
22951                                    && config.navigation == Configuration.NAVIGATION_NONAV);
22952         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
22953         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
22954                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
22955                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
22956                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
22957         final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
22958                 HIDE_ERROR_DIALOGS, 0) != 0;
22959         mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
22960     }
22961
22962     @Override
22963     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
22964         synchronized (this) {
22965             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
22966             if (srec != null) {
22967                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
22968             }
22969         }
22970         return false;
22971     }
22972
22973     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22974             Intent resultData) {
22975
22976         synchronized (this) {
22977             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22978             if (r != null) {
22979                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22980             }
22981             return false;
22982         }
22983     }
22984
22985     public int getLaunchedFromUid(IBinder activityToken) {
22986         ActivityRecord srec;
22987         synchronized (this) {
22988             srec = ActivityRecord.forTokenLocked(activityToken);
22989         }
22990         if (srec == null) {
22991             return -1;
22992         }
22993         return srec.launchedFromUid;
22994     }
22995
22996     public String getLaunchedFromPackage(IBinder activityToken) {
22997         ActivityRecord srec;
22998         synchronized (this) {
22999             srec = ActivityRecord.forTokenLocked(activityToken);
23000         }
23001         if (srec == null) {
23002             return null;
23003         }
23004         return srec.launchedFromPackage;
23005     }
23006
23007     // =========================================================
23008     // LIFETIME MANAGEMENT
23009     // =========================================================
23010
23011     // Returns whether the app is receiving broadcast.
23012     // If receiving, fetch all broadcast queues which the app is
23013     // the current [or imminent] receiver on.
23014     private boolean isReceivingBroadcastLocked(ProcessRecord app,
23015             ArraySet<BroadcastQueue> receivingQueues) {
23016         final int N = app.curReceivers.size();
23017         if (N > 0) {
23018             for (int i = 0; i < N; i++) {
23019                 receivingQueues.add(app.curReceivers.valueAt(i).queue);
23020             }
23021             return true;
23022         }
23023
23024         // It's not the current receiver, but it might be starting up to become one
23025         for (BroadcastQueue queue : mBroadcastQueues) {
23026             final BroadcastRecord r = queue.mPendingBroadcast;
23027             if (r != null && r.curApp == app) {
23028                 // found it; report which queue it's in
23029                 receivingQueues.add(queue);
23030             }
23031         }
23032
23033         return !receivingQueues.isEmpty();
23034     }
23035
23036     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
23037             int targetUid, ComponentName targetComponent, String targetProcess) {
23038         if (!mTrackingAssociations) {
23039             return null;
23040         }
23041         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
23042                 = mAssociations.get(targetUid);
23043         if (components == null) {
23044             components = new ArrayMap<>();
23045             mAssociations.put(targetUid, components);
23046         }
23047         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
23048         if (sourceUids == null) {
23049             sourceUids = new SparseArray<>();
23050             components.put(targetComponent, sourceUids);
23051         }
23052         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
23053         if (sourceProcesses == null) {
23054             sourceProcesses = new ArrayMap<>();
23055             sourceUids.put(sourceUid, sourceProcesses);
23056         }
23057         Association ass = sourceProcesses.get(sourceProcess);
23058         if (ass == null) {
23059             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
23060                     targetProcess);
23061             sourceProcesses.put(sourceProcess, ass);
23062         }
23063         ass.mCount++;
23064         ass.mNesting++;
23065         if (ass.mNesting == 1) {
23066             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
23067             ass.mLastState = sourceState;
23068         }
23069         return ass;
23070     }
23071
23072     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
23073             ComponentName targetComponent) {
23074         if (!mTrackingAssociations) {
23075             return;
23076         }
23077         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
23078                 = mAssociations.get(targetUid);
23079         if (components == null) {
23080             return;
23081         }
23082         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
23083         if (sourceUids == null) {
23084             return;
23085         }
23086         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
23087         if (sourceProcesses == null) {
23088             return;
23089         }
23090         Association ass = sourceProcesses.get(sourceProcess);
23091         if (ass == null || ass.mNesting <= 0) {
23092             return;
23093         }
23094         ass.mNesting--;
23095         if (ass.mNesting == 0) {
23096             long uptime = SystemClock.uptimeMillis();
23097             ass.mTime += uptime - ass.mStartTime;
23098             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
23099                     += uptime - ass.mLastStateUptime;
23100             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
23101         }
23102     }
23103
23104     private void noteUidProcessState(final int uid, final int state) {
23105         mBatteryStatsService.noteUidProcessState(uid, state);
23106         mAppOpsService.updateUidProcState(uid, state);
23107         if (mTrackingAssociations) {
23108             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
23109                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
23110                         = mAssociations.valueAt(i1);
23111                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
23112                     SparseArray<ArrayMap<String, Association>> sourceUids
23113                             = targetComponents.valueAt(i2);
23114                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
23115                     if (sourceProcesses != null) {
23116                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
23117                             Association ass = sourceProcesses.valueAt(i4);
23118                             if (ass.mNesting >= 1) {
23119                                 // currently associated
23120                                 long uptime = SystemClock.uptimeMillis();
23121                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
23122                                         += uptime - ass.mLastStateUptime;
23123                                 ass.mLastState = state;
23124                                 ass.mLastStateUptime = uptime;
23125                             }
23126                         }
23127                     }
23128                 }
23129             }
23130         }
23131     }
23132
23133     private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
23134             boolean doingAll, long now) {
23135         if (mAdjSeq == app.adjSeq) {
23136             if (app.adjSeq == app.completedAdjSeq) {
23137                 // This adjustment has already been computed successfully.
23138                 return false;
23139             } else {
23140                 // The process is being computed, so there is a cycle. We cannot
23141                 // rely on this process's state.
23142                 app.containsCycle = true;
23143
23144                 return false;
23145             }
23146         }
23147
23148         if (app.thread == null) {
23149             app.adjSeq = mAdjSeq;
23150             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23151             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23152             app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ;
23153             app.completedAdjSeq = app.adjSeq;
23154             return false;
23155         }
23156
23157         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
23158         app.adjSource = null;
23159         app.adjTarget = null;
23160         app.empty = false;
23161         app.cached = false;
23162
23163         final int activitiesSize = app.activities.size();
23164         final int appUid = app.info.uid;
23165         final int logUid = mCurOomAdjUid;
23166
23167         int prevAppAdj = app.curAdj;
23168         int prevProcState = app.curProcState;
23169
23170         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
23171             // The max adjustment doesn't allow this app to be anything
23172             // below foreground, so it is not worth doing work for it.
23173             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23174                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making fixed: " + app);
23175             }
23176             app.adjType = "fixed";
23177             app.adjSeq = mAdjSeq;
23178             app.curRawAdj = app.maxAdj;
23179             app.foregroundActivities = false;
23180             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23181             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
23182             // System processes can do UI, and when they do we want to have
23183             // them trim their memory after the user leaves the UI.  To
23184             // facilitate this, here we need to determine whether or not it
23185             // is currently showing UI.
23186             app.systemNoUi = true;
23187             if (app == TOP_APP) {
23188                 app.systemNoUi = false;
23189                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23190                 app.adjType = "pers-top-activity";
23191             } else if (app.hasTopUi) {
23192                 // sched group/proc state adjustment is below
23193                 app.systemNoUi = false;
23194                 app.adjType = "pers-top-ui";
23195             } else if (activitiesSize > 0) {
23196                 for (int j = 0; j < activitiesSize; j++) {
23197                     final ActivityRecord r = app.activities.get(j);
23198                     if (r.visible) {
23199                         app.systemNoUi = false;
23200                     }
23201                 }
23202             }
23203             if (!app.systemNoUi) {
23204               if (mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE) {
23205                   // screen on, promote UI
23206                   app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
23207                   app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23208               } else {
23209                   // screen off, restrict UI scheduling
23210                   app.curProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23211                   app.curSchedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
23212               }
23213             }
23214             app.curAdj = app.maxAdj;
23215             app.completedAdjSeq = app.adjSeq;
23216             // if curAdj is less than prevAppAdj, then this process was promoted
23217             return app.curAdj < prevAppAdj;
23218         }
23219
23220         app.systemNoUi = false;
23221
23222         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
23223
23224         // Determine the importance of the process, starting with most
23225         // important to least, and assign an appropriate OOM adjustment.
23226         int adj;
23227         int schedGroup;
23228         int procState;
23229         int cachedAdjSeq;
23230
23231         boolean foregroundActivities = false;
23232         mTmpBroadcastQueue.clear();
23233         if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
23234             // The last app on the list is the foreground app.
23235             adj = ProcessList.FOREGROUND_APP_ADJ;
23236             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23237             app.adjType = "top-activity";
23238             foregroundActivities = true;
23239             procState = PROCESS_STATE_CUR_TOP;
23240             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23241                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
23242             }
23243         } else if (app.runningRemoteAnimation) {
23244             adj = ProcessList.VISIBLE_APP_ADJ;
23245             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23246             app.adjType = "running-remote-anim";
23247             procState = PROCESS_STATE_CUR_TOP;
23248             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23249                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app);
23250             }
23251         } else if (app.instr != null) {
23252             // Don't want to kill running instrumentation.
23253             adj = ProcessList.FOREGROUND_APP_ADJ;
23254             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23255             app.adjType = "instrumentation";
23256             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
23257             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23258                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app);
23259             }
23260         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
23261             // An app that is currently receiving a broadcast also
23262             // counts as being in the foreground for OOM killer purposes.
23263             // It's placed in a sched group based on the nature of the
23264             // broadcast as reflected by which queue it's active in.
23265             adj = ProcessList.FOREGROUND_APP_ADJ;
23266             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
23267                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
23268             app.adjType = "broadcast";
23269             procState = ActivityManager.PROCESS_STATE_RECEIVER;
23270             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23271                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app);
23272             }
23273         } else if (app.executingServices.size() > 0) {
23274             // An app that is currently executing a service callback also
23275             // counts as being in the foreground.
23276             adj = ProcessList.FOREGROUND_APP_ADJ;
23277             schedGroup = app.execServicesFg ?
23278                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
23279             app.adjType = "exec-service";
23280             procState = ActivityManager.PROCESS_STATE_SERVICE;
23281             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23282                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app);
23283             }
23284             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
23285         } else if (app == TOP_APP) {
23286             adj = ProcessList.FOREGROUND_APP_ADJ;
23287             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23288             app.adjType = "top-sleeping";
23289             foregroundActivities = true;
23290             procState = PROCESS_STATE_CUR_TOP;
23291             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23292                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + app);
23293             }
23294         } else {
23295             // As far as we know the process is empty.  We may change our mind later.
23296             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23297             // At this point we don't actually know the adjustment.  Use the cached adj
23298             // value that the caller wants us to.
23299             adj = cachedAdj;
23300             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23301             app.cached = true;
23302             app.empty = true;
23303             app.adjType = "cch-empty";
23304             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23305                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app);
23306             }
23307         }
23308
23309         // Examine all activities if not already foreground.
23310         if (!foregroundActivities && activitiesSize > 0) {
23311             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
23312             for (int j = 0; j < activitiesSize; j++) {
23313                 final ActivityRecord r = app.activities.get(j);
23314                 if (r.app != app) {
23315                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
23316                             + " instead of expected " + app);
23317                     if (r.app == null || (r.app.uid == app.uid)) {
23318                         // Only fix things up when they look sane
23319                         r.setProcess(app);
23320                     } else {
23321                         continue;
23322                     }
23323                 }
23324                 if (r.visible) {
23325                     // App has a visible activity; only upgrade adjustment.
23326                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
23327                         adj = ProcessList.VISIBLE_APP_ADJ;
23328                         app.adjType = "vis-activity";
23329                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23330                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
23331                                     "Raise adj to vis-activity: " + app);
23332                         }
23333                     }
23334                     if (procState > PROCESS_STATE_CUR_TOP) {
23335                         procState = PROCESS_STATE_CUR_TOP;
23336                         app.adjType = "vis-activity";
23337                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23338                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
23339                                     "Raise procstate to vis-activity (top): " + app);
23340                         }
23341                     }
23342                     if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23343                         schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23344                     }
23345                     app.cached = false;
23346                     app.empty = false;
23347                     foregroundActivities = true;
23348                     final TaskRecord task = r.getTask();
23349                     if (task != null && minLayer > 0) {
23350                         final int layer = task.mLayerRank;
23351                         if (layer >= 0 && minLayer > layer) {
23352                             minLayer = layer;
23353                         }
23354                     }
23355                     break;
23356                 } else if (r.isState(ActivityState.PAUSING, ActivityState.PAUSED)) {
23357                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23358                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23359                         app.adjType = "pause-activity";
23360                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23361                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
23362                                     "Raise adj to pause-activity: "  + app);
23363                         }
23364                     }
23365                     if (procState > PROCESS_STATE_CUR_TOP) {
23366                         procState = PROCESS_STATE_CUR_TOP;
23367                         app.adjType = "pause-activity";
23368                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23369                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
23370                                     "Raise procstate to pause-activity (top): "  + app);
23371                         }
23372                     }
23373                     if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23374                         schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23375                     }
23376                     app.cached = false;
23377                     app.empty = false;
23378                     foregroundActivities = true;
23379                 } else if (r.isState(ActivityState.STOPPING)) {
23380                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23381                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23382                         app.adjType = "stop-activity";
23383                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23384                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
23385                                     "Raise adj to stop-activity: "  + app);
23386                         }
23387                     }
23388                     // For the process state, we will at this point consider the
23389                     // process to be cached.  It will be cached either as an activity
23390                     // or empty depending on whether the activity is finishing.  We do
23391                     // this so that we can treat the process as cached for purposes of
23392                     // memory trimming (determing current memory level, trim command to
23393                     // send to process) since there can be an arbitrary number of stopping
23394                     // processes and they should soon all go into the cached state.
23395                     if (!r.finishing) {
23396                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23397                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23398                             app.adjType = "stop-activity";
23399                             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23400                                 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23401                                         "Raise procstate to stop-activity: " + app);
23402                             }
23403                         }
23404                     }
23405                     app.cached = false;
23406                     app.empty = false;
23407                     foregroundActivities = true;
23408                 } else {
23409                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23410                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23411                         app.adjType = "cch-act";
23412                         if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23413                             reportOomAdjMessageLocked(TAG_OOM_ADJ,
23414                                     "Raise procstate to cached activity: " + app);
23415                         }
23416                     }
23417                 }
23418             }
23419             if (adj == ProcessList.VISIBLE_APP_ADJ) {
23420                 adj += minLayer;
23421             }
23422         }
23423         if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
23424             procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
23425             app.adjType = "cch-rec";
23426             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23427                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to cached recent: " + app);
23428             }
23429         }
23430
23431         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
23432                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
23433             if (app.foregroundServices) {
23434                 // The user is aware of this app, so make it visible.
23435                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23436                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
23437                 app.cached = false;
23438                 app.adjType = "fg-service";
23439                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23440                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23441                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to fg service: " + app);
23442                 }
23443             } else if (app.hasOverlayUi) {
23444                 // The process is display an overlay UI.
23445                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23446                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23447                 app.cached = false;
23448                 app.adjType = "has-overlay-ui";
23449                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23450                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23451                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to overlay ui: " + app);
23452                 }
23453             }
23454         }
23455
23456         // If the app was recently in the foreground and moved to a foreground service status,
23457         // allow it to get a higher rank in memory for some time, compared to other foreground
23458         // services so that it can finish performing any persistence/processing of in-memory state.
23459         if (app.foregroundServices && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
23460                 && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now
23461                     || app.setProcState <= ActivityManager.PROCESS_STATE_TOP)) {
23462             adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
23463             app.adjType = "fg-service-act";
23464             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23465                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app);
23466             }
23467         }
23468
23469         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
23470                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23471             if (app.forcingToImportant != null) {
23472                 // This is currently used for toasts...  they are not interactive, and
23473                 // we don't want them to cause the app to become fully foreground (and
23474                 // thus out of background check), so we yes the best background level we can.
23475                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23476                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23477                 app.cached = false;
23478                 app.adjType = "force-imp";
23479                 app.adjSource = app.forcingToImportant;
23480                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23481                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23482                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to force imp: " + app);
23483                 }
23484             }
23485         }
23486
23487         if (app == mHeavyWeightProcess) {
23488             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
23489                 // We don't want to kill the current heavy-weight process.
23490                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
23491                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23492                 app.cached = false;
23493                 app.adjType = "heavy";
23494                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23495                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to heavy: " + app);
23496                 }
23497             }
23498             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
23499                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
23500                 app.adjType = "heavy";
23501                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23502                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to heavy: " + app);
23503                 }
23504             }
23505         }
23506
23507         if (app == mHomeProcess) {
23508             if (adj > ProcessList.HOME_APP_ADJ) {
23509                 // This process is hosting what we currently consider to be the
23510                 // home app, so we don't want to let it go into the background.
23511                 adj = ProcessList.HOME_APP_ADJ;
23512                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23513                 app.cached = false;
23514                 app.adjType = "home";
23515                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23516                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to home: " + app);
23517                 }
23518             }
23519             if (procState > ActivityManager.PROCESS_STATE_HOME) {
23520                 procState = ActivityManager.PROCESS_STATE_HOME;
23521                 app.adjType = "home";
23522                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23523                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to home: " + app);
23524                 }
23525             }
23526         }
23527
23528         if (app == mPreviousProcess && app.activities.size() > 0) {
23529             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23530                 // This was the previous process that showed UI to the user.
23531                 // We want to try to keep it around more aggressively, to give
23532                 // a good experience around switching between two apps.
23533                 adj = ProcessList.PREVIOUS_APP_ADJ;
23534                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23535                 app.cached = false;
23536                 app.adjType = "previous";
23537                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23538                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app);
23539                 }
23540             }
23541             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23542                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23543                 app.adjType = "previous";
23544                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23545                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app);
23546                 }
23547             }
23548         }
23549
23550         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
23551                 + " reason=" + app.adjType);
23552
23553         // By default, we use the computed adjustment.  It may be changed if
23554         // there are applications dependent on our services or providers, but
23555         // this gives us a baseline and makes sure we don't get into an
23556         // infinite recursion.
23557         app.curRawAdj = adj;
23558         app.hasStartedServices = false;
23559         app.adjSeq = mAdjSeq;
23560
23561         if (mBackupTarget != null && app == mBackupTarget.app) {
23562             // If possible we want to avoid killing apps while they're being backed up
23563             if (adj > ProcessList.BACKUP_APP_ADJ) {
23564                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
23565                 adj = ProcessList.BACKUP_APP_ADJ;
23566                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23567                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23568                 }
23569                 app.adjType = "backup";
23570                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23571                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app);
23572                 }
23573                 app.cached = false;
23574             }
23575             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
23576                 procState = ActivityManager.PROCESS_STATE_BACKUP;
23577                 app.adjType = "backup";
23578                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23579                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to backup: " + app);
23580                 }
23581             }
23582         }
23583
23584         boolean mayBeTop = false;
23585         String mayBeTopType = null;
23586         Object mayBeTopSource = null;
23587         Object mayBeTopTarget = null;
23588
23589         for (int is = app.services.size()-1;
23590                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23591                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23592                         || procState > ActivityManager.PROCESS_STATE_TOP);
23593                 is--) {
23594             ServiceRecord s = app.services.valueAt(is);
23595             if (s.startRequested) {
23596                 app.hasStartedServices = true;
23597                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
23598                     procState = ActivityManager.PROCESS_STATE_SERVICE;
23599                     app.adjType = "started-services";
23600                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23601                         reportOomAdjMessageLocked(TAG_OOM_ADJ,
23602                                 "Raise procstate to started service: " + app);
23603                     }
23604                 }
23605                 if (app.hasShownUi && app != mHomeProcess) {
23606                     // If this process has shown some UI, let it immediately
23607                     // go to the LRU list because it may be pretty heavy with
23608                     // UI stuff.  We'll tag it with a label just to help
23609                     // debug and understand what is going on.
23610                     if (adj > ProcessList.SERVICE_ADJ) {
23611                         app.adjType = "cch-started-ui-services";
23612                     }
23613                 } else {
23614                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23615                         // This service has seen some activity within
23616                         // recent memory, so we will keep its process ahead
23617                         // of the background processes.
23618                         if (adj > ProcessList.SERVICE_ADJ) {
23619                             adj = ProcessList.SERVICE_ADJ;
23620                             app.adjType = "started-services";
23621                             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23622                                 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23623                                         "Raise adj to started service: " + app);
23624                             }
23625                             app.cached = false;
23626                         }
23627                     }
23628                     // If we have let the service slide into the background
23629                     // state, still have some text describing what it is doing
23630                     // even though the service no longer has an impact.
23631                     if (adj > ProcessList.SERVICE_ADJ) {
23632                         app.adjType = "cch-started-services";
23633                     }
23634                 }
23635             }
23636
23637             for (int conni = s.connections.size()-1;
23638                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23639                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23640                             || procState > ActivityManager.PROCESS_STATE_TOP);
23641                     conni--) {
23642                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
23643                 for (int i = 0;
23644                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
23645                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23646                                 || procState > ActivityManager.PROCESS_STATE_TOP);
23647                         i++) {
23648                     // XXX should compute this based on the max of
23649                     // all connected clients.
23650                     ConnectionRecord cr = clist.get(i);
23651                     if (cr.binding.client == app) {
23652                         // Binding to ourself is not interesting.
23653                         continue;
23654                     }
23655
23656                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
23657                         ProcessRecord client = cr.binding.client;
23658                         computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23659                         if (client.containsCycle) {
23660                             // We've detected a cycle. We should retry computeOomAdjLocked later in
23661                             // case a later-checked connection from a client  would raise its
23662                             // priority legitimately.
23663                             app.containsCycle = true;
23664                             // If the client has not been completely evaluated, skip using its
23665                             // priority. Else use the conservative value for now and look for a
23666                             // better state in the next iteration.
23667                             if (client.completedAdjSeq < mAdjSeq) {
23668                                 continue;
23669                             }
23670                         }
23671                         int clientAdj = client.curRawAdj;
23672                         int clientProcState = client.curProcState;
23673                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23674                             // If the other app is cached for any reason, for purposes here
23675                             // we are going to consider it empty.  The specific cached state
23676                             // doesn't propagate except under certain conditions.
23677                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23678                         }
23679                         String adjType = null;
23680                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
23681                             // Not doing bind OOM management, so treat
23682                             // this guy more like a started service.
23683                             if (app.hasShownUi && app != mHomeProcess) {
23684                                 // If this process has shown some UI, let it immediately
23685                                 // go to the LRU list because it may be pretty heavy with
23686                                 // UI stuff.  We'll tag it with a label just to help
23687                                 // debug and understand what is going on.
23688                                 if (adj > clientAdj) {
23689                                     adjType = "cch-bound-ui-services";
23690                                 }
23691                                 app.cached = false;
23692                                 clientAdj = adj;
23693                                 clientProcState = procState;
23694                             } else {
23695                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23696                                     // This service has not seen activity within
23697                                     // recent memory, so allow it to drop to the
23698                                     // LRU list if there is no other reason to keep
23699                                     // it around.  We'll also tag it with a label just
23700                                     // to help debug and undertand what is going on.
23701                                     if (adj > clientAdj) {
23702                                         adjType = "cch-bound-services";
23703                                     }
23704                                     clientAdj = adj;
23705                                 }
23706                             }
23707                         }
23708                         if (adj > clientAdj) {
23709                             // If this process has recently shown UI, and
23710                             // the process that is binding to it is less
23711                             // important than being visible, then we don't
23712                             // care about the binding as much as we care
23713                             // about letting this process get into the LRU
23714                             // list to be killed and restarted if needed for
23715                             // memory.
23716                             if (app.hasShownUi && app != mHomeProcess
23717                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23718                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
23719                                     adjType = "cch-bound-ui-services";
23720                                 }
23721                             } else {
23722                                 int newAdj;
23723                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
23724                                         |Context.BIND_IMPORTANT)) != 0) {
23725                                     if (clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
23726                                         newAdj = clientAdj;
23727                                     } else {
23728                                         // make this service persistent
23729                                         newAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
23730                                         schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23731                                         procState = ActivityManager.PROCESS_STATE_PERSISTENT;
23732                                     }
23733                                 } else if ((cr.flags & Context.BIND_ADJUST_BELOW_PERCEPTIBLE) != 0
23734                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
23735                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ + 1) {
23736                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ + 1;
23737                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
23738                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
23739                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23740                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
23741                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
23742                                     newAdj = clientAdj;
23743                                 } else {
23744                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
23745                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
23746                                     } else {
23747                                         newAdj = adj;
23748                                     }
23749                                 }
23750                                 if (!client.cached) {
23751                                     app.cached = false;
23752                                 }
23753                                 if (adj >  newAdj) {
23754                                     adj = newAdj;
23755                                     adjType = "service";
23756                                 }
23757                             }
23758                         }
23759                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
23760                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
23761                             // This will treat important bound services identically to
23762                             // the top app, which may behave differently than generic
23763                             // foreground work.
23764                             if (client.curSchedGroup > schedGroup) {
23765                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23766                                     schedGroup = client.curSchedGroup;
23767                                 } else {
23768                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23769                                 }
23770                             }
23771                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23772                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23773                                     // Special handling of clients who are in the top state.
23774                                     // We *may* want to consider this process to be in the
23775                                     // top state as well, but only if there is not another
23776                                     // reason for it to be running.  Being on the top is a
23777                                     // special state, meaning you are specifically running
23778                                     // for the current top app.  If the process is already
23779                                     // running in the background for some other reason, it
23780                                     // is more important to continue considering it to be
23781                                     // in the background state.
23782                                     mayBeTop = true;
23783                                     mayBeTopType = "service";
23784                                     mayBeTopSource = cr.binding.client;
23785                                     mayBeTopTarget = s.name;
23786                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23787                                 } else {
23788                                     // Special handling for above-top states (persistent
23789                                     // processes).  These should not bring the current process
23790                                     // into the top state, since they are not on top.  Instead
23791                                     // give them the best state after that.
23792                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
23793                                         clientProcState =
23794                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23795                                     } else if (mWakefulness
23796                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
23797                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
23798                                                     != 0) {
23799                                         clientProcState =
23800                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23801                                     } else {
23802                                         clientProcState =
23803                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23804                                     }
23805                                 }
23806                             }
23807                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
23808                             if (clientProcState <
23809                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23810                                 clientProcState =
23811                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23812                             }
23813                         } else {
23814                             if (clientProcState <
23815                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
23816                                 clientProcState =
23817                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
23818                             }
23819                         }
23820                         if (procState > clientProcState) {
23821                             procState = clientProcState;
23822                             if (adjType == null) {
23823                                 adjType = "service";
23824                             }
23825                         }
23826                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
23827                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
23828                             app.pendingUiClean = true;
23829                         }
23830                         if (adjType != null) {
23831                             app.adjType = adjType;
23832                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23833                                     .REASON_SERVICE_IN_USE;
23834                             app.adjSource = cr.binding.client;
23835                             app.adjSourceProcState = clientProcState;
23836                             app.adjTarget = s.name;
23837                             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23838                                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
23839                                         + ": " + app + ", due to " + cr.binding.client
23840                                         + " adj=" + adj + " procState="
23841                                         + ProcessList.makeProcStateString(procState));
23842                             }
23843                         }
23844                     }
23845                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
23846                         app.treatLikeActivity = true;
23847                     }
23848                     final ActivityRecord a = cr.activity;
23849                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
23850                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible
23851                                 || a.isState(ActivityState.RESUMED, ActivityState.PAUSING))) {
23852                             adj = ProcessList.FOREGROUND_APP_ADJ;
23853                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
23854                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23855                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
23856                                 } else {
23857                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23858                                 }
23859                             }
23860                             app.cached = false;
23861                             app.adjType = "service";
23862                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23863                                     .REASON_SERVICE_IN_USE;
23864                             app.adjSource = a;
23865                             app.adjSourceProcState = procState;
23866                             app.adjTarget = s.name;
23867                             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23868                                 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23869                                         "Raise to service w/activity: " + app);
23870                             }
23871                         }
23872                     }
23873                 }
23874             }
23875         }
23876
23877         for (int provi = app.pubProviders.size()-1;
23878                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23879                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23880                         || procState > ActivityManager.PROCESS_STATE_TOP);
23881                 provi--) {
23882             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
23883             for (int i = cpr.connections.size()-1;
23884                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23885                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23886                             || procState > ActivityManager.PROCESS_STATE_TOP);
23887                     i--) {
23888                 ContentProviderConnection conn = cpr.connections.get(i);
23889                 ProcessRecord client = conn.client;
23890                 if (client == app) {
23891                     // Being our own client is not interesting.
23892                     continue;
23893                 }
23894                 computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23895                 if (client.containsCycle) {
23896                     // We've detected a cycle. We should retry computeOomAdjLocked later in
23897                     // case a later-checked connection from a client  would raise its
23898                     // priority legitimately.
23899                     app.containsCycle = true;
23900                     // If the client has not been completely evaluated, skip using its
23901                     // priority. Else use the conservative value for now and look for a
23902                     // better state in the next iteration.
23903                     if (client.completedAdjSeq < mAdjSeq) {
23904                         continue;
23905                     }
23906                 }
23907                 int clientAdj = client.curRawAdj;
23908                 int clientProcState = client.curProcState;
23909                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23910                     // If the other app is cached for any reason, for purposes here
23911                     // we are going to consider it empty.
23912                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23913                 }
23914                 String adjType = null;
23915                 if (adj > clientAdj) {
23916                     if (app.hasShownUi && app != mHomeProcess
23917                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23918                         adjType = "cch-ui-provider";
23919                     } else {
23920                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
23921                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
23922                         adjType = "provider";
23923                     }
23924                     app.cached &= client.cached;
23925                 }
23926                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23927                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23928                         // Special handling of clients who are in the top state.
23929                         // We *may* want to consider this process to be in the
23930                         // top state as well, but only if there is not another
23931                         // reason for it to be running.  Being on the top is a
23932                         // special state, meaning you are specifically running
23933                         // for the current top app.  If the process is already
23934                         // running in the background for some other reason, it
23935                         // is more important to continue considering it to be
23936                         // in the background state.
23937                         mayBeTop = true;
23938                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23939                         mayBeTopType = adjType = "provider-top";
23940                         mayBeTopSource = client;
23941                         mayBeTopTarget = cpr.name;
23942                     } else {
23943                         // Special handling for above-top states (persistent
23944                         // processes).  These should not bring the current process
23945                         // into the top state, since they are not on top.  Instead
23946                         // give them the best state after that.
23947                         clientProcState =
23948                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23949                         if (adjType == null) {
23950                             adjType = "provider";
23951                         }
23952                     }
23953                 }
23954                 if (procState > clientProcState) {
23955                     procState = clientProcState;
23956                 }
23957                 if (client.curSchedGroup > schedGroup) {
23958                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23959                 }
23960                 if (adjType != null) {
23961                     app.adjType = adjType;
23962                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23963                             .REASON_PROVIDER_IN_USE;
23964                     app.adjSource = client;
23965                     app.adjSourceProcState = clientProcState;
23966                     app.adjTarget = cpr.name;
23967                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23968                         reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
23969                                 + ": " + app + ", due to " + client
23970                                 + " adj=" + adj + " procState="
23971                                 + ProcessList.makeProcStateString(procState));
23972                     }
23973                 }
23974             }
23975             // If the provider has external (non-framework) process
23976             // dependencies, ensure that its adjustment is at least
23977             // FOREGROUND_APP_ADJ.
23978             if (cpr.hasExternalProcessHandles()) {
23979                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
23980                     adj = ProcessList.FOREGROUND_APP_ADJ;
23981                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23982                     app.cached = false;
23983                     app.adjType = "ext-provider";
23984                     app.adjTarget = cpr.name;
23985                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23986                         reportOomAdjMessageLocked(TAG_OOM_ADJ,
23987                                 "Raise adj to external provider: " + app);
23988                     }
23989                 }
23990                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23991                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23992                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
23993                             "Raise procstate to external provider: " + app);
23994                 }
23995             }
23996         }
23997
23998         if (app.lastProviderTime > 0 &&
23999                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
24000             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
24001                 adj = ProcessList.PREVIOUS_APP_ADJ;
24002                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
24003                 app.cached = false;
24004                 app.adjType = "recent-provider";
24005                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
24006                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
24007                             "Raise adj to recent provider: " + app);
24008                 }
24009             }
24010             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
24011                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
24012                 app.adjType = "recent-provider";
24013                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
24014                     reportOomAdjMessageLocked(TAG_OOM_ADJ,
24015                             "Raise procstate to recent provider: " + app);
24016                 }
24017             }
24018         }
24019
24020         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
24021             // A client of one of our services or providers is in the top state.  We
24022             // *may* want to be in the top state, but not if we are already running in
24023             // the background for some other reason.  For the decision here, we are going
24024             // to pick out a few specific states that we want to remain in when a client
24025             // is top (states that tend to be longer-term) and otherwise allow it to go
24026             // to the top state.
24027             switch (procState) {
24028                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
24029                 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
24030                     // Something else is keeping it at this level, just leave it.
24031                     break;
24032                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
24033                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
24034                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
24035                 case ActivityManager.PROCESS_STATE_SERVICE:
24036                     // These all are longer-term states, so pull them up to the top
24037                     // of the background states, but not all the way to the top state.
24038                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
24039                     app.adjType = mayBeTopType;
24040                     app.adjSource = mayBeTopSource;
24041                     app.adjTarget = mayBeTopTarget;
24042                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
24043                         reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
24044                                 + ": " + app + ", due to " + mayBeTopSource
24045                                 + " adj=" + adj + " procState="
24046                                 + ProcessList.makeProcStateString(procState));
24047                     }
24048                     break;
24049                 default:
24050                     // Otherwise, top is a better choice, so take it.
24051                     procState = ActivityManager.PROCESS_STATE_TOP;
24052                     app.adjType = mayBeTopType;
24053                     app.adjSource = mayBeTopSource;
24054                     app.adjTarget = mayBeTopTarget;
24055                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
24056                         reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
24057                                 + ": " + app + ", due to " + mayBeTopSource
24058                                 + " adj=" + adj + " procState="
24059                                 + ProcessList.makeProcStateString(procState));
24060                     }
24061                     break;
24062             }
24063         }
24064
24065         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
24066             if (app.hasClientActivities) {
24067                 // This is a cached process, but with client activities.  Mark it so.
24068                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
24069                 app.adjType = "cch-client-act";
24070             } else if (app.treatLikeActivity) {
24071                 // This is a cached process, but somebody wants us to treat it like it has
24072                 // an activity, okay!
24073                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
24074                 app.adjType = "cch-as-act";
24075             }
24076         }
24077
24078         if (adj == ProcessList.SERVICE_ADJ) {
24079             if (doingAll) {
24080                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
24081                 mNewNumServiceProcs++;
24082                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
24083                 if (!app.serviceb) {
24084                     // This service isn't far enough down on the LRU list to
24085                     // normally be a B service, but if we are low on RAM and it
24086                     // is large we want to force it down since we would prefer to
24087                     // keep launcher over it.
24088                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
24089                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
24090                         app.serviceHighRam = true;
24091                         app.serviceb = true;
24092                         //Slog.i(TAG, "ADJ " + app + " high ram!");
24093                     } else {
24094                         mNewNumAServiceProcs++;
24095                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
24096                     }
24097                 } else {
24098                     app.serviceHighRam = false;
24099                 }
24100             }
24101             if (app.serviceb) {
24102                 adj = ProcessList.SERVICE_B_ADJ;
24103             }
24104         }
24105
24106         app.curRawAdj = adj;
24107
24108         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
24109         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
24110         if (adj > app.maxAdj) {
24111             adj = app.maxAdj;
24112             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
24113                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
24114             }
24115         }
24116
24117         // Put bound foreground services in a special sched group for additional
24118         // restrictions on screen off
24119         if (procState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE &&
24120             mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) {
24121             if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) {
24122                 schedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
24123             }
24124         }
24125
24126         // Do final modification to adj.  Everything we do between here and applying
24127         // the final setAdj must be done in this function, because we will also use
24128         // it when computing the final cached adj later.  Note that we don't need to
24129         // worry about this for max adj above, since max adj will always be used to
24130         // keep it out of the cached vaues.
24131         app.curAdj = app.modifyRawOomAdj(adj);
24132         app.curSchedGroup = schedGroup;
24133         app.curProcState = procState;
24134         app.foregroundActivities = foregroundActivities;
24135         app.completedAdjSeq = mAdjSeq;
24136
24137         // if curAdj or curProcState improved, then this process was promoted
24138         return app.curAdj < prevAppAdj || app.curProcState < prevProcState;
24139     }
24140
24141     /**
24142      * Record new PSS sample for a process.
24143      */
24144     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
24145             long rss, int statType, long pssDuration, long now) {
24146         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
24147                 swapPss * 1024, rss * 1024, statType, procState, pssDuration);
24148         proc.lastPssTime = now;
24149         proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
24150         if (DEBUG_PSS) Slog.d(TAG_PSS,
24151                 "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
24152                 + " state=" + ProcessList.makeProcStateString(procState));
24153         if (proc.initialIdlePss == 0) {
24154             proc.initialIdlePss = pss;
24155         }
24156         proc.lastPss = pss;
24157         proc.lastSwapPss = swapPss;
24158         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
24159             proc.lastCachedPss = pss;
24160             proc.lastCachedSwapPss = swapPss;
24161         }
24162
24163         final SparseArray<Pair<Long, String>> watchUids
24164                 = mMemWatchProcesses.getMap().get(proc.processName);
24165         Long check = null;
24166         if (watchUids != null) {
24167             Pair<Long, String> val = watchUids.get(proc.uid);
24168             if (val == null) {
24169                 val = watchUids.get(0);
24170             }
24171             if (val != null) {
24172                 check = val.first;
24173             }
24174         }
24175         if (check != null) {
24176             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
24177                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24178                 if (!isDebuggable) {
24179                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
24180                         isDebuggable = true;
24181                     }
24182                 }
24183                 if (isDebuggable) {
24184                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
24185                     final ProcessRecord myProc = proc;
24186                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
24187                     mMemWatchDumpProcName = proc.processName;
24188                     mMemWatchDumpFile = heapdumpFile.toString();
24189                     mMemWatchDumpPid = proc.pid;
24190                     mMemWatchDumpUid = proc.uid;
24191                     BackgroundThread.getHandler().post(new Runnable() {
24192                         @Override
24193                         public void run() {
24194                             revokeUriPermission(ActivityThread.currentActivityThread()
24195                                             .getApplicationThread(),
24196                                     null, DumpHeapActivity.JAVA_URI,
24197                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
24198                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
24199                                     UserHandle.myUserId());
24200                             ParcelFileDescriptor fd = null;
24201                             try {
24202                                 heapdumpFile.delete();
24203                                 fd = ParcelFileDescriptor.open(heapdumpFile,
24204                                         ParcelFileDescriptor.MODE_CREATE |
24205                                                 ParcelFileDescriptor.MODE_TRUNCATE |
24206                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
24207                                                 ParcelFileDescriptor.MODE_APPEND);
24208                                 IApplicationThread thread = myProc.thread;
24209                                 if (thread != null) {
24210                                     try {
24211                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
24212                                                 "Requesting dump heap from "
24213                                                 + myProc + " to " + heapdumpFile);
24214                                         thread.dumpHeap(/* managed= */ true,
24215                                                 /* mallocInfo= */ false, /* runGc= */ false,
24216                                                 heapdumpFile.toString(), fd);
24217                                     } catch (RemoteException e) {
24218                                     }
24219                                 }
24220                             } catch (FileNotFoundException e) {
24221                                 e.printStackTrace();
24222                             } finally {
24223                                 if (fd != null) {
24224                                     try {
24225                                         fd.close();
24226                                     } catch (IOException e) {
24227                                     }
24228                                 }
24229                             }
24230                         }
24231                     });
24232                 } else {
24233                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
24234                             + ", but debugging not enabled");
24235                 }
24236             }
24237         }
24238     }
24239
24240     /**
24241      * Schedule PSS collection of a process.
24242      */
24243     boolean requestPssLocked(ProcessRecord proc, int procState) {
24244         if (mPendingPssProcesses.contains(proc)) {
24245             return false;
24246         }
24247         if (mPendingPssProcesses.size() == 0) {
24248             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
24249         }
24250         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
24251         proc.pssProcState = procState;
24252         proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
24253         mPendingPssProcesses.add(proc);
24254         return true;
24255     }
24256
24257     /**
24258      * Schedule PSS collection of all processes.
24259      */
24260     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
24261         if (!always) {
24262             if (now < (mLastFullPssTime +
24263                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
24264                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
24265                 return;
24266             }
24267         }
24268         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs!  memLowered=" + memLowered);
24269         mLastFullPssTime = now;
24270         mFullPssPending = true;
24271         for (int i = mPendingPssProcesses.size() - 1; i >= 0; i--) {
24272             ProcessList.abortNextPssTime(mPendingPssProcesses.get(i).procStateMemTracker);;
24273         }
24274         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
24275         mPendingPssProcesses.clear();
24276         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24277             ProcessRecord app = mLruProcesses.get(i);
24278             if (app.thread == null
24279                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
24280                 continue;
24281             }
24282             if (memLowered || (always && now >
24283                             app.lastStateTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
24284                     || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
24285                 app.pssProcState = app.setProcState;
24286                 app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
24287                         : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
24288                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24289                         app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24290                 mPendingPssProcesses.add(app);
24291             }
24292         }
24293         if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) {
24294             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
24295         }
24296     }
24297
24298     public void setTestPssMode(boolean enabled) {
24299         synchronized (this) {
24300             mTestPssMode = enabled;
24301             if (enabled) {
24302                 // Whenever we enable the mode, we want to take a snapshot all of current
24303                 // process mem use.
24304                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
24305             }
24306         }
24307     }
24308
24309     /**
24310      * Ask a given process to GC right now.
24311      */
24312     final void performAppGcLocked(ProcessRecord app) {
24313         try {
24314             app.lastRequestedGc = SystemClock.uptimeMillis();
24315             if (app.thread != null) {
24316                 if (app.reportLowMemory) {
24317                     app.reportLowMemory = false;
24318                     app.thread.scheduleLowMemory();
24319                 } else {
24320                     app.thread.processInBackground();
24321                 }
24322             }
24323         } catch (Exception e) {
24324             // whatever.
24325         }
24326     }
24327
24328     /**
24329      * Returns true if things are idle enough to perform GCs.
24330      */
24331     private final boolean canGcNowLocked() {
24332         boolean processingBroadcasts = false;
24333         for (BroadcastQueue q : mBroadcastQueues) {
24334             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
24335                 processingBroadcasts = true;
24336             }
24337         }
24338         return !processingBroadcasts
24339                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
24340     }
24341
24342     /**
24343      * Perform GCs on all processes that are waiting for it, but only
24344      * if things are idle.
24345      */
24346     final void performAppGcsLocked() {
24347         final int N = mProcessesToGc.size();
24348         if (N <= 0) {
24349             return;
24350         }
24351         if (canGcNowLocked()) {
24352             while (mProcessesToGc.size() > 0) {
24353                 ProcessRecord proc = mProcessesToGc.remove(0);
24354                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
24355                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
24356                             <= SystemClock.uptimeMillis()) {
24357                         // To avoid spamming the system, we will GC processes one
24358                         // at a time, waiting a few seconds between each.
24359                         performAppGcLocked(proc);
24360                         scheduleAppGcsLocked();
24361                         return;
24362                     } else {
24363                         // It hasn't been long enough since we last GCed this
24364                         // process...  put it in the list to wait for its time.
24365                         addProcessToGcListLocked(proc);
24366                         break;
24367                     }
24368                 }
24369             }
24370
24371             scheduleAppGcsLocked();
24372         }
24373     }
24374
24375     /**
24376      * If all looks good, perform GCs on all processes waiting for them.
24377      */
24378     final void performAppGcsIfAppropriateLocked() {
24379         if (canGcNowLocked()) {
24380             performAppGcsLocked();
24381             return;
24382         }
24383         // Still not idle, wait some more.
24384         scheduleAppGcsLocked();
24385     }
24386
24387     /**
24388      * Schedule the execution of all pending app GCs.
24389      */
24390     final void scheduleAppGcsLocked() {
24391         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
24392
24393         if (mProcessesToGc.size() > 0) {
24394             // Schedule a GC for the time to the next process.
24395             ProcessRecord proc = mProcessesToGc.get(0);
24396             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
24397
24398             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
24399             long now = SystemClock.uptimeMillis();
24400             if (when < (now+mConstants.GC_TIMEOUT)) {
24401                 when = now + mConstants.GC_TIMEOUT;
24402             }
24403             mHandler.sendMessageAtTime(msg, when);
24404         }
24405     }
24406
24407     /**
24408      * Add a process to the array of processes waiting to be GCed.  Keeps the
24409      * list in sorted order by the last GC time.  The process can't already be
24410      * on the list.
24411      */
24412     final void addProcessToGcListLocked(ProcessRecord proc) {
24413         boolean added = false;
24414         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
24415             if (mProcessesToGc.get(i).lastRequestedGc <
24416                     proc.lastRequestedGc) {
24417                 added = true;
24418                 mProcessesToGc.add(i+1, proc);
24419                 break;
24420             }
24421         }
24422         if (!added) {
24423             mProcessesToGc.add(0, proc);
24424         }
24425     }
24426
24427     /**
24428      * Set up to ask a process to GC itself.  This will either do it
24429      * immediately, or put it on the list of processes to gc the next
24430      * time things are idle.
24431      */
24432     final void scheduleAppGcLocked(ProcessRecord app) {
24433         long now = SystemClock.uptimeMillis();
24434         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
24435             return;
24436         }
24437         if (!mProcessesToGc.contains(app)) {
24438             addProcessToGcListLocked(app);
24439             scheduleAppGcsLocked();
24440         }
24441     }
24442
24443     final void checkExcessivePowerUsageLocked() {
24444         updateCpuStatsNow();
24445
24446         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
24447         boolean doCpuKills = true;
24448         if (mLastPowerCheckUptime == 0) {
24449             doCpuKills = false;
24450         }
24451         final long curUptime = SystemClock.uptimeMillis();
24452         final long uptimeSince = curUptime - mLastPowerCheckUptime;
24453         mLastPowerCheckUptime = curUptime;
24454         int i = mLruProcesses.size();
24455         while (i > 0) {
24456             i--;
24457             ProcessRecord app = mLruProcesses.get(i);
24458             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24459                 if (app.lastCpuTime <= 0) {
24460                     continue;
24461                 }
24462                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
24463                 if (DEBUG_POWER) {
24464                     StringBuilder sb = new StringBuilder(128);
24465                     sb.append("CPU for ");
24466                     app.toShortString(sb);
24467                     sb.append(": over ");
24468                     TimeUtils.formatDuration(uptimeSince, sb);
24469                     sb.append(" used ");
24470                     TimeUtils.formatDuration(cputimeUsed, sb);
24471                     sb.append(" (");
24472                     sb.append((cputimeUsed*100)/uptimeSince);
24473                     sb.append("%)");
24474                     Slog.i(TAG_POWER, sb.toString());
24475                 }
24476                 // If the process has used too much CPU over the last duration, the
24477                 // user probably doesn't want this, so kill!
24478                 if (doCpuKills && uptimeSince > 0) {
24479                     // What is the limit for this process?
24480                     int cpuLimit;
24481                     long checkDur = curUptime - app.whenUnimportant;
24482                     if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
24483                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
24484                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
24485                             || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
24486                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
24487                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
24488                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
24489                     } else {
24490                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
24491                     }
24492                     if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
24493                         synchronized (stats) {
24494                             stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
24495                                     uptimeSince, cputimeUsed);
24496                         }
24497                         app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
24498                                 + " dur=" + checkDur + " limit=" + cpuLimit, true);
24499                         app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
24500                     }
24501                 }
24502                 app.lastCpuTime = app.curCpuTime;
24503             }
24504         }
24505     }
24506
24507     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
24508             long nowElapsed) {
24509         boolean success = true;
24510
24511         if (app.curRawAdj != app.setRawAdj) {
24512             app.setRawAdj = app.curRawAdj;
24513         }
24514
24515         int changes = 0;
24516
24517         if (app.curAdj != app.setAdj) {
24518             ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
24519             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
24520                 String msg = "Set " + app.pid + " " + app.processName + " adj "
24521                         + app.curAdj + ": " + app.adjType;
24522                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24523             }
24524             app.setAdj = app.curAdj;
24525             app.verifiedAdj = ProcessList.INVALID_ADJ;
24526         }
24527
24528         if (app.setSchedGroup != app.curSchedGroup) {
24529             int oldSchedGroup = app.setSchedGroup;
24530             app.setSchedGroup = app.curSchedGroup;
24531             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24532                 String msg = "Setting sched group of " + app.processName
24533                         + " to " + app.curSchedGroup + ": " + app.adjType;
24534                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24535             }
24536             if (app.waitingToKill != null && app.curReceivers.isEmpty()
24537                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
24538                 app.kill(app.waitingToKill, true);
24539                 success = false;
24540             } else {
24541                 int processGroup;
24542                 switch (app.curSchedGroup) {
24543                     case ProcessList.SCHED_GROUP_BACKGROUND:
24544                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
24545                         break;
24546                     case ProcessList.SCHED_GROUP_TOP_APP:
24547                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
24548                         processGroup = THREAD_GROUP_TOP_APP;
24549                         break;
24550                     case ProcessList.SCHED_GROUP_RESTRICTED:
24551                         processGroup = THREAD_GROUP_RESTRICTED;
24552                         break;
24553                     default:
24554                         processGroup = THREAD_GROUP_DEFAULT;
24555                         break;
24556                 }
24557                 long oldId = Binder.clearCallingIdentity();
24558                 try {
24559                     setProcessGroup(app.pid, processGroup);
24560                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
24561                         // do nothing if we already switched to RT
24562                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
24563                             mVrController.onTopProcChangedLocked(app);
24564                             if (mUseFifoUiScheduling) {
24565                                 // Switch UI pipeline for app to SCHED_FIFO
24566                                 app.savedPriority = Process.getThreadPriority(app.pid);
24567                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
24568                                 if (app.renderThreadTid != 0) {
24569                                     scheduleAsFifoPriority(app.renderThreadTid,
24570                                         /* suppressLogs */true);
24571                                     if (DEBUG_OOM_ADJ) {
24572                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
24573                                             app.renderThreadTid + ") to FIFO");
24574                                     }
24575                                 } else {
24576                                     if (DEBUG_OOM_ADJ) {
24577                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
24578                                     }
24579                                 }
24580                             } else {
24581                                 // Boost priority for top app UI and render threads
24582                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
24583                                 if (app.renderThreadTid != 0) {
24584                                     try {
24585                                         setThreadPriority(app.renderThreadTid,
24586                                                 TOP_APP_PRIORITY_BOOST);
24587                                     } catch (IllegalArgumentException e) {
24588                                         // thread died, ignore
24589                                     }
24590                                 }
24591                             }
24592                         }
24593                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
24594                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
24595                         mVrController.onTopProcChangedLocked(app);
24596                         if (mUseFifoUiScheduling) {
24597                             try {
24598                                 // Reset UI pipeline to SCHED_OTHER
24599                                 setThreadScheduler(app.pid, SCHED_OTHER, 0);
24600                                 setThreadPriority(app.pid, app.savedPriority);
24601                                 if (app.renderThreadTid != 0) {
24602                                     setThreadScheduler(app.renderThreadTid,
24603                                         SCHED_OTHER, 0);
24604                                     setThreadPriority(app.renderThreadTid, -4);
24605                                 }
24606                             } catch (IllegalArgumentException e) {
24607                                 Slog.w(TAG,
24608                                         "Failed to set scheduling policy, thread does not exist:\n"
24609                                                 + e);
24610                             } catch (SecurityException e) {
24611                                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
24612                             }
24613                         } else {
24614                             // Reset priority for top app UI and render threads
24615                             setThreadPriority(app.pid, 0);
24616                             if (app.renderThreadTid != 0) {
24617                                 setThreadPriority(app.renderThreadTid, 0);
24618                             }
24619                         }
24620                     }
24621                 } catch (Exception e) {
24622                     if (false) {
24623                         Slog.w(TAG, "Failed setting process group of " + app.pid
24624                                 + " to " + app.curSchedGroup);
24625                         Slog.w(TAG, "at location", e);
24626                     }
24627                 } finally {
24628                     Binder.restoreCallingIdentity(oldId);
24629                 }
24630             }
24631         }
24632         if (app.repForegroundActivities != app.foregroundActivities) {
24633             app.repForegroundActivities = app.foregroundActivities;
24634             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
24635         }
24636         if (app.repProcState != app.curProcState) {
24637             app.repProcState = app.curProcState;
24638             if (app.thread != null) {
24639                 try {
24640                     if (false) {
24641                         //RuntimeException h = new RuntimeException("here");
24642                         Slog.i(TAG, "Sending new process state " + app.repProcState
24643                                 + " to " + app /*, h*/);
24644                     }
24645                     app.thread.setProcessState(app.repProcState);
24646                 } catch (RemoteException e) {
24647                 }
24648             }
24649         }
24650         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
24651                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
24652             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
24653                 // Experimental code to more aggressively collect pss while
24654                 // running test...  the problem is that this tends to collect
24655                 // the data right when a process is transitioning between process
24656                 // states, which will tend to give noisy data.
24657                 long start = SystemClock.uptimeMillis();
24658                 long startTime = SystemClock.currentThreadTimeMillis();
24659                 long pss = Debug.getPss(app.pid, mTmpLong, null);
24660                 long endTime = SystemClock.currentThreadTimeMillis();
24661                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
24662                         mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
24663                 mPendingPssProcesses.remove(app);
24664                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
24665                         + " to " + app.curProcState + ": "
24666                         + (SystemClock.uptimeMillis()-start) + "ms");
24667             }
24668             app.lastStateTime = now;
24669             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24670                     app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24671             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
24672                     + ProcessList.makeProcStateString(app.setProcState) + " to "
24673                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
24674                     + (app.nextPssTime-now) + ": " + app);
24675         } else {
24676             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
24677                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
24678                     mTestPssMode)))) {
24679                 if (requestPssLocked(app, app.setProcState)) {
24680                     app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24681                             app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24682                 }
24683             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
24684                     "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
24685         }
24686         if (app.setProcState != app.curProcState) {
24687             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24688                 String msg = "Proc state change of " + app.processName
24689                         + " to " + ProcessList.makeProcStateString(app.curProcState)
24690                         + " (" + app.curProcState + ")" + ": " + app.adjType;
24691                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24692             }
24693             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
24694             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
24695             if (setImportant && !curImportant) {
24696                 // This app is no longer something we consider important enough to allow to
24697                 // use arbitrary amounts of battery power.  Note
24698                 // its current CPU time to later know to kill it if
24699                 // it is not behaving well.
24700                 app.whenUnimportant = now;
24701                 app.lastCpuTime = 0;
24702             }
24703             // Inform UsageStats of important process state change
24704             // Must be called before updating setProcState
24705             maybeUpdateUsageStatsLocked(app, nowElapsed);
24706
24707             maybeUpdateLastTopTime(app, now);
24708
24709             app.setProcState = app.curProcState;
24710             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24711                 app.notCachedSinceIdle = false;
24712             }
24713             if (!doingAll) {
24714                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
24715             } else {
24716                 app.procStateChanged = true;
24717             }
24718         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
24719                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
24720             // For apps that sit around for a long time in the interactive state, we need
24721             // to report this at least once a day so they don't go idle.
24722             maybeUpdateUsageStatsLocked(app, nowElapsed);
24723         }
24724
24725         if (changes != 0) {
24726             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24727                     "Changes in " + app + ": " + changes);
24728             int i = mPendingProcessChanges.size()-1;
24729             ProcessChangeItem item = null;
24730             while (i >= 0) {
24731                 item = mPendingProcessChanges.get(i);
24732                 if (item.pid == app.pid) {
24733                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24734                             "Re-using existing item: " + item);
24735                     break;
24736                 }
24737                 i--;
24738             }
24739             if (i < 0) {
24740                 // No existing item in pending changes; need a new one.
24741                 final int NA = mAvailProcessChanges.size();
24742                 if (NA > 0) {
24743                     item = mAvailProcessChanges.remove(NA-1);
24744                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24745                             "Retrieving available item: " + item);
24746                 } else {
24747                     item = new ProcessChangeItem();
24748                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24749                             "Allocating new item: " + item);
24750                 }
24751                 item.changes = 0;
24752                 item.pid = app.pid;
24753                 item.uid = app.info.uid;
24754                 if (mPendingProcessChanges.size() == 0) {
24755                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24756                             "*** Enqueueing dispatch processes changed!");
24757                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
24758                 }
24759                 mPendingProcessChanges.add(item);
24760             }
24761             item.changes |= changes;
24762             item.foregroundActivities = app.repForegroundActivities;
24763             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24764                     "Item " + Integer.toHexString(System.identityHashCode(item))
24765                     + " " + app.toShortString() + ": changes=" + item.changes
24766                     + " foreground=" + item.foregroundActivities
24767                     + " type=" + app.adjType + " source=" + app.adjSource
24768                     + " target=" + app.adjTarget);
24769         }
24770
24771         return success;
24772     }
24773
24774     private boolean isEphemeralLocked(int uid) {
24775         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
24776         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
24777             return false;
24778         }
24779         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
24780                 packages[0]);
24781     }
24782
24783     @VisibleForTesting
24784     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
24785         final UidRecord.ChangeItem pendingChange;
24786         if (uidRec == null || uidRec.pendingChange == null) {
24787             if (mPendingUidChanges.size() == 0) {
24788                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24789                         "*** Enqueueing dispatch uid changed!");
24790                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
24791             }
24792             final int NA = mAvailUidChanges.size();
24793             if (NA > 0) {
24794                 pendingChange = mAvailUidChanges.remove(NA-1);
24795                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24796                         "Retrieving available item: " + pendingChange);
24797             } else {
24798                 pendingChange = new UidRecord.ChangeItem();
24799                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24800                         "Allocating new item: " + pendingChange);
24801             }
24802             if (uidRec != null) {
24803                 uidRec.pendingChange = pendingChange;
24804                 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
24805                     // If this uid is going away, and we haven't yet reported it is gone,
24806                     // then do so now.
24807                     change |= UidRecord.CHANGE_IDLE;
24808                 }
24809             } else if (uid < 0) {
24810                 throw new IllegalArgumentException("No UidRecord or uid");
24811             }
24812             pendingChange.uidRecord = uidRec;
24813             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
24814             mPendingUidChanges.add(pendingChange);
24815         } else {
24816             pendingChange = uidRec.pendingChange;
24817             // If there is no change in idle or active state, then keep whatever was pending.
24818             if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
24819                 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
24820                         | UidRecord.CHANGE_ACTIVE));
24821             }
24822             // If there is no change in cached or uncached state, then keep whatever was pending.
24823             if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
24824                 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
24825                         | UidRecord.CHANGE_UNCACHED));
24826             }
24827             // If this is a report of the UID being gone, then we shouldn't keep any previous
24828             // report of it being active or cached.  (That is, a gone uid is never active,
24829             // and never cached.)
24830             if ((change & UidRecord.CHANGE_GONE) != 0) {
24831                 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
24832                 if (!uidRec.idle) {
24833                     // If this uid is going away, and we haven't yet reported it is gone,
24834                     // then do so now.
24835                     change |= UidRecord.CHANGE_IDLE;
24836                 }
24837             }
24838         }
24839         pendingChange.change = change;
24840         pendingChange.processState = uidRec != null
24841                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
24842         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
24843         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
24844         if (uidRec != null) {
24845             uidRec.lastReportedChange = change;
24846             uidRec.updateLastDispatchedProcStateSeq(change);
24847         }
24848
24849         // Directly update the power manager, since we sit on top of it and it is critical
24850         // it be kept in sync (so wake locks will be held as soon as appropriate).
24851         if (mLocalPowerManager != null) {
24852             // TO DO: dispatch cached/uncached changes here, so we don't need to report
24853             // all proc state changes.
24854             if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
24855                 mLocalPowerManager.uidActive(pendingChange.uid);
24856             }
24857             if ((change & UidRecord.CHANGE_IDLE) != 0) {
24858                 mLocalPowerManager.uidIdle(pendingChange.uid);
24859             }
24860             if ((change & UidRecord.CHANGE_GONE) != 0) {
24861                 mLocalPowerManager.uidGone(pendingChange.uid);
24862             } else {
24863                 mLocalPowerManager.updateUidProcState(pendingChange.uid,
24864                         pendingChange.processState);
24865             }
24866         }
24867     }
24868
24869     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
24870             String authority) {
24871         if (app == null) return;
24872         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
24873             UserState userState = mUserController.getStartedUserState(app.userId);
24874             if (userState == null) return;
24875             final long now = SystemClock.elapsedRealtime();
24876             Long lastReported = userState.mProviderLastReportedFg.get(authority);
24877             if (lastReported == null || lastReported < now - 60 * 1000L) {
24878                 if (mSystemReady) {
24879                     // Cannot touch the user stats if not system ready
24880                     mUsageStatsService.reportContentProviderUsage(
24881                             authority, providerPkgName, app.userId);
24882                 }
24883                 userState.mProviderLastReportedFg.put(authority, now);
24884             }
24885         }
24886     }
24887
24888     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
24889         if (DEBUG_USAGE_STATS) {
24890             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
24891                     + "] state changes: old = " + app.setProcState + ", new = "
24892                     + app.curProcState);
24893         }
24894         if (mUsageStatsService == null) {
24895             return;
24896         }
24897         boolean isInteraction;
24898         // To avoid some abuse patterns, we are going to be careful about what we consider
24899         // to be an app interaction.  Being the top activity doesn't count while the display
24900         // is sleeping, nor do short foreground services.
24901         if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
24902             isInteraction = true;
24903             app.fgInteractionTime = 0;
24904         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
24905             if (app.fgInteractionTime == 0) {
24906                 app.fgInteractionTime = nowElapsed;
24907                 isInteraction = false;
24908             } else {
24909                 isInteraction = nowElapsed > app.fgInteractionTime
24910                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
24911             }
24912         } else {
24913             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
24914             app.fgInteractionTime = 0;
24915         }
24916         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
24917                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
24918             app.interactionEventTime = nowElapsed;
24919             String[] packages = app.getPackageList();
24920             if (packages != null) {
24921                 for (int i = 0; i < packages.length; i++) {
24922                     mUsageStatsService.reportEvent(packages[i], app.userId,
24923                             UsageEvents.Event.SYSTEM_INTERACTION);
24924                 }
24925             }
24926         }
24927         app.reportedInteraction = isInteraction;
24928         if (!isInteraction) {
24929             app.interactionEventTime = 0;
24930         }
24931     }
24932
24933     private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) {
24934         if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP
24935                 && app.curProcState > ActivityManager.PROCESS_STATE_TOP) {
24936             app.lastTopTime = nowUptime;
24937         }
24938     }
24939
24940     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
24941         if (proc.thread != null) {
24942             if (proc.baseProcessTracker != null) {
24943                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
24944             }
24945         }
24946     }
24947
24948     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
24949             ProcessRecord TOP_APP, boolean doingAll, long now) {
24950         if (app.thread == null) {
24951             return false;
24952         }
24953
24954         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
24955
24956         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
24957     }
24958
24959     @GuardedBy("this")
24960     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
24961             boolean oomAdj) {
24962         if (isForeground != proc.foregroundServices) {
24963             proc.foregroundServices = isForeground;
24964             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
24965                     proc.info.uid);
24966             if (isForeground) {
24967                 if (curProcs == null) {
24968                     curProcs = new ArrayList<ProcessRecord>();
24969                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
24970                 }
24971                 if (!curProcs.contains(proc)) {
24972                     curProcs.add(proc);
24973                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
24974                             proc.info.packageName, proc.info.uid);
24975                 }
24976             } else {
24977                 if (curProcs != null) {
24978                     if (curProcs.remove(proc)) {
24979                         mBatteryStatsService.noteEvent(
24980                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
24981                                 proc.info.packageName, proc.info.uid);
24982                         if (curProcs.size() <= 0) {
24983                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
24984                         }
24985                     }
24986                 }
24987             }
24988             if (oomAdj) {
24989                 updateOomAdjLocked();
24990             }
24991         }
24992     }
24993
24994     private final ActivityRecord resumedAppLocked() {
24995         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
24996         String pkg;
24997         int uid;
24998         if (act != null) {
24999             pkg = act.packageName;
25000             uid = act.info.applicationInfo.uid;
25001         } else {
25002             pkg = null;
25003             uid = -1;
25004         }
25005         // Has the UID or resumed package name changed?
25006         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
25007                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
25008             if (mCurResumedPackage != null) {
25009                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
25010                         mCurResumedPackage, mCurResumedUid);
25011             }
25012             mCurResumedPackage = pkg;
25013             mCurResumedUid = uid;
25014             if (mCurResumedPackage != null) {
25015                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
25016                         mCurResumedPackage, mCurResumedUid);
25017             }
25018         }
25019         return act;
25020     }
25021
25022     /**
25023      * Update OomAdj for a specific process.
25024      * @param app The process to update
25025      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
25026      *                  if necessary, or skip.
25027      * @return whether updateOomAdjLocked(app) was successful.
25028      */
25029     @GuardedBy("this")
25030     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
25031         final ActivityRecord TOP_ACT = resumedAppLocked();
25032         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
25033         final boolean wasCached = app.cached;
25034
25035         mAdjSeq++;
25036
25037         // This is the desired cached adjusment we want to tell it to use.
25038         // If our app is currently cached, we know it, and that is it.  Otherwise,
25039         // we don't know it yet, and it needs to now be cached we will then
25040         // need to do a complete oom adj.
25041         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
25042                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
25043         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
25044                 SystemClock.uptimeMillis());
25045         if (oomAdjAll
25046                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
25047             // Changed to/from cached state, so apps after it in the LRU
25048             // list may also be changed.
25049             updateOomAdjLocked();
25050         }
25051         return success;
25052     }
25053
25054     @GuardedBy("this")
25055     final void updateOomAdjLocked() {
25056         final ActivityRecord TOP_ACT = resumedAppLocked();
25057         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
25058         final long now = SystemClock.uptimeMillis();
25059         final long nowElapsed = SystemClock.elapsedRealtime();
25060         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
25061         final int N = mLruProcesses.size();
25062
25063         if (false) {
25064             RuntimeException e = new RuntimeException();
25065             e.fillInStackTrace();
25066             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
25067         }
25068
25069         // Reset state in all uid records.
25070         for (int i=mActiveUids.size()-1; i>=0; i--) {
25071             final UidRecord uidRec = mActiveUids.valueAt(i);
25072             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
25073                     "Starting update of " + uidRec);
25074             uidRec.reset();
25075         }
25076
25077         mStackSupervisor.rankTaskLayersIfNeeded();
25078
25079         mAdjSeq++;
25080         mNewNumServiceProcs = 0;
25081         mNewNumAServiceProcs = 0;
25082
25083         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
25084         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
25085
25086         // Let's determine how many processes we have running vs.
25087         // how many slots we have for background processes; we may want
25088         // to put multiple processes in a slot of there are enough of
25089         // them.
25090         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
25091                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
25092         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
25093         if (numEmptyProcs > cachedProcessLimit) {
25094             // If there are more empty processes than our limit on cached
25095             // processes, then use the cached process limit for the factor.
25096             // This ensures that the really old empty processes get pushed
25097             // down to the bottom, so if we are running low on memory we will
25098             // have a better chance at keeping around more cached processes
25099             // instead of a gazillion empty processes.
25100             numEmptyProcs = cachedProcessLimit;
25101         }
25102         int emptyFactor = numEmptyProcs/numSlots;
25103         if (emptyFactor < 1) emptyFactor = 1;
25104         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
25105         if (cachedFactor < 1) cachedFactor = 1;
25106         int stepCached = 0;
25107         int stepEmpty = 0;
25108         int numCached = 0;
25109         int numEmpty = 0;
25110         int numTrimming = 0;
25111
25112         mNumNonCachedProcs = 0;
25113         mNumCachedHiddenProcs = 0;
25114
25115         // First update the OOM adjustment for each of the
25116         // application processes based on their current state.
25117         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
25118         int nextCachedAdj = curCachedAdj+1;
25119         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
25120         int nextEmptyAdj = curEmptyAdj+2;
25121
25122         boolean retryCycles = false;
25123
25124         // need to reset cycle state before calling computeOomAdjLocked because of service connections
25125         for (int i=N-1; i>=0; i--) {
25126             ProcessRecord app = mLruProcesses.get(i);
25127             app.containsCycle = false;
25128         }
25129         for (int i=N-1; i>=0; i--) {
25130             ProcessRecord app = mLruProcesses.get(i);
25131             if (!app.killedByAm && app.thread != null) {
25132                 app.procStateChanged = false;
25133                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
25134
25135                 // if any app encountered a cycle, we need to perform an additional loop later
25136                 retryCycles |= app.containsCycle;
25137
25138                 // If we haven't yet assigned the final cached adj
25139                 // to the process, do that now.
25140                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
25141                     switch (app.curProcState) {
25142                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
25143                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
25144                         case ActivityManager.PROCESS_STATE_CACHED_RECENT:
25145                             // This process is a cached process holding activities...
25146                             // assign it the next cached value for that type, and then
25147                             // step that cached level.
25148                             app.curRawAdj = curCachedAdj;
25149                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
25150                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
25151                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
25152                                     + ")");
25153                             if (curCachedAdj != nextCachedAdj) {
25154                                 stepCached++;
25155                                 if (stepCached >= cachedFactor) {
25156                                     stepCached = 0;
25157                                     curCachedAdj = nextCachedAdj;
25158                                     nextCachedAdj += 2;
25159                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
25160                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
25161                                     }
25162                                 }
25163                             }
25164                             break;
25165                         default:
25166                             // For everything else, assign next empty cached process
25167                             // level and bump that up.  Note that this means that
25168                             // long-running services that have dropped down to the
25169                             // cached level will be treated as empty (since their process
25170                             // state is still as a service), which is what we want.
25171                             app.curRawAdj = curEmptyAdj;
25172                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
25173                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
25174                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
25175                                     + ")");
25176                             if (curEmptyAdj != nextEmptyAdj) {
25177                                 stepEmpty++;
25178                                 if (stepEmpty >= emptyFactor) {
25179                                     stepEmpty = 0;
25180                                     curEmptyAdj = nextEmptyAdj;
25181                                     nextEmptyAdj += 2;
25182                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
25183                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
25184                                     }
25185                                 }
25186                             }
25187                             break;
25188                     }
25189                 }
25190
25191
25192             }
25193         }
25194
25195         // Cycle strategy:
25196         // - Retry computing any process that has encountered a cycle.
25197         // - Continue retrying until no process was promoted.
25198         // - Iterate from least important to most important.
25199         int cycleCount = 0;
25200         while (retryCycles && cycleCount < 10) {
25201             cycleCount++;
25202             retryCycles = false;
25203
25204             for (int i=0; i<N; i++) {
25205                 ProcessRecord app = mLruProcesses.get(i);
25206                 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
25207                     app.adjSeq--;
25208                     app.completedAdjSeq--;
25209                 }
25210             }
25211
25212             for (int i=0; i<N; i++) {
25213                 ProcessRecord app = mLruProcesses.get(i);
25214                 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
25215
25216                     if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now)) {
25217                         retryCycles = true;
25218                     }
25219                 }
25220             }
25221         }
25222
25223         for (int i=N-1; i>=0; i--) {
25224             ProcessRecord app = mLruProcesses.get(i);
25225             if (!app.killedByAm && app.thread != null) {
25226                 applyOomAdjLocked(app, true, now, nowElapsed);
25227
25228                 // Count the number of process types.
25229                 switch (app.curProcState) {
25230                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
25231                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
25232                         mNumCachedHiddenProcs++;
25233                         numCached++;
25234                         if (numCached > cachedProcessLimit) {
25235                             app.kill("cached #" + numCached, true);
25236                         }
25237                         break;
25238                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
25239                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
25240                                 && app.lastActivityTime < oldTime) {
25241                             app.kill("empty for "
25242                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
25243                                     / 1000) + "s", true);
25244                         } else {
25245                             numEmpty++;
25246                             if (numEmpty > emptyProcessLimit) {
25247                                 app.kill("empty #" + numEmpty, true);
25248                             }
25249                         }
25250                         break;
25251                     default:
25252                         mNumNonCachedProcs++;
25253                         break;
25254                 }
25255
25256                 if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
25257                     // If this is an isolated process, there are no services
25258                     // running in it, and it's not a special process with a
25259                     // custom entry point, then the process is no longer
25260                     // needed.  We agressively kill these because we can by
25261                     // definition not re-use the same process again, and it is
25262                     // good to avoid having whatever code was running in them
25263                     // left sitting around after no longer needed.
25264                     app.kill("isolated not needed", true);
25265                 } else {
25266                     // Keeping this process, update its uid.
25267                     final UidRecord uidRec = app.uidRecord;
25268                     if (uidRec != null) {
25269                         uidRec.ephemeral = app.info.isInstantApp();
25270                         if (uidRec.curProcState > app.curProcState) {
25271                             uidRec.curProcState = app.curProcState;
25272                         }
25273                         if (app.foregroundServices) {
25274                             uidRec.foregroundServices = true;
25275                         }
25276                     }
25277                 }
25278
25279                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
25280                         && !app.killedByAm) {
25281                     numTrimming++;
25282                 }
25283             }
25284         }
25285
25286         incrementProcStateSeqAndNotifyAppsLocked();
25287
25288         mNumServiceProcs = mNewNumServiceProcs;
25289
25290         // Now determine the memory trimming level of background processes.
25291         // Unfortunately we need to start at the back of the list to do this
25292         // properly.  We only do this if the number of background apps we
25293         // are managing to keep around is less than half the maximum we desire;
25294         // if we are keeping a good number around, we'll let them use whatever
25295         // memory they want.
25296         final int numCachedAndEmpty = numCached + numEmpty;
25297         int memFactor;
25298         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
25299                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
25300             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
25301                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
25302             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
25303                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
25304             } else {
25305                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
25306             }
25307         } else {
25308             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
25309         }
25310         // We always allow the memory level to go up (better).  We only allow it to go
25311         // down if we are in a state where that is allowed, *and* the total number of processes
25312         // has gone down since last time.
25313         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
25314                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
25315                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
25316         if (memFactor > mLastMemoryLevel) {
25317             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
25318                 memFactor = mLastMemoryLevel;
25319                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
25320             }
25321         }
25322         if (memFactor != mLastMemoryLevel) {
25323             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
25324         }
25325         mLastMemoryLevel = memFactor;
25326         mLastNumProcesses = mLruProcesses.size();
25327         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
25328         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
25329         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
25330             if (mLowRamStartTime == 0) {
25331                 mLowRamStartTime = now;
25332             }
25333             int step = 0;
25334             int fgTrimLevel;
25335             switch (memFactor) {
25336                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
25337                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
25338                     break;
25339                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
25340                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
25341                     break;
25342                 default:
25343                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
25344                     break;
25345             }
25346             int factor = numTrimming/3;
25347             int minFactor = 2;
25348             if (mHomeProcess != null) minFactor++;
25349             if (mPreviousProcess != null) minFactor++;
25350             if (factor < minFactor) factor = minFactor;
25351             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
25352             for (int i=N-1; i>=0; i--) {
25353                 ProcessRecord app = mLruProcesses.get(i);
25354                 if (allChanged || app.procStateChanged) {
25355                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
25356                     app.procStateChanged = false;
25357                 }
25358                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
25359                         && !app.killedByAm) {
25360                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
25361                         try {
25362                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25363                                     "Trimming memory of " + app.processName + " to " + curLevel);
25364                             app.thread.scheduleTrimMemory(curLevel);
25365                         } catch (RemoteException e) {
25366                         }
25367                         if (false) {
25368                             // For now we won't do this; our memory trimming seems
25369                             // to be good enough at this point that destroying
25370                             // activities causes more harm than good.
25371                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
25372                                     && app != mHomeProcess && app != mPreviousProcess) {
25373                                 // Need to do this on its own message because the stack may not
25374                                 // be in a consistent state at this point.
25375                                 // For these apps we will also finish their activities
25376                                 // to help them free memory.
25377                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
25378                             }
25379                         }
25380                     }
25381                     app.trimMemoryLevel = curLevel;
25382                     step++;
25383                     if (step >= factor) {
25384                         step = 0;
25385                         switch (curLevel) {
25386                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
25387                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
25388                                 break;
25389                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
25390                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
25391                                 break;
25392                         }
25393                     }
25394                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
25395                         && !app.killedByAm) {
25396                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
25397                             && app.thread != null) {
25398                         try {
25399                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25400                                     "Trimming memory of heavy-weight " + app.processName
25401                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
25402                             app.thread.scheduleTrimMemory(
25403                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
25404                         } catch (RemoteException e) {
25405                         }
25406                     }
25407                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
25408                 } else {
25409                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
25410                             || app.systemNoUi) && app.pendingUiClean) {
25411                         // If this application is now in the background and it
25412                         // had done UI, then give it the special trim level to
25413                         // have it free UI resources.
25414                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
25415                         if (app.trimMemoryLevel < level && app.thread != null) {
25416                             try {
25417                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25418                                         "Trimming memory of bg-ui " + app.processName
25419                                         + " to " + level);
25420                                 app.thread.scheduleTrimMemory(level);
25421                             } catch (RemoteException e) {
25422                             }
25423                         }
25424                         app.pendingUiClean = false;
25425                     }
25426                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
25427                         try {
25428                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25429                                     "Trimming memory of fg " + app.processName
25430                                     + " to " + fgTrimLevel);
25431                             app.thread.scheduleTrimMemory(fgTrimLevel);
25432                         } catch (RemoteException e) {
25433                         }
25434                     }
25435                     app.trimMemoryLevel = fgTrimLevel;
25436                 }
25437             }
25438         } else {
25439             if (mLowRamStartTime != 0) {
25440                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
25441                 mLowRamStartTime = 0;
25442             }
25443             for (int i=N-1; i>=0; i--) {
25444                 ProcessRecord app = mLruProcesses.get(i);
25445                 if (allChanged || app.procStateChanged) {
25446                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
25447                     app.procStateChanged = false;
25448                 }
25449                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
25450                         || app.systemNoUi) && app.pendingUiClean) {
25451                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
25452                             && app.thread != null) {
25453                         try {
25454                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25455                                     "Trimming memory of ui hidden " + app.processName
25456                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
25457                             app.thread.scheduleTrimMemory(
25458                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
25459                         } catch (RemoteException e) {
25460                         }
25461                     }
25462                     app.pendingUiClean = false;
25463                 }
25464                 app.trimMemoryLevel = 0;
25465             }
25466         }
25467
25468         if (mAlwaysFinishActivities) {
25469             // Need to do this on its own message because the stack may not
25470             // be in a consistent state at this point.
25471             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
25472         }
25473
25474         if (allChanged) {
25475             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
25476         }
25477
25478         ArrayList<UidRecord> becameIdle = null;
25479
25480         // Update from any uid changes.
25481         if (mLocalPowerManager != null) {
25482             mLocalPowerManager.startUidChanges();
25483         }
25484         for (int i=mActiveUids.size()-1; i>=0; i--) {
25485             final UidRecord uidRec = mActiveUids.valueAt(i);
25486             int uidChange = UidRecord.CHANGE_PROCSTATE;
25487             if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
25488                     && (uidRec.setProcState != uidRec.curProcState
25489                            || uidRec.setWhitelist != uidRec.curWhitelist)) {
25490                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
25491                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
25492                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
25493                         + " to " + uidRec.curWhitelist);
25494                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
25495                         && !uidRec.curWhitelist) {
25496                     // UID is now in the background (and not on the temp whitelist).  Was it
25497                     // previously in the foreground (or on the temp whitelist)?
25498                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
25499                             || uidRec.setWhitelist) {
25500                         uidRec.lastBackgroundTime = nowElapsed;
25501                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
25502                             // Note: the background settle time is in elapsed realtime, while
25503                             // the handler time base is uptime.  All this means is that we may
25504                             // stop background uids later than we had intended, but that only
25505                             // happens because the device was sleeping so we are okay anyway.
25506                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
25507                                     mConstants.BACKGROUND_SETTLE_TIME);
25508                         }
25509                     }
25510                     if (uidRec.idle && !uidRec.setIdle) {
25511                         uidChange = UidRecord.CHANGE_IDLE;
25512                         if (becameIdle == null) {
25513                             becameIdle = new ArrayList<>();
25514                         }
25515                         becameIdle.add(uidRec);
25516                     }
25517                 } else {
25518                     if (uidRec.idle) {
25519                         uidChange = UidRecord.CHANGE_ACTIVE;
25520                         EventLogTags.writeAmUidActive(uidRec.uid);
25521                         uidRec.idle = false;
25522                     }
25523                     uidRec.lastBackgroundTime = 0;
25524                 }
25525                 final boolean wasCached = uidRec.setProcState
25526                         > ActivityManager.PROCESS_STATE_RECEIVER;
25527                 final boolean isCached = uidRec.curProcState
25528                         > ActivityManager.PROCESS_STATE_RECEIVER;
25529                 if (wasCached != isCached ||
25530                         uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
25531                     uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
25532                 }
25533                 uidRec.setProcState = uidRec.curProcState;
25534                 uidRec.setWhitelist = uidRec.curWhitelist;
25535                 uidRec.setIdle = uidRec.idle;
25536                 enqueueUidChangeLocked(uidRec, -1, uidChange);
25537                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
25538                 if (uidRec.foregroundServices) {
25539                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
25540                 }
25541             }
25542         }
25543         if (mLocalPowerManager != null) {
25544             mLocalPowerManager.finishUidChanges();
25545         }
25546
25547         if (becameIdle != null) {
25548             // If we have any new uids that became idle this time, we need to make sure
25549             // they aren't left with running services.
25550             for (int i = becameIdle.size() - 1; i >= 0; i--) {
25551                 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
25552             }
25553         }
25554
25555         if (mProcessStats.shouldWriteNowLocked(now)) {
25556             mHandler.post(new Runnable() {
25557                 @Override public void run() {
25558                     synchronized (ActivityManagerService.this) {
25559                         mProcessStats.writeStateAsyncLocked();
25560                     }
25561                 }
25562             });
25563         }
25564
25565         if (DEBUG_OOM_ADJ) {
25566             final long duration = SystemClock.uptimeMillis() - now;
25567             if (false) {
25568                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
25569                         new RuntimeException("here").fillInStackTrace());
25570             } else {
25571                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
25572             }
25573         }
25574     }
25575
25576     @Override
25577     public void makePackageIdle(String packageName, int userId) {
25578         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
25579                 != PackageManager.PERMISSION_GRANTED) {
25580             String msg = "Permission Denial: makePackageIdle() from pid="
25581                     + Binder.getCallingPid()
25582                     + ", uid=" + Binder.getCallingUid()
25583                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
25584             Slog.w(TAG, msg);
25585             throw new SecurityException(msg);
25586         }
25587         final int callingPid = Binder.getCallingPid();
25588         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
25589                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
25590         long callingId = Binder.clearCallingIdentity();
25591         synchronized(this) {
25592             try {
25593                 IPackageManager pm = AppGlobals.getPackageManager();
25594                 int pkgUid = -1;
25595                 try {
25596                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
25597                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
25598                 } catch (RemoteException e) {
25599                 }
25600                 if (pkgUid == -1) {
25601                     throw new IllegalArgumentException("Unknown package name " + packageName);
25602                 }
25603
25604                 if (mLocalPowerManager != null) {
25605                     mLocalPowerManager.startUidChanges();
25606                 }
25607                 final int appId = UserHandle.getAppId(pkgUid);
25608                 final int N = mActiveUids.size();
25609                 for (int i=N-1; i>=0; i--) {
25610                     final UidRecord uidRec = mActiveUids.valueAt(i);
25611                     final long bgTime = uidRec.lastBackgroundTime;
25612                     if (bgTime > 0 && !uidRec.idle) {
25613                         if (UserHandle.getAppId(uidRec.uid) == appId) {
25614                             if (userId == UserHandle.USER_ALL ||
25615                                     userId == UserHandle.getUserId(uidRec.uid)) {
25616                                 EventLogTags.writeAmUidIdle(uidRec.uid);
25617                                 uidRec.idle = true;
25618                                 uidRec.setIdle = true;
25619                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
25620                                         + " from package " + packageName + " user " + userId);
25621                                 doStopUidLocked(uidRec.uid, uidRec);
25622                             }
25623                         }
25624                     }
25625                 }
25626             } finally {
25627                 if (mLocalPowerManager != null) {
25628                     mLocalPowerManager.finishUidChanges();
25629                 }
25630                 Binder.restoreCallingIdentity(callingId);
25631             }
25632         }
25633     }
25634
25635     final void idleUids() {
25636         synchronized (this) {
25637             final int N = mActiveUids.size();
25638             if (N <= 0) {
25639                 return;
25640             }
25641             final long nowElapsed = SystemClock.elapsedRealtime();
25642             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
25643             long nextTime = 0;
25644             if (mLocalPowerManager != null) {
25645                 mLocalPowerManager.startUidChanges();
25646             }
25647             for (int i=N-1; i>=0; i--) {
25648                 final UidRecord uidRec = mActiveUids.valueAt(i);
25649                 final long bgTime = uidRec.lastBackgroundTime;
25650                 if (bgTime > 0 && !uidRec.idle) {
25651                     if (bgTime <= maxBgTime) {
25652                         EventLogTags.writeAmUidIdle(uidRec.uid);
25653                         uidRec.idle = true;
25654                         uidRec.setIdle = true;
25655                         doStopUidLocked(uidRec.uid, uidRec);
25656                     } else {
25657                         if (nextTime == 0 || nextTime > bgTime) {
25658                             nextTime = bgTime;
25659                         }
25660                     }
25661                 }
25662             }
25663             if (mLocalPowerManager != null) {
25664                 mLocalPowerManager.finishUidChanges();
25665             }
25666             if (nextTime > 0) {
25667                 mHandler.removeMessages(IDLE_UIDS_MSG);
25668                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
25669                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
25670             }
25671         }
25672     }
25673
25674     /**
25675      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
25676      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
25677      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
25678      */
25679     @VisibleForTesting
25680     @GuardedBy("this")
25681     void incrementProcStateSeqAndNotifyAppsLocked() {
25682         if (mWaitForNetworkTimeoutMs <= 0) {
25683             return;
25684         }
25685         // Used for identifying which uids need to block for network.
25686         ArrayList<Integer> blockingUids = null;
25687         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
25688             final UidRecord uidRec = mActiveUids.valueAt(i);
25689             // If the network is not restricted for uid, then nothing to do here.
25690             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
25691                 continue;
25692             }
25693             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
25694                 continue;
25695             }
25696             // If process state is not changed, then there's nothing to do.
25697             if (uidRec.setProcState == uidRec.curProcState) {
25698                 continue;
25699             }
25700             final int blockState = getBlockStateForUid(uidRec);
25701             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
25702             // there's nothing the app needs to do in this scenario.
25703             if (blockState == NETWORK_STATE_NO_CHANGE) {
25704                 continue;
25705             }
25706             synchronized (uidRec.networkStateLock) {
25707                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
25708                 if (blockState == NETWORK_STATE_BLOCK) {
25709                     if (blockingUids == null) {
25710                         blockingUids = new ArrayList<>();
25711                     }
25712                     blockingUids.add(uidRec.uid);
25713                 } else {
25714                     if (DEBUG_NETWORK) {
25715                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
25716                                 + " threads for uid: " + uidRec);
25717                     }
25718                     if (uidRec.waitingForNetwork) {
25719                         uidRec.networkStateLock.notifyAll();
25720                     }
25721                 }
25722             }
25723         }
25724
25725         // There are no uids that need to block, so nothing more to do.
25726         if (blockingUids == null) {
25727             return;
25728         }
25729
25730         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
25731             final ProcessRecord app = mLruProcesses.get(i);
25732             if (!blockingUids.contains(app.uid)) {
25733                 continue;
25734             }
25735             if (!app.killedByAm && app.thread != null) {
25736                 final UidRecord uidRec = mActiveUids.get(app.uid);
25737                 try {
25738                     if (DEBUG_NETWORK) {
25739                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
25740                                 + uidRec);
25741                     }
25742                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
25743                 } catch (RemoteException ignored) {
25744                 }
25745             }
25746         }
25747     }
25748
25749     /**
25750      * Checks if the uid is coming from background to foreground or vice versa and returns
25751      * appropriate block state based on this.
25752      *
25753      * @return blockState based on whether the uid is coming from background to foreground or
25754      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
25755      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
25756      *         {@link #NETWORK_STATE_NO_CHANGE}.
25757      */
25758     @VisibleForTesting
25759     int getBlockStateForUid(UidRecord uidRec) {
25760         // Denotes whether uid's process state is currently allowed network access.
25761         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
25762                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
25763         // Denotes whether uid's process state was previously allowed network access.
25764         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
25765                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
25766
25767         // When the uid is coming to foreground, AMS should inform the app thread that it should
25768         // block for the network rules to get updated before launching an activity.
25769         if (!wasAllowed && isAllowed) {
25770             return NETWORK_STATE_BLOCK;
25771         }
25772         // When the uid is going to background, AMS should inform the app thread that if an
25773         // activity launch is blocked for the network rules to get updated, it should be unblocked.
25774         if (wasAllowed && !isAllowed) {
25775             return NETWORK_STATE_UNBLOCK;
25776         }
25777         return NETWORK_STATE_NO_CHANGE;
25778     }
25779
25780     final void runInBackgroundDisabled(int uid) {
25781         synchronized (this) {
25782             UidRecord uidRec = mActiveUids.get(uid);
25783             if (uidRec != null) {
25784                 // This uid is actually running...  should it be considered background now?
25785                 if (uidRec.idle) {
25786                     doStopUidLocked(uidRec.uid, uidRec);
25787                 }
25788             } else {
25789                 // This uid isn't actually running...  still send a report about it being "stopped".
25790                 doStopUidLocked(uid, null);
25791             }
25792         }
25793     }
25794
25795     /**
25796      * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
25797      */
25798     void doStopUidForIdleUidsLocked() {
25799         final int size = mActiveUids.size();
25800         for (int i = 0; i < size; i++) {
25801             final int uid = mActiveUids.keyAt(i);
25802             if (UserHandle.isCore(uid)) {
25803                 continue;
25804             }
25805             final UidRecord uidRec = mActiveUids.valueAt(i);
25806             if (!uidRec.idle) {
25807                 continue;
25808             }
25809             doStopUidLocked(uidRec.uid, uidRec);
25810         }
25811     }
25812
25813     final void doStopUidLocked(int uid, final UidRecord uidRec) {
25814         mServices.stopInBackgroundLocked(uid);
25815         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
25816     }
25817
25818     /**
25819      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25820      */
25821     @GuardedBy("this")
25822     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
25823             long duration, String tag) {
25824         if (DEBUG_WHITELISTS) {
25825             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
25826                     + targetUid + ", " + duration + ")");
25827         }
25828
25829         synchronized (mPidsSelfLocked) {
25830             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
25831             if (pr == null) {
25832                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
25833                         + callerPid);
25834                 return;
25835             }
25836             if (!pr.whitelistManager) {
25837                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
25838                         != PackageManager.PERMISSION_GRANTED) {
25839                     if (DEBUG_WHITELISTS) {
25840                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
25841                                 + ": pid " + callerPid + " is not allowed");
25842                     }
25843                     return;
25844                 }
25845             }
25846         }
25847
25848         tempWhitelistUidLocked(targetUid, duration, tag);
25849     }
25850
25851     /**
25852      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25853      */
25854     @GuardedBy("this")
25855     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
25856         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
25857         setUidTempWhitelistStateLocked(targetUid, true);
25858         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
25859     }
25860
25861     void pushTempWhitelist() {
25862         final int N;
25863         final PendingTempWhitelist[] list;
25864
25865         // First copy out the pending changes...  we need to leave them in the map for now,
25866         // in case someone needs to check what is coming up while we don't have the lock held.
25867         synchronized(this) {
25868             N = mPendingTempWhitelist.size();
25869             list = new PendingTempWhitelist[N];
25870             for (int i = 0; i < N; i++) {
25871                 list[i] = mPendingTempWhitelist.valueAt(i);
25872             }
25873         }
25874
25875         // Now safely dispatch changes to device idle controller.
25876         for (int i = 0; i < N; i++) {
25877             PendingTempWhitelist ptw = list[i];
25878             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
25879                     ptw.duration, true, ptw.tag);
25880         }
25881
25882         // And now we can safely remove them from the map.
25883         synchronized(this) {
25884             for (int i = 0; i < N; i++) {
25885                 PendingTempWhitelist ptw = list[i];
25886                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
25887                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
25888                     mPendingTempWhitelist.removeAt(index);
25889                 }
25890             }
25891         }
25892     }
25893
25894     @GuardedBy("this")
25895     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
25896         boolean changed = false;
25897         for (int i=mActiveUids.size()-1; i>=0; i--) {
25898             final UidRecord uidRec = mActiveUids.valueAt(i);
25899             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
25900                 uidRec.curWhitelist = onWhitelist;
25901                 changed = true;
25902             }
25903         }
25904         if (changed) {
25905             updateOomAdjLocked();
25906         }
25907     }
25908
25909     @GuardedBy("this")
25910     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
25911         boolean changed = false;
25912         final UidRecord uidRec = mActiveUids.get(uid);
25913         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
25914             uidRec.curWhitelist = onWhitelist;
25915             updateOomAdjLocked();
25916         }
25917     }
25918
25919     final void trimApplications() {
25920         synchronized (this) {
25921             trimApplicationsLocked();
25922         }
25923     }
25924
25925     final void trimApplicationsLocked() {
25926         // First remove any unused application processes whose package
25927         // has been removed.
25928         for (int i=mRemovedProcesses.size()-1; i>=0; i--) {
25929             final ProcessRecord app = mRemovedProcesses.get(i);
25930             if (app.activities.size() == 0 && app.recentTasks.size() == 0
25931                     && app.curReceivers.isEmpty() && app.services.size() == 0) {
25932                 Slog.i(
25933                     TAG, "Exiting empty application process "
25934                     + app.toShortString() + " ("
25935                     + (app.thread != null ? app.thread.asBinder() : null)
25936                     + ")\n");
25937                 if (app.pid > 0 && app.pid != MY_PID) {
25938                     app.kill("empty", false);
25939                 } else if (app.thread != null) {
25940                     try {
25941                         app.thread.scheduleExit();
25942                     } catch (Exception e) {
25943                         // Ignore exceptions.
25944                     }
25945                 }
25946                 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
25947                 mRemovedProcesses.remove(i);
25948
25949                 if (app.persistent) {
25950                     addAppLocked(app.info, null, false, null /* ABI override */);
25951                 }
25952             }
25953         }
25954
25955         // Now update the oom adj for all processes. Don't skip this, since other callers
25956         // might be depending on it.
25957         updateOomAdjLocked();
25958     }
25959
25960     /** This method sends the specified signal to each of the persistent apps */
25961     public void signalPersistentProcesses(int sig) throws RemoteException {
25962         if (sig != SIGNAL_USR1) {
25963             throw new SecurityException("Only SIGNAL_USR1 is allowed");
25964         }
25965
25966         synchronized (this) {
25967             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
25968                     != PackageManager.PERMISSION_GRANTED) {
25969                 throw new SecurityException("Requires permission "
25970                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
25971             }
25972
25973             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
25974                 ProcessRecord r = mLruProcesses.get(i);
25975                 if (r.thread != null && r.persistent) {
25976                     sendSignal(r.pid, sig);
25977                 }
25978             }
25979         }
25980     }
25981
25982     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
25983         if (proc == null || proc == mProfileProc) {
25984             proc = mProfileProc;
25985             profileType = mProfileType;
25986             clearProfilerLocked();
25987         }
25988         if (proc == null) {
25989             return;
25990         }
25991         try {
25992             proc.thread.profilerControl(false, null, profileType);
25993         } catch (RemoteException e) {
25994             throw new IllegalStateException("Process disappeared");
25995         }
25996     }
25997
25998     private void clearProfilerLocked() {
25999         if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
26000             try {
26001                 mProfilerInfo.profileFd.close();
26002             } catch (IOException e) {
26003             }
26004         }
26005         mProfileApp = null;
26006         mProfileProc = null;
26007         mProfilerInfo = null;
26008     }
26009
26010     public boolean profileControl(String process, int userId, boolean start,
26011             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
26012
26013         try {
26014             synchronized (this) {
26015                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
26016                 // its own permission.
26017                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26018                         != PackageManager.PERMISSION_GRANTED) {
26019                     throw new SecurityException("Requires permission "
26020                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26021                 }
26022
26023                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
26024                     throw new IllegalArgumentException("null profile info or fd");
26025                 }
26026
26027                 ProcessRecord proc = null;
26028                 if (process != null) {
26029                     proc = findProcessLocked(process, userId, "profileControl");
26030                 }
26031
26032                 if (start && (proc == null || proc.thread == null)) {
26033                     throw new IllegalArgumentException("Unknown process: " + process);
26034                 }
26035
26036                 if (start) {
26037                     stopProfilerLocked(null, 0);
26038                     setProfileApp(proc.info, proc.processName, profilerInfo);
26039                     mProfileProc = proc;
26040                     mProfileType = profileType;
26041                     ParcelFileDescriptor fd = profilerInfo.profileFd;
26042                     try {
26043                         fd = fd.dup();
26044                     } catch (IOException e) {
26045                         fd = null;
26046                     }
26047                     profilerInfo.profileFd = fd;
26048                     proc.thread.profilerControl(start, profilerInfo, profileType);
26049                     fd = null;
26050                     try {
26051                         mProfilerInfo.profileFd.close();
26052                     } catch (IOException e) {
26053                     }
26054                     mProfilerInfo.profileFd = null;
26055
26056                     if (proc.pid == MY_PID) {
26057                         // When profiling the system server itself, avoid closing the file
26058                         // descriptor, as profilerControl will not create a copy.
26059                         // Note: it is also not correct to just set profileFd to null, as the
26060                         //       whole ProfilerInfo instance is passed down!
26061                         profilerInfo = null;
26062                     }
26063                 } else {
26064                     stopProfilerLocked(proc, profileType);
26065                     if (profilerInfo != null && profilerInfo.profileFd != null) {
26066                         try {
26067                             profilerInfo.profileFd.close();
26068                         } catch (IOException e) {
26069                         }
26070                     }
26071                 }
26072
26073                 return true;
26074             }
26075         } catch (RemoteException e) {
26076             throw new IllegalStateException("Process disappeared");
26077         } finally {
26078             if (profilerInfo != null && profilerInfo.profileFd != null) {
26079                 try {
26080                     profilerInfo.profileFd.close();
26081                 } catch (IOException e) {
26082                 }
26083             }
26084         }
26085     }
26086
26087     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
26088         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
26089                 userId, true, ALLOW_FULL_ONLY, callName, null);
26090         ProcessRecord proc = null;
26091         try {
26092             int pid = Integer.parseInt(process);
26093             synchronized (mPidsSelfLocked) {
26094                 proc = mPidsSelfLocked.get(pid);
26095             }
26096         } catch (NumberFormatException e) {
26097         }
26098
26099         if (proc == null) {
26100             ArrayMap<String, SparseArray<ProcessRecord>> all
26101                     = mProcessNames.getMap();
26102             SparseArray<ProcessRecord> procs = all.get(process);
26103             if (procs != null && procs.size() > 0) {
26104                 proc = procs.valueAt(0);
26105                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
26106                     for (int i=1; i<procs.size(); i++) {
26107                         ProcessRecord thisProc = procs.valueAt(i);
26108                         if (thisProc.userId == userId) {
26109                             proc = thisProc;
26110                             break;
26111                         }
26112                     }
26113                 }
26114             }
26115         }
26116
26117         return proc;
26118     }
26119
26120     public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
26121             boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
26122
26123         try {
26124             synchronized (this) {
26125                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
26126                 // its own permission (same as profileControl).
26127                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26128                         != PackageManager.PERMISSION_GRANTED) {
26129                     throw new SecurityException("Requires permission "
26130                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26131                 }
26132
26133                 if (fd == null) {
26134                     throw new IllegalArgumentException("null fd");
26135                 }
26136
26137                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
26138                 if (proc == null || proc.thread == null) {
26139                     throw new IllegalArgumentException("Unknown process: " + process);
26140                 }
26141
26142                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26143                 if (!isDebuggable) {
26144                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26145                         throw new SecurityException("Process not debuggable: " + proc);
26146                     }
26147                 }
26148
26149                 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
26150                 fd = null;
26151                 return true;
26152             }
26153         } catch (RemoteException e) {
26154             throw new IllegalStateException("Process disappeared");
26155         } finally {
26156             if (fd != null) {
26157                 try {
26158                     fd.close();
26159                 } catch (IOException e) {
26160                 }
26161             }
26162         }
26163     }
26164
26165     @Override
26166     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
26167             String reportPackage) {
26168         if (processName != null) {
26169             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
26170                     "setDumpHeapDebugLimit()");
26171         } else {
26172             synchronized (mPidsSelfLocked) {
26173                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
26174                 if (proc == null) {
26175                     throw new SecurityException("No process found for calling pid "
26176                             + Binder.getCallingPid());
26177                 }
26178                 if (!Build.IS_DEBUGGABLE
26179                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26180                     throw new SecurityException("Not running a debuggable build");
26181                 }
26182                 processName = proc.processName;
26183                 uid = proc.uid;
26184                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
26185                     throw new SecurityException("Package " + reportPackage + " is not running in "
26186                             + proc);
26187                 }
26188             }
26189         }
26190         synchronized (this) {
26191             if (maxMemSize > 0) {
26192                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
26193             } else {
26194                 if (uid != 0) {
26195                     mMemWatchProcesses.remove(processName, uid);
26196                 } else {
26197                     mMemWatchProcesses.getMap().remove(processName);
26198                 }
26199             }
26200         }
26201     }
26202
26203     @Override
26204     public void dumpHeapFinished(String path) {
26205         synchronized (this) {
26206             if (Binder.getCallingPid() != mMemWatchDumpPid) {
26207                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
26208                         + " does not match last pid " + mMemWatchDumpPid);
26209                 return;
26210             }
26211             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
26212                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
26213                         + " does not match last path " + mMemWatchDumpFile);
26214                 return;
26215             }
26216             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
26217             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
26218
26219             // Forced gc to clean up the remnant hprof fd.
26220             Runtime.getRuntime().gc();
26221         }
26222     }
26223
26224     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
26225     public void monitor() {
26226         synchronized (this) { }
26227     }
26228
26229     void onCoreSettingsChange(Bundle settings) {
26230         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
26231             ProcessRecord processRecord = mLruProcesses.get(i);
26232             try {
26233                 if (processRecord.thread != null) {
26234                     processRecord.thread.setCoreSettings(settings);
26235                 }
26236             } catch (RemoteException re) {
26237                 /* ignore */
26238             }
26239         }
26240     }
26241
26242     // Multi-user methods
26243
26244     /**
26245      * Start user, if its not already running, but don't bring it to foreground.
26246      */
26247     @Override
26248     public boolean startUserInBackground(final int userId) {
26249         return startUserInBackgroundWithListener(userId, null);
26250     }
26251
26252     @Override
26253     public boolean startUserInBackgroundWithListener(final int userId,
26254                 @Nullable IProgressListener unlockListener) {
26255         return mUserController.startUser(userId, /* foreground */ false, unlockListener);
26256     }
26257
26258     @Override
26259     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
26260         return mUserController.unlockUser(userId, token, secret, listener);
26261     }
26262
26263     @Override
26264     public boolean switchUser(final int targetUserId) {
26265         return mUserController.switchUser(targetUserId);
26266     }
26267
26268     @Override
26269     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
26270         return mUserController.stopUser(userId, force, callback);
26271     }
26272
26273     @Override
26274     public UserInfo getCurrentUser() {
26275         return mUserController.getCurrentUser();
26276     }
26277
26278     String getStartedUserState(int userId) {
26279         final UserState userState = mUserController.getStartedUserState(userId);
26280         return UserState.stateToString(userState.state);
26281     }
26282
26283     @Override
26284     public boolean isUserRunning(int userId, int flags) {
26285         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
26286                 && checkCallingPermission(INTERACT_ACROSS_USERS)
26287                     != PackageManager.PERMISSION_GRANTED) {
26288             String msg = "Permission Denial: isUserRunning() from pid="
26289                     + Binder.getCallingPid()
26290                     + ", uid=" + Binder.getCallingUid()
26291                     + " requires " + INTERACT_ACROSS_USERS;
26292             Slog.w(TAG, msg);
26293             throw new SecurityException(msg);
26294         }
26295         return mUserController.isUserRunning(userId, flags);
26296     }
26297
26298     @Override
26299     public int[] getRunningUserIds() {
26300         if (checkCallingPermission(INTERACT_ACROSS_USERS)
26301                 != PackageManager.PERMISSION_GRANTED) {
26302             String msg = "Permission Denial: isUserRunning() from pid="
26303                     + Binder.getCallingPid()
26304                     + ", uid=" + Binder.getCallingUid()
26305                     + " requires " + INTERACT_ACROSS_USERS;
26306             Slog.w(TAG, msg);
26307             throw new SecurityException(msg);
26308         }
26309         return mUserController.getStartedUserArray();
26310     }
26311
26312     @Override
26313     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
26314         mUserController.registerUserSwitchObserver(observer, name);
26315     }
26316
26317     @Override
26318     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
26319         mUserController.unregisterUserSwitchObserver(observer);
26320     }
26321
26322     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
26323         if (info == null) return null;
26324         ApplicationInfo newInfo = new ApplicationInfo(info);
26325         newInfo.initForUser(userId);
26326         return newInfo;
26327     }
26328
26329     public boolean isUserStopped(int userId) {
26330         return mUserController.getStartedUserState(userId) == null;
26331     }
26332
26333     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
26334         if (aInfo == null
26335                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
26336             return aInfo;
26337         }
26338
26339         ActivityInfo info = new ActivityInfo(aInfo);
26340         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
26341         return info;
26342     }
26343
26344     private boolean processSanityChecksLocked(ProcessRecord process) {
26345         if (process == null || process.thread == null) {
26346             return false;
26347         }
26348
26349         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26350         if (!isDebuggable) {
26351             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26352                 return false;
26353             }
26354         }
26355
26356         return true;
26357     }
26358
26359     public boolean startBinderTracking() throws RemoteException {
26360         synchronized (this) {
26361             mBinderTransactionTrackingEnabled = true;
26362             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
26363             // permission (same as profileControl).
26364             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26365                     != PackageManager.PERMISSION_GRANTED) {
26366                 throw new SecurityException("Requires permission "
26367                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26368             }
26369
26370             for (int i = 0; i < mLruProcesses.size(); i++) {
26371                 ProcessRecord process = mLruProcesses.get(i);
26372                 if (!processSanityChecksLocked(process)) {
26373                     continue;
26374                 }
26375                 try {
26376                     process.thread.startBinderTracking();
26377                 } catch (RemoteException e) {
26378                     Log.v(TAG, "Process disappared");
26379                 }
26380             }
26381             return true;
26382         }
26383     }
26384
26385     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
26386         try {
26387             synchronized (this) {
26388                 mBinderTransactionTrackingEnabled = false;
26389                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
26390                 // permission (same as profileControl).
26391                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26392                         != PackageManager.PERMISSION_GRANTED) {
26393                     throw new SecurityException("Requires permission "
26394                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26395                 }
26396
26397                 if (fd == null) {
26398                     throw new IllegalArgumentException("null fd");
26399                 }
26400
26401                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
26402                 pw.println("Binder transaction traces for all processes.\n");
26403                 for (ProcessRecord process : mLruProcesses) {
26404                     if (!processSanityChecksLocked(process)) {
26405                         continue;
26406                     }
26407
26408                     pw.println("Traces for process: " + process.processName);
26409                     pw.flush();
26410                     try {
26411                         TransferPipe tp = new TransferPipe();
26412                         try {
26413                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
26414                             tp.go(fd.getFileDescriptor());
26415                         } finally {
26416                             tp.kill();
26417                         }
26418                     } catch (IOException e) {
26419                         pw.println("Failure while dumping IPC traces from " + process +
26420                                 ".  Exception: " + e);
26421                         pw.flush();
26422                     } catch (RemoteException e) {
26423                         pw.println("Got a RemoteException while dumping IPC traces from " +
26424                                 process + ".  Exception: " + e);
26425                         pw.flush();
26426                     }
26427                 }
26428                 fd = null;
26429                 return true;
26430             }
26431         } finally {
26432             if (fd != null) {
26433                 try {
26434                     fd.close();
26435                 } catch (IOException e) {
26436                 }
26437             }
26438         }
26439     }
26440
26441     @VisibleForTesting
26442     final class LocalService extends ActivityManagerInternal {
26443         @Override
26444         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
26445                 int targetUserId) {
26446             synchronized (ActivityManagerService.this) {
26447                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
26448                         targetPkg, intent, null, targetUserId);
26449             }
26450         }
26451
26452         @Override
26453         public String checkContentProviderAccess(String authority, int userId) {
26454             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
26455         }
26456
26457         @Override
26458         public void onWakefulnessChanged(int wakefulness) {
26459             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
26460         }
26461
26462         @Override
26463         public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
26464                 String processName, String abiOverride, int uid, Runnable crashHandler) {
26465             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
26466                     processName, abiOverride, uid, crashHandler);
26467         }
26468
26469         @Override
26470         public SleepToken acquireSleepToken(String tag, int displayId) {
26471             Preconditions.checkNotNull(tag);
26472             return ActivityManagerService.this.acquireSleepToken(tag, displayId);
26473         }
26474
26475         @Override
26476         public ComponentName getHomeActivityForUser(int userId) {
26477             synchronized (ActivityManagerService.this) {
26478                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
26479                 return homeActivity == null ? null : homeActivity.realActivity;
26480             }
26481         }
26482
26483         @Override
26484         public void onUserRemoved(int userId) {
26485             synchronized (ActivityManagerService.this) {
26486                 ActivityManagerService.this.onUserStoppedLocked(userId);
26487             }
26488             mBatteryStatsService.onUserRemoved(userId);
26489             mUserController.onUserRemoved(userId);
26490         }
26491
26492         @Override
26493         public void onLocalVoiceInteractionStarted(IBinder activity,
26494                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
26495             synchronized (ActivityManagerService.this) {
26496                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
26497                         voiceSession, voiceInteractor);
26498             }
26499         }
26500
26501         @Override
26502         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
26503             synchronized (ActivityManagerService.this) {
26504                 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
26505                         reasons, timestamp);
26506             }
26507         }
26508
26509         @Override
26510         public void notifyAppTransitionFinished() {
26511             synchronized (ActivityManagerService.this) {
26512                 mStackSupervisor.notifyAppTransitionDone();
26513             }
26514         }
26515
26516         @Override
26517         public void notifyAppTransitionCancelled() {
26518             synchronized (ActivityManagerService.this) {
26519                 mStackSupervisor.notifyAppTransitionDone();
26520             }
26521         }
26522
26523         @Override
26524         public List<IBinder> getTopVisibleActivities() {
26525             synchronized (ActivityManagerService.this) {
26526                 return mStackSupervisor.getTopVisibleActivities();
26527             }
26528         }
26529
26530         @Override
26531         public void notifyDockedStackMinimizedChanged(boolean minimized) {
26532             synchronized (ActivityManagerService.this) {
26533                 mStackSupervisor.setDockedStackMinimized(minimized);
26534             }
26535         }
26536
26537         @Override
26538         public void killForegroundAppsForUser(int userHandle) {
26539             synchronized (ActivityManagerService.this) {
26540                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
26541                 final int NP = mProcessNames.getMap().size();
26542                 for (int ip = 0; ip < NP; ip++) {
26543                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
26544                     final int NA = apps.size();
26545                     for (int ia = 0; ia < NA; ia++) {
26546                         final ProcessRecord app = apps.valueAt(ia);
26547                         if (app.persistent) {
26548                             // We don't kill persistent processes.
26549                             continue;
26550                         }
26551                         if (app.removed) {
26552                             procs.add(app);
26553                         } else if (app.userId == userHandle && app.foregroundActivities) {
26554                             app.removed = true;
26555                             procs.add(app);
26556                         }
26557                     }
26558                 }
26559
26560                 final int N = procs.size();
26561                 for (int i = 0; i < N; i++) {
26562                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
26563                 }
26564             }
26565         }
26566
26567         @Override
26568         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
26569                 long duration) {
26570             if (!(target instanceof PendingIntentRecord)) {
26571                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
26572                 return;
26573             }
26574             synchronized (ActivityManagerService.this) {
26575                 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
26576             }
26577         }
26578
26579         @Override
26580         public void setDeviceIdleWhitelist(int[] allAppids, int[] exceptIdleAppids) {
26581             synchronized (ActivityManagerService.this) {
26582                 mDeviceIdleWhitelist = allAppids;
26583                 mDeviceIdleExceptIdleWhitelist = exceptIdleAppids;
26584             }
26585         }
26586
26587         @Override
26588         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
26589             synchronized (ActivityManagerService.this) {
26590                 mDeviceIdleTempWhitelist = appids;
26591                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
26592             }
26593         }
26594
26595         @Override
26596         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
26597                 int userId) {
26598             Preconditions.checkNotNull(values, "Configuration must not be null");
26599             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
26600             synchronized (ActivityManagerService.this) {
26601                 updateConfigurationLocked(values, null, false, true, userId,
26602                         false /* deferResume */);
26603             }
26604         }
26605
26606         @Override
26607         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
26608                 Bundle bOptions) {
26609             Preconditions.checkNotNull(intents, "intents");
26610             final String[] resolvedTypes = new String[intents.length];
26611
26612             // UID of the package on user userId.
26613             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
26614             // packageUid may not be initialized.
26615             int packageUid = 0;
26616             final long ident = Binder.clearCallingIdentity();
26617
26618             try {
26619                 for (int i = 0; i < intents.length; i++) {
26620                     resolvedTypes[i] =
26621                             intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
26622                 }
26623
26624                 packageUid = AppGlobals.getPackageManager().getPackageUid(
26625                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
26626             } catch (RemoteException e) {
26627                 // Shouldn't happen.
26628             } finally {
26629                 Binder.restoreCallingIdentity(ident);
26630             }
26631
26632             synchronized (ActivityManagerService.this) {
26633                 return mActivityStartController.startActivitiesInPackage(
26634                         packageUid, packageName,
26635                         intents, resolvedTypes, null /* resultTo */,
26636                         SafeActivityOptions.fromBundle(bOptions), userId,
26637                         false /* validateIncomingUser */, null /* originatingPendingIntent */);
26638             }
26639         }
26640
26641         @Override
26642         public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
26643                 Intent intent, Bundle options, int userId) {
26644             return ActivityManagerService.this.startActivityAsUser(
26645                     caller, callerPacakge, intent,
26646                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
26647                     null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
26648                     false /*validateIncomingUser*/);
26649         }
26650
26651         @Override
26652         public int getUidProcessState(int uid) {
26653             return getUidState(uid);
26654         }
26655
26656         @Override
26657         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
26658             synchronized (ActivityManagerService.this) {
26659
26660                 // We might change the visibilities here, so prepare an empty app transition which
26661                 // might be overridden later if we actually change visibilities.
26662                 final boolean wasTransitionSet =
26663                         mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
26664                 if (!wasTransitionSet) {
26665                     mWindowManager.prepareAppTransition(TRANSIT_NONE,
26666                             false /* alwaysKeepCurrent */);
26667                 }
26668                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26669
26670                 // If there was a transition set already we don't want to interfere with it as we
26671                 // might be starting it too early.
26672                 if (!wasTransitionSet) {
26673                     mWindowManager.executeAppTransition();
26674                 }
26675             }
26676             if (callback != null) {
26677                 callback.run();
26678             }
26679         }
26680
26681         @Override
26682         public boolean isSystemReady() {
26683             // no need to synchronize(this) just to read & return the value
26684             return mSystemReady;
26685         }
26686
26687         @Override
26688         public void notifyKeyguardTrustedChanged() {
26689             synchronized (ActivityManagerService.this) {
26690                 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
26691                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26692                 }
26693             }
26694         }
26695
26696         /**
26697          * Sets if the given pid has an overlay UI or not.
26698          *
26699          * @param pid The pid we are setting overlay UI for.
26700          * @param hasOverlayUi True if the process has overlay UI.
26701          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
26702          */
26703         @Override
26704         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
26705             synchronized (ActivityManagerService.this) {
26706                 final ProcessRecord pr;
26707                 synchronized (mPidsSelfLocked) {
26708                     pr = mPidsSelfLocked.get(pid);
26709                     if (pr == null) {
26710                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
26711                         return;
26712                     }
26713                 }
26714                 if (pr.hasOverlayUi == hasOverlayUi) {
26715                     return;
26716                 }
26717                 pr.hasOverlayUi = hasOverlayUi;
26718                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
26719                 updateOomAdjLocked(pr, true);
26720             }
26721         }
26722
26723         @Override
26724         public void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
26725             ActivityManagerService.this.setRunningRemoteAnimation(pid, runningRemoteAnimation);
26726         }
26727
26728         /**
26729          * Called after the network policy rules are updated by
26730          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
26731          * and {@param procStateSeq}.
26732          */
26733         @Override
26734         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
26735             if (DEBUG_NETWORK) {
26736                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
26737                         + uid + " seq: " + procStateSeq);
26738             }
26739             UidRecord record;
26740             synchronized (ActivityManagerService.this) {
26741                 record = mActiveUids.get(uid);
26742                 if (record == null) {
26743                     if (DEBUG_NETWORK) {
26744                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
26745                                 + " procStateSeq: " + procStateSeq);
26746                     }
26747                     return;
26748                 }
26749             }
26750             synchronized (record.networkStateLock) {
26751                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26752                     if (DEBUG_NETWORK) {
26753                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
26754                                 + " been handled for uid: " + uid);
26755                     }
26756                     return;
26757                 }
26758                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
26759                 if (record.curProcStateSeq > procStateSeq) {
26760                     if (DEBUG_NETWORK) {
26761                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
26762                                 + ", curProcstateSeq: " + record.curProcStateSeq
26763                                 + ", procStateSeq: " + procStateSeq);
26764                     }
26765                     return;
26766                 }
26767                 if (record.waitingForNetwork) {
26768                     if (DEBUG_NETWORK) {
26769                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
26770                                 + ", procStateSeq: " + procStateSeq);
26771                     }
26772                     record.networkStateLock.notifyAll();
26773                 }
26774             }
26775         }
26776
26777         @Override
26778         public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
26779             synchronized (ActivityManagerService.this) {
26780                 mActiveVoiceInteractionServiceComponent = component;
26781             }
26782         }
26783
26784         /**
26785          * Called after virtual display Id is updated by
26786          * {@link com.android.server.vr.Vr2dDisplay} with a specific
26787          * {@param vrVr2dDisplayId}.
26788          */
26789         @Override
26790         public void setVr2dDisplayId(int vr2dDisplayId) {
26791             if (DEBUG_STACK) {
26792                 Slog.d(TAG, "setVr2dDisplayId called for: " +
26793                         vr2dDisplayId);
26794             }
26795             synchronized (ActivityManagerService.this) {
26796                 mVr2dDisplayId = vr2dDisplayId;
26797             }
26798         }
26799
26800         @Override
26801         public void saveANRState(String reason) {
26802             synchronized (ActivityManagerService.this) {
26803                 final StringWriter sw = new StringWriter();
26804                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
26805                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
26806                 if (reason != null) {
26807                     pw.println("  Reason: " + reason);
26808                 }
26809                 pw.println();
26810                 mActivityStartController.dump(pw, "  ", null);
26811                 pw.println();
26812                 pw.println("-------------------------------------------------------------------------------");
26813                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
26814                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
26815                         "" /* header */);
26816                 pw.println();
26817                 pw.close();
26818
26819                 mLastANRState = sw.toString();
26820             }
26821         }
26822
26823         @Override
26824         public void clearSavedANRState() {
26825             synchronized (ActivityManagerService.this) {
26826                 mLastANRState = null;
26827             }
26828         }
26829
26830         @Override
26831         public void setFocusedActivity(IBinder token) {
26832             synchronized (ActivityManagerService.this) {
26833                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
26834                 if (r == null) {
26835                     throw new IllegalArgumentException(
26836                             "setFocusedActivity: No activity record matching token=" + token);
26837                 }
26838                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
26839                         r, "setFocusedActivity")) {
26840                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
26841                 }
26842             }
26843         }
26844
26845         @Override
26846         public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
26847             synchronized (ActivityManagerService.this) {
26848                 if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
26849                     ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
26850                     if (types == null) {
26851                         if (uid < 0) {
26852                             return;
26853                         }
26854                         types = new ArrayMap<>();
26855                         mAllowAppSwitchUids.put(userId, types);
26856                     }
26857                     if (uid < 0) {
26858                         types.remove(type);
26859                     } else {
26860                         types.put(type, uid);
26861                     }
26862                 }
26863             }
26864         }
26865
26866         @Override
26867         public boolean isRuntimeRestarted() {
26868             return mSystemServiceManager.isRuntimeRestarted();
26869         }
26870
26871         @Override
26872         public boolean hasRunningActivity(int uid, @Nullable String packageName) {
26873             if (packageName == null) return false;
26874
26875             synchronized (ActivityManagerService.this) {
26876                 for (int i = 0; i < mLruProcesses.size(); i++) {
26877                     final ProcessRecord processRecord = mLruProcesses.get(i);
26878                     if (processRecord.uid == uid) {
26879                         for (int j = 0; j < processRecord.activities.size(); j++) {
26880                             final ActivityRecord activityRecord = processRecord.activities.get(j);
26881                             if (packageName.equals(activityRecord.packageName)) {
26882                                 return true;
26883                             }
26884                         }
26885                     }
26886                 }
26887             }
26888             return false;
26889         }
26890
26891         @Override
26892         public void registerScreenObserver(ScreenObserver observer) {
26893             mScreenObservers.add(observer);
26894         }
26895
26896         @Override
26897         public boolean canStartMoreUsers() {
26898             return mUserController.canStartMoreUsers();
26899         }
26900
26901         @Override
26902         public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
26903             mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
26904         }
26905
26906         @Override
26907         public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
26908             mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
26909         }
26910
26911         @Override
26912         public int getMaxRunningUsers() {
26913             return mUserController.mMaxRunningUsers;
26914         }
26915
26916         @Override
26917         public boolean isCallerRecents(int callingUid) {
26918             return getRecentTasks().isCallerRecents(callingUid);
26919         }
26920
26921         @Override
26922         public boolean isRecentsComponentHomeActivity(int userId) {
26923             return getRecentTasks().isRecentsComponentHomeActivity(userId);
26924         }
26925
26926         @Override
26927         public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
26928             ActivityManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
26929         }
26930
26931         @Override
26932         public boolean isUidActive(int uid) {
26933             synchronized (ActivityManagerService.this) {
26934                 return isUidActiveLocked(uid);
26935             }
26936         }
26937
26938         @Override
26939         public List<ProcessMemoryState> getMemoryStateForProcesses() {
26940             List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
26941             synchronized (mPidsSelfLocked) {
26942                 for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
26943                     final ProcessRecord r = mPidsSelfLocked.valueAt(i);
26944                     final int pid = r.pid;
26945                     final int uid = r.uid;
26946                     final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
26947                     if (memoryStat == null) {
26948                         continue;
26949                     }
26950                     ProcessMemoryState processMemoryState =
26951                             new ProcessMemoryState(uid,
26952                                     r.processName,
26953                                     r.maxAdj,
26954                                     memoryStat.pgfault,
26955                                     memoryStat.pgmajfault,
26956                                     memoryStat.rssInBytes,
26957                                     memoryStat.cacheInBytes,
26958                                     memoryStat.swapInBytes);
26959                     processMemoryStates.add(processMemoryState);
26960                 }
26961             }
26962             return processMemoryStates;
26963         }
26964
26965         @Override
26966         public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
26967             ActivityManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
26968         }
26969
26970         @Override
26971         public Intent getHomeIntent() {
26972             synchronized (ActivityManagerService.this) {
26973                 return ActivityManagerService.this.getHomeIntent();
26974             }
26975         }
26976
26977         @Override
26978         public void notifyDefaultDisplaySizeChanged() {
26979             synchronized (ActivityManagerService.this) {
26980                 if (mSystemServiceManager.isBootCompleted() && mHomeProcess != null) {
26981
26982                     // TODO: Ugly hack to unblock the release
26983                     Slog.i(TAG, "Killing home process because of display size change");
26984                     removeProcessLocked(mHomeProcess, false, true, "kill home screen size");
26985                 }
26986             }
26987         }
26988     }
26989
26990     /**
26991      * Called by app main thread to wait for the network policy rules to get updated.
26992      *
26993      * @param procStateSeq The sequence number indicating the process state change that the main
26994      *                     thread is interested in.
26995      */
26996     @Override
26997     public void waitForNetworkStateUpdate(long procStateSeq) {
26998         final int callingUid = Binder.getCallingUid();
26999         if (DEBUG_NETWORK) {
27000             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
27001         }
27002         UidRecord record;
27003         synchronized (this) {
27004             record = mActiveUids.get(callingUid);
27005             if (record == null) {
27006                 return;
27007             }
27008         }
27009         synchronized (record.networkStateLock) {
27010             if (record.lastDispatchedProcStateSeq < procStateSeq) {
27011                 if (DEBUG_NETWORK) {
27012                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
27013                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
27014                             + " lastProcStateSeqDispatchedToObservers: "
27015                             + record.lastDispatchedProcStateSeq);
27016                 }
27017                 return;
27018             }
27019             if (record.curProcStateSeq > procStateSeq) {
27020                 if (DEBUG_NETWORK) {
27021                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
27022                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
27023                             + ", procStateSeq: " + procStateSeq);
27024                 }
27025                 return;
27026             }
27027             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
27028                 if (DEBUG_NETWORK) {
27029                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
27030                             + procStateSeq + ", so no need to wait. Uid: "
27031                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
27032                             + record.lastNetworkUpdatedProcStateSeq);
27033                 }
27034                 return;
27035             }
27036             try {
27037                 if (DEBUG_NETWORK) {
27038                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
27039                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
27040                 }
27041                 final long startTime = SystemClock.uptimeMillis();
27042                 record.waitingForNetwork = true;
27043                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
27044                 record.waitingForNetwork = false;
27045                 final long totalTime = SystemClock.uptimeMillis() - startTime;
27046                 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
27047                     Slog.w(TAG_NETWORK, "Total time waited for network rules to get updated: "
27048                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
27049                             + procStateSeq + " UidRec: " + record
27050                             + " validateUidRec: " + mValidateUids.get(callingUid));
27051                 }
27052             } catch (InterruptedException e) {
27053                 Thread.currentThread().interrupt();
27054             }
27055         }
27056     }
27057
27058     public void waitForBroadcastIdle(PrintWriter pw) {
27059         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
27060         while (true) {
27061             boolean idle = true;
27062             synchronized (this) {
27063                 for (BroadcastQueue queue : mBroadcastQueues) {
27064                     if (!queue.isIdle()) {
27065                         final String msg = "Waiting for queue " + queue + " to become idle...";
27066                         pw.println(msg);
27067                         pw.flush();
27068                         Slog.v(TAG, msg);
27069                         idle = false;
27070                     }
27071                 }
27072             }
27073
27074             if (idle) {
27075                 final String msg = "All broadcast queues are idle!";
27076                 pw.println(msg);
27077                 pw.flush();
27078                 Slog.v(TAG, msg);
27079                 return;
27080             } else {
27081                 SystemClock.sleep(1000);
27082             }
27083         }
27084     }
27085
27086     /**
27087      * Return the user id of the last resumed activity.
27088      */
27089     @Override
27090     public @UserIdInt int getLastResumedActivityUserId() {
27091         enforceCallingPermission(
27092                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
27093         synchronized (this) {
27094             if (mLastResumedActivity == null) {
27095                 return mUserController.getCurrentUserId();
27096             }
27097             return mLastResumedActivity.userId;
27098         }
27099     }
27100
27101     /**
27102      * Kill processes for the user with id userId and that depend on the package named packageName
27103      */
27104     @Override
27105     public void killPackageDependents(String packageName, int userId) {
27106         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
27107         if (packageName == null) {
27108             throw new NullPointerException(
27109                     "Cannot kill the dependents of a package without its name.");
27110         }
27111
27112         long callingId = Binder.clearCallingIdentity();
27113         IPackageManager pm = AppGlobals.getPackageManager();
27114         int pkgUid = -1;
27115         try {
27116             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
27117         } catch (RemoteException e) {
27118         }
27119         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
27120             throw new IllegalArgumentException(
27121                     "Cannot kill dependents of non-existing package " + packageName);
27122         }
27123         try {
27124             synchronized(this) {
27125                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
27126                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
27127                         "dep: " + packageName);
27128             }
27129         } finally {
27130             Binder.restoreCallingIdentity(callingId);
27131         }
27132     }
27133
27134     @Override
27135     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
27136             CharSequence message) throws RemoteException {
27137         if (message != null) {
27138             enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
27139                     "dismissKeyguard()");
27140         }
27141         final long callingId = Binder.clearCallingIdentity();
27142         try {
27143             mKeyguardController.dismissKeyguard(token, callback, message);
27144         } finally {
27145             Binder.restoreCallingIdentity(callingId);
27146         }
27147     }
27148
27149     @Override
27150     public int restartUserInBackground(final int userId) {
27151         return mUserController.restartUser(userId, /* foreground */ false);
27152     }
27153
27154     @Override
27155     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
27156         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
27157                 "scheduleApplicationInfoChanged()");
27158
27159         synchronized (this) {
27160             final long origId = Binder.clearCallingIdentity();
27161             try {
27162                 updateApplicationInfoLocked(packageNames, userId);
27163             } finally {
27164                 Binder.restoreCallingIdentity(origId);
27165             }
27166         }
27167     }
27168
27169     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
27170         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
27171         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
27172             final ProcessRecord app = mLruProcesses.get(i);
27173             if (app.thread == null) {
27174                 continue;
27175             }
27176
27177             if (userId != UserHandle.USER_ALL && app.userId != userId) {
27178                 continue;
27179             }
27180
27181             final int packageCount = app.pkgList.size();
27182             for (int j = 0; j < packageCount; j++) {
27183                 final String packageName = app.pkgList.keyAt(j);
27184                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
27185                     try {
27186                         final ApplicationInfo ai = AppGlobals.getPackageManager()
27187                                 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
27188                         if (ai != null) {
27189                             app.thread.scheduleApplicationInfoChanged(ai);
27190                         }
27191                     } catch (RemoteException e) {
27192                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
27193                                     packageName, app));
27194                     }
27195                 }
27196             }
27197         }
27198         if (updateFrameworkRes) {
27199             // Update system server components that need to know about changed overlays. Because the
27200             // overlay is applied in ActivityThread, we need to serialize through its thread too.
27201             final Executor executor = ActivityThread.currentActivityThread().getExecutor();
27202             final DisplayManagerInternal display =
27203                     LocalServices.getService(DisplayManagerInternal.class);
27204             if (display != null) {
27205                 executor.execute(display::onOverlayChanged);
27206             }
27207             if (mWindowManager != null) {
27208                 executor.execute(mWindowManager::onOverlayChanged);
27209             }
27210         }
27211     }
27212
27213     /**
27214      * Attach an agent to the specified process (proces name or PID)
27215      */
27216     public void attachAgent(String process, String path) {
27217         try {
27218             synchronized (this) {
27219                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
27220                 if (proc == null || proc.thread == null) {
27221                     throw new IllegalArgumentException("Unknown process: " + process);
27222                 }
27223
27224                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
27225                 if (!isDebuggable) {
27226                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
27227                         throw new SecurityException("Process not debuggable: " + proc);
27228                     }
27229                 }
27230
27231                 proc.thread.attachAgent(path);
27232             }
27233         } catch (RemoteException e) {
27234             throw new IllegalStateException("Process disappeared");
27235         }
27236     }
27237
27238     @VisibleForTesting
27239     public static class Injector {
27240         private NetworkManagementInternal mNmi;
27241
27242         public Context getContext() {
27243             return null;
27244         }
27245
27246         public AppOpsService getAppOpsService(File file, Handler handler) {
27247             return new AppOpsService(file, handler);
27248         }
27249
27250         public Handler getUiHandler(ActivityManagerService service) {
27251             return service.new UiHandler();
27252         }
27253
27254         public boolean isNetworkRestrictedForUid(int uid) {
27255             if (ensureHasNetworkManagementInternal()) {
27256                 return mNmi.isNetworkRestrictedForUid(uid);
27257             }
27258             return false;
27259         }
27260
27261         private boolean ensureHasNetworkManagementInternal() {
27262             if (mNmi == null) {
27263                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
27264             }
27265             return mNmi != null;
27266         }
27267     }
27268
27269     @Override
27270     public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
27271             throws RemoteException {
27272         synchronized (this) {
27273             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27274             if (r == null) {
27275                 return;
27276             }
27277             final long origId = Binder.clearCallingIdentity();
27278             try {
27279                 r.setShowWhenLocked(showWhenLocked);
27280             } finally {
27281                 Binder.restoreCallingIdentity(origId);
27282             }
27283         }
27284     }
27285
27286     @Override
27287     public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
27288         synchronized (this) {
27289             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27290             if (r == null) {
27291                 return;
27292             }
27293             final long origId = Binder.clearCallingIdentity();
27294             try {
27295                 r.setTurnScreenOn(turnScreenOn);
27296             } finally {
27297                 Binder.restoreCallingIdentity(origId);
27298             }
27299         }
27300     }
27301
27302     @Override
27303     public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
27304             throws RemoteException {
27305         enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
27306                 "registerRemoteAnimations");
27307         definition.setCallingPid(Binder.getCallingPid());
27308         synchronized (this) {
27309             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27310             if (r == null) {
27311                 return;
27312             }
27313             final long origId = Binder.clearCallingIdentity();
27314             try {
27315                 r.registerRemoteAnimations(definition);
27316             } finally {
27317                 Binder.restoreCallingIdentity(origId);
27318             }
27319         }
27320     }
27321
27322     @Override
27323     public void registerRemoteAnimationForNextActivityStart(String packageName,
27324             RemoteAnimationAdapter adapter) throws RemoteException {
27325         enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
27326                 "registerRemoteAnimationForNextActivityStart");
27327         adapter.setCallingPid(Binder.getCallingPid());
27328         synchronized (this) {
27329             final long origId = Binder.clearCallingIdentity();
27330             try {
27331                 mActivityStartController.registerRemoteAnimationForNextActivityStart(packageName,
27332                         adapter);
27333             } finally {
27334                 Binder.restoreCallingIdentity(origId);
27335             }
27336         }
27337     }
27338
27339     /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
27340     @Override
27341     public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
27342         synchronized (this) {
27343             final long origId = Binder.clearCallingIdentity();
27344             try {
27345                 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
27346             } finally {
27347                 Binder.restoreCallingIdentity(origId);
27348             }
27349         }
27350     }
27351 }