2 * Copyright (C) 2006-2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.server.am;
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;
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;
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;
473 import dalvik.system.VMRuntime;
475 import libcore.io.IoUtils;
476 import libcore.util.EmptyArray;
478 import com.google.android.collect.Lists;
479 import com.google.android.collect.Maps;
481 import org.xmlpull.v1.XmlPullParser;
482 import org.xmlpull.v1.XmlPullParserException;
483 import org.xmlpull.v1.XmlSerializer;
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;
517 public class ActivityManagerService extends IActivityManager.Stub
518 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
521 * Priority we boost main thread and RT of top app to.
523 public static final int TOP_APP_PRIORITY_BOOST = -10;
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;
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";
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;
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;
568 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
570 // Maximum number of receivers an app can register.
571 private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000;
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;
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;
585 * How long we wait for an provider to be published. Should be longer than
586 * {@link #CONTENT_PROVIDER_PUBLISH_TIMEOUT}.
588 static final int CONTENT_PROVIDER_WAIT_TIMEOUT = 20 * 1000;
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;
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;
600 // How long we wait until we timeout on key dispatching.
601 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
603 // How long we wait until we timeout on key dispatching during instrumentation.
604 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
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;
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;
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;
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;
621 // Maximum number of persisted Uri grants a package is allowed
622 static final int MAX_PERSISTED_URI_GRANTS = 128;
624 static final int MY_PID = myPid();
626 static final String[] EMPTY_STRING_ARRAY = new String[0];
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;
634 /** If a UID observer takes more than this long, send a WTF. */
635 private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
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;
642 // Necessary ApplicationInfo flags to mark an app as persistent
643 private static final int PERSISTENT_MASK =
644 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
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";
650 // Used to indicate that an app transition should be animated.
651 static final boolean ANIMATE = true;
653 // Determines whether to take full screen screenshots
654 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
657 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
659 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
662 * State indicating that there is no need for any blocking for network.
665 static final int NETWORK_STATE_NO_CHANGE = 0;
668 * State indicating that the main thread needs to be informed about the network wait.
671 static final int NETWORK_STATE_BLOCK = 1;
674 * State indicating that any threads waiting for network state to get updated can be unblocked.
677 static final int NETWORK_STATE_UNBLOCK = 2;
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;
683 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
685 /** All system services */
686 SystemServiceManager mSystemServiceManager;
688 // Wrapper around VoiceInteractionServiceManager
689 private AssistUtils mAssistUtils;
691 // Keeps track of the active voice interaction service component, notified from
692 // VoiceInteractionManagerService
693 ComponentName mActiveVoiceInteractionServiceComponent;
695 private Installer mInstaller;
697 /** Run all ActivityStacks through this */
698 final ActivityStackSupervisor mStackSupervisor;
699 private final KeyguardController mKeyguardController;
701 private final ActivityStartController mActivityStartController;
703 private final ClientLifecycleManager mLifecycleManager;
705 final TaskChangeNotificationController mTaskChangeNotificationController;
707 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
709 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
711 public final IntentFirewall mIntentFirewall;
713 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
714 // default action automatically. Important for devices without direct input
716 private boolean mShowDialogs = true;
718 private final VrController mVrController;
720 // VR Vr2d Display Id.
721 int mVr2dDisplayId = INVALID_DISPLAY;
723 // Whether we should use SCHED_FIFO for UI and RenderThreads.
724 private boolean mUseFifoUiScheduling = false;
726 private static final String SYSUI_COMPONENT_NAME = "com.android.systemui/.SystemUIService";
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];
734 BroadcastStats mLastBroadcastStats;
735 BroadcastStats mCurBroadcastStats;
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;
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
750 private ActivityRecord mLastResumedActivity;
753 * The activity that is currently being traced as the active resumed activity.
755 * @see #updateResumedAppTrace
757 private @Nullable ActivityRecord mTracedResumedActivity;
760 * If non-null, we are tracking the time the user spends in the currently focused app.
762 private AppTimeTracker mCurAppTimeTracker;
765 * List of intents that were used to start the most recent tasks.
767 private final RecentTasks mRecentTasks;
770 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
772 String mDeviceOwnerName;
775 * The controller for all operations related to locktask.
777 private final LockTaskController mLockTaskController;
779 final UserController mUserController;
782 * Packages that are being allowed to perform unrestricted app switches. Mapping is
783 * User -> Type -> uid.
785 final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
787 final AppErrors mAppErrors;
789 final AppWarnings mAppWarnings;
792 * Dump of the activity state at the time of the last ANR. Cleared after
793 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
795 String mLastANRState;
798 * Indicates the maximum time spent waiting for the network rules to get updated.
801 long mWaitForNetworkTimeoutMs;
803 /** Total # of UID change events dispatched, shown in dumpsys. */
804 int mUidChangeDispatchCount;
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
810 * If priority arguments are omitted all sections are dumped, otherwise sections are dumped
811 * according to their priority.
813 private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
815 public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
818 doDump(fd, pw, new String[]{"activities"}, asProto);
819 doDump(fd, pw, new String[]{"service", SYSUI_COMPONENT_NAME}, asProto);
823 public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
824 doDump(fd, pw, new String[]{"-a", "--normal-priority"}, asProto);
828 public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
829 doDump(fd, pw, args, asProto);
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());
842 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
843 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
845 static void boostPriorityForLockedSection() {
846 sThreadPriorityBooster.boost();
849 static void resetPriorityAfterLockedSection() {
850 sThreadPriorityBooster.reset();
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;
867 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
868 String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
870 activity = _activity;
874 receiver = _receiver;
875 receiverExtras = _receiverExtras;
876 userHandle = _userHandle;
881 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
882 synchronized (this) {
886 pendingAssistExtrasTimedOut(this);
890 final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
893 * Process management.
895 final ProcessList mProcessList = new ProcessList();
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
903 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
906 * Tracking long-term execution of processes to look for abuse and other
909 final ProcessStatsService mProcessStats;
912 * The currently running isolated processes.
914 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
917 * Counter for assigning isolated process uids, to avoid frequently reusing the
920 int mNextIsolatedProcessUid = 0;
923 * The currently running heavy-weight process, if any.
925 ProcessRecord mHeavyWeightProcess = null;
928 * Non-persistent appId whitelist for background restrictions
930 int[] mBackgroundAppIdWhitelist = new int[] {
935 * Broadcast actions that will always be deliverable to unlaunched/background apps
937 ArraySet<String> mBackgroundLaunchBroadcasts;
940 * All of the processes we currently have running organized by pid.
941 * The keys are the pid running the application.
943 * <p>NOTE: This object is protected by its own lock, NOT the global
944 * activity manager lock!
946 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
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
953 abstract class ImportanceToken implements IBinder.DeathRecipient {
958 ImportanceToken(int _pid, IBinder _token, String _reason) {
965 public String toString() {
966 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
967 + " " + reason + " " + pid + " " + token + " }";
970 void writeToProto(ProtoOutputStream proto, long fieldId) {
971 final long pToken = proto.start(fieldId);
972 proto.write(ImportanceTokenProto.PID, pid);
974 proto.write(ImportanceTokenProto.TOKEN, token.toString());
976 proto.write(ImportanceTokenProto.REASON, reason);
980 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
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.
987 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
990 * List of persistent applications that are in the process
993 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
996 * Processes that are being forcibly torn down.
998 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
1001 * List of running applications, sorted by recent usage.
1002 * The first entry in the list is the least recently used.
1004 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
1007 * Where in mLruProcesses that the processes hosting activities start.
1009 int mLruProcessActivityStart = 0;
1012 * Where in mLruProcesses that the processes hosting services start.
1013 * This is after (lower index) than mLruProcessesActivityStart.
1015 int mLruProcessServiceStart = 0;
1018 * List of processes that should gc as soon as things are idle.
1020 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
1023 * Processes we want to collect PSS data from.
1025 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
1027 private boolean mBinderTransactionTrackingEnabled = false;
1030 * Last time we requested PSS data of all processes.
1032 long mLastFullPssTime = SystemClock.uptimeMillis();
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.
1038 boolean mFullPssPending = false;
1041 * This is the process holding what we currently consider to be
1042 * the "home" activity.
1044 ProcessRecord mHomeProcess;
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.
1050 ProcessRecord mPreviousProcess;
1053 * The time at which the previous process was last visible.
1055 long mPreviousProcessVisibleTime;
1058 * Track all uids that have actively running processes.
1060 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1063 * This is for verifying the UID report flow.
1065 static final boolean VALIDATE_UID_STATES = true;
1066 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1069 * Packages that the user has asked to have run in screen size
1070 * compatibility mode instead of filling the screen.
1072 final CompatModePackages mCompatModePackages;
1075 * Set of IntentSenderRecord objects that are currently active.
1077 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1078 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
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.
1086 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1087 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1090 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1091 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1093 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1096 * Resolver for broadcast intents to registered receivers.
1097 * Holds BroadcastFilter (subclass of IntentFilter).
1099 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1100 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
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) {
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);
1123 protected BroadcastFilter[] newArray(int size) {
1124 return new BroadcastFilter[size];
1128 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1129 return packageName.equals(filter.packageName);
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.
1140 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1141 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1143 final ActiveServices mServices;
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;
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];
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;
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.
1179 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1180 mAssociations = new SparseArray<>();
1181 boolean mTrackingAssociations;
1184 * Backup/restore process management
1186 String mBackupAppName = null;
1187 BackupRecord mBackupTarget = null;
1189 final ProviderMap mProviderMap;
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.
1196 final ArrayList<ContentProviderRecord> mLaunchingProviders
1197 = new ArrayList<ContentProviderRecord>();
1200 * File storing persisted {@link #mGrantedUriPermissions}.
1202 private final AtomicFile mGrantFile;
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";
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}.
1223 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1224 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1226 public static class GrantUri {
1227 public final int sourceUserId;
1228 public final Uri uri;
1229 public boolean prefix;
1231 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1232 this.sourceUserId = sourceUserId;
1234 this.prefix = prefix;
1238 public int hashCode() {
1240 hashCode = 31 * hashCode + sourceUserId;
1241 hashCode = 31 * hashCode + uri.hashCode();
1242 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
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;
1257 public String toString() {
1258 String result = uri.toString() + " [user " + sourceUserId + "]";
1259 if (prefix) result += " [prefix]";
1263 public String toSafeString() {
1264 String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1265 if (prefix) result += " [prefix]";
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);
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);
1281 return new GrantUri(defaultSourceUserHandle, uri, false);
1286 boolean mSystemProvidersInstalled;
1288 CoreSettingsObserver mCoreSettingsObserver;
1290 FontScaleSettingObserver mFontScaleSettingObserver;
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);
1296 public FontScaleSettingObserver() {
1298 ContentResolver resolver = mContext.getContentResolver();
1299 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1300 resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
1301 UserHandle.USER_ALL);
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());
1316 DevelopmentSettingsObserver mDevelopmentSettingsObserver;
1318 private final class DevelopmentSettingsObserver extends ContentObserver {
1319 private final Uri mUri = Settings.Global
1320 .getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
1322 private final ComponentName mBugreportStorageProvider = new ComponentName(
1323 "com.android.shell", "com.android.shell.BugreportStorageProvider");
1325 public DevelopmentSettingsObserver() {
1327 mContext.getContentResolver().registerContentObserver(mUri, false, this,
1328 UserHandle.USER_ALL);
1329 // Always kick once to ensure that we match current state
1334 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1335 if (mUri.equals(uri)) {
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,
1351 * Thread-local storage used to carry caller permissions over through
1352 * indirect content-provider access.
1354 private class Identity {
1355 public final IBinder token;
1356 public final int pid;
1357 public final int uid;
1359 Identity(IBinder _token, int _pid, int _uid) {
1366 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1369 * All information we have collected about the runtime performance of
1370 * any user id that can impact battery performance.
1372 final BatteryStatsService mBatteryStatsService;
1375 * Information about component usage
1377 UsageStatsManagerInternal mUsageStatsService;
1380 * Access to DeviceIdleController service.
1382 DeviceIdleController.LocalService mLocalDeviceIdleController;
1385 * Power-save whitelisted app-ids (not including except-idle-whitelisted ones).
1387 int[] mDeviceIdleWhitelist = new int[0];
1390 * Power-save whitelisted app-ids (including except-idle-whitelisted ones).
1392 int[] mDeviceIdleExceptIdleWhitelist = new int[0];
1395 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1397 int[] mDeviceIdleTempWhitelist = new int[0];
1399 static final class PendingTempWhitelist {
1400 final int targetUid;
1401 final long duration;
1404 PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1405 targetUid = _targetUid;
1406 duration = _duration;
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);
1419 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1422 * Information about and control over application operations
1424 final AppOpsService mAppOpsService;
1426 /** Current sequencing integer of the configuration, for skipping old configurations. */
1427 private int mConfigurationSeq;
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
1434 private Configuration mTempConfig = new Configuration();
1436 private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1437 new UpdateConfigurationResult();
1438 private static final class UpdateConfigurationResult {
1439 // Configuration changes that were updated.
1441 // If the activity was relaunched to match the new configuration.
1442 boolean activityRelaunched;
1446 activityRelaunched = false;
1450 boolean mSuppressResizeConfigChanges;
1453 * Hardware-reported OpenGLES version.
1455 final int GL_ES_VERSION;
1458 * List of initialization arguments to pass to all processes when binding applications to them.
1459 * For example, references to the commonly used services.
1461 ArrayMap<String, IBinder> mAppBindArgs;
1462 ArrayMap<String, IBinder> mIsolatedAppBindArgs;
1465 * Temporary to avoid allocations. Protected by main lock.
1467 final StringBuilder mStringBuilder = new StringBuilder(256);
1470 * Used to control how we initialize the service.
1472 ComponentName mTopComponent;
1473 String mTopAction = Intent.ACTION_MAIN;
1476 volatile boolean mProcessesReady = false;
1477 volatile boolean mSystemReady = false;
1478 volatile boolean mOnBattery = false;
1479 volatile int mFactoryTest;
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;
1487 final Context mContext;
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.
1493 final Context mUiContext;
1496 * The time at which we will allow normal application switches again,
1497 * after a call to {@link #stopAppSwitches()}.
1499 long mAppSwitchesAllowedTime;
1502 * This is set to true after the first switch after mAppSwitchesAllowedTime
1503 * is set; any switches after that will clear the time.
1505 boolean mDidAppSwitch;
1508 * Last time (in uptime) at which we checked for power usage.
1510 long mLastPowerCheckUptime;
1513 * Set while we are wanting to sleep, to prevent any
1514 * activities from being started/resumed.
1516 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
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.
1522 * Whether mSleeping can quickly toggled between true/false without the device actually
1523 * display changing states is undefined.
1525 private boolean mSleeping = false;
1528 * The process state used for processes that are running the top activities.
1529 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1531 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1534 * Set while we are running a voice interaction. This overrides
1535 * sleeping while it is active.
1537 IVoiceInteractionSession mRunningVoice;
1540 * For some direct access we need to power manager.
1542 PowerManagerInternal mLocalPowerManager;
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.
1549 PowerManager.WakeLock mVoiceWakeLock;
1552 * State of external calls telling us if the device is awake or asleep.
1554 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1557 * State of external calls telling us if the device is awake or asleep.
1559 private boolean mKeyguardShown = false;
1562 * Set if we are shutting down the system, similar to sleeping.
1564 boolean mShuttingDown = false;
1567 * Current sequence id for oom_adj computation traversal.
1572 * Current sequence id for process LRU updating.
1577 * Keep track of the non-cached/empty process we last found, to help
1578 * determine how to distribute cached/empty processes next time.
1580 int mNumNonCachedProcs = 0;
1583 * Keep track of the number of cached hidden procs, to balance oom adj
1584 * distribution between those and empty procs.
1586 int mNumCachedHiddenProcs = 0;
1589 * Keep track of the number of service processes we last found, to
1590 * determine on the next iteration which should be B services.
1592 int mNumServiceProcs = 0;
1593 int mNewNumAServiceProcs = 0;
1594 int mNewNumServiceProcs = 0;
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.
1602 boolean mAllowLowerMemLevel = false;
1605 * The last computed memory level, for holding when we are in a state that
1606 * processes are going away for other reasons.
1608 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
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.
1614 int mLastNumProcesses;
1617 * The uptime of the last time we performed idle maintenance.
1619 long mLastIdleTime = SystemClock.uptimeMillis();
1622 * Total time spent with RAM that has been added in the past since the last idle time.
1624 long mLowRamTimeSinceLastIdle = 0;
1627 * If RAM is currently low, when that horrible situation started.
1629 long mLowRamStartTime = 0;
1632 * For reporting to battery stats the current top application.
1634 private String mCurResumedPackage = null;
1635 private int mCurResumedUid = -1;
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.
1642 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1643 = new ProcessMap<ArrayList<ProcessRecord>>();
1646 * Set if the systemServer made a call to enterSafeMode.
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.
1655 boolean mTestPssMode = false;
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;
1665 * Flag that indicates if multi-window is enabled.
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'.
1673 * @see #mSupportsSplitScreenMultiWindow
1674 * @see #mSupportsFreeformWindowManagement
1675 * @see #mSupportsPictureInPicture
1676 * @see #mSupportsMultiDisplay
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;
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.
1695 private @Nullable Map<String, String> mAppAgentMap = null;
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;
1706 final long[] mTmpLong = new long[3];
1708 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1711 * A global counter for generating sequence numbers.
1712 * This value will be used when incrementing sequence numbers in individual uidRecords.
1714 * Having a global counter ensures that seq numbers are monotonically increasing for a
1715 * particular uid even when the uidRecord is re-created.
1719 long mProcStateSeqCounter = 0;
1722 * A global counter for generating sequence numbers to uniquely identify pending process starts.
1725 private long mProcStartSeqCounter = 0;
1728 * Contains {@link ProcessRecord} objects for pending process starts.
1730 * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1733 private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1735 private final Injector mInjector;
1737 static final class ProcessChangeItem {
1738 static final int CHANGE_ACTIVITIES = 1<<0;
1743 boolean foregroundActivities;
1746 static final class UidObserverRegistration {
1753 * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
1754 * We show it in dumpsys.
1756 int mSlowDispatchCount;
1758 /** Max time it took for each dispatch. */
1759 int mMaxDispatchTime;
1761 final SparseIntArray lastProcStates;
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,
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,
1777 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1781 cutpoint = _cutpoint;
1782 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1783 lastProcStates = new SparseIntArray();
1785 lastProcStates = null;
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));
1809 final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1811 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1812 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1814 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1815 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1817 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1818 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1820 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1821 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1823 OomAdjObserver mCurOomAdjObserver;
1826 interface OomAdjObserver {
1827 void onOomAdjMessage(String msg);
1831 * Runtime CPU use collection thread. This object's lock is used to
1832 * perform synchronization with the thread (notifying it to run).
1834 final Thread mProcessCpuThread;
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.
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);
1849 long mLastWriteTime = 0;
1852 * Used to retain an update lock when the foreground activity is in
1855 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1858 * Set to true after the system has finished booting.
1860 boolean mBooted = false;
1863 * Current boot phase.
1867 WindowManagerService mWindowManager;
1868 final ActivityThread mSystemThread;
1870 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1871 final ProcessRecord mApp;
1873 final IApplicationThread mAppThread;
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());
1882 mAppThread = thread;
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);
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;
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;
1950 static final String SERVICE_RECORD_KEY = "servicerecord";
1952 static ServiceThread sKillThread = null;
1953 static KillHandler sKillHandler = null;
1955 CompatModeDialog mCompatModeDialog;
1956 long mLastMemUsageReportTime = 0;
1959 * Flag whether the current user is a "monkey", i.e. whether
1960 * the UI is driven by a UI automation tool.
1962 private boolean mUserIsMonkey;
1964 /** The dimensions of the thumbnails in the Recents UI. */
1965 int mThumbnailWidth;
1966 int mThumbnailHeight;
1967 float mFullscreenThumbnailScale;
1969 final ServiceThread mHandlerThread;
1970 final MainHandler mHandler;
1971 final Handler mUiHandler;
1972 final ServiceThread mProcStartHandlerThread;
1973 final Handler mProcStartHandler;
1975 final ActivityManagerConstants mConstants;
1977 // Encapsulates the global setting "hidden_api_blacklist_exemptions"
1978 final HiddenApiSettings mHiddenApiBlacklist;
1980 PackageManagerInternal mPackageManagerInt;
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;
1986 final boolean mPermissionReviewRequired;
1988 boolean mHasHeavyWeightFeature;
1991 * Whether to force background check on all apps (for battery saver) or not.
1993 boolean mForceBackgroundCheck;
1995 private static String sTheRealBuildSerial = Build.UNKNOWN;
1998 * Current global configuration information. Contains general settings for the entire system,
1999 * also corresponds to the merged configuration of the default display.
2001 Configuration getGlobalConfiguration() {
2002 return mStackSupervisor.getConfiguration();
2005 final class KillHandler extends Handler {
2006 static final int KILL_PROCESS_GROUP_MSG = 4000;
2008 public KillHandler(Looper looper) {
2009 super(looper, null, true);
2013 public void handleMessage(Message msg) {
2015 case KILL_PROCESS_GROUP_MSG:
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);
2024 super.handleMessage(msg);
2029 final class UiHandler extends Handler {
2030 public UiHandler() {
2031 super(com.android.server.UiThread.get().getLooper(), null, true);
2035 public void handleMessage(Message msg) {
2037 case SHOW_ERROR_UI_MSG: {
2038 mAppErrors.handleShowAppErrorUi(msg);
2039 ensureBootCompleted();
2041 case SHOW_NOT_RESPONDING_UI_MSG: {
2042 mAppErrors.handleShowAnrUi(msg);
2043 ensureBootCompleted();
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");
2050 Slog.e(TAG, "App not found when showing strict mode dialog.");
2053 if (proc.crashDialog != null) {
2054 Slog.e(TAG, "App already has strict mode dialog: " + proc);
2057 AppErrorResult res = (AppErrorResult) data.get("result");
2058 if (mShowDialogs && !mSleeping && !mShuttingDown) {
2059 Dialog d = new StrictModeViolationDialog(mUiContext,
2060 ActivityManagerService.this, res, proc);
2062 proc.crashDialog = d;
2064 // The device is asleep, so just pretend that the user
2065 // saw a crash dialog and hit "force quit".
2069 ensureBootCompleted();
2071 case SHOW_FACTORY_ERROR_UI_MSG: {
2072 Dialog d = new FactoryErrorDialog(
2073 mUiContext, msg.getData().getCharSequence("msg"));
2075 ensureBootCompleted();
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,
2086 app.waitedForDebugger = true;
2090 if (app.waitDialog != null) {
2091 app.waitDialog.dismiss();
2092 app.waitDialog = null;
2097 case SHOW_UID_ERROR_UI_MSG: {
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));
2109 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
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));
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)) {
2129 mCompatModeDialog.dismiss();
2130 mCompatModeDialog = null;
2132 if (ar != null && false) {
2133 if (mCompatModePackages.getPackageAskCompatModeLocked(
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();
2149 case DISMISS_DIALOG_UI_MSG: {
2150 final Dialog d = (Dialog) msg.obj;
2154 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
2155 dispatchProcessesChanged();
2158 case DISPATCH_PROCESS_DIED_UI_MSG: {
2159 final int pid = msg.arg1;
2160 final int uid = msg.arg2;
2161 dispatchProcessDied(pid, uid);
2164 case DISPATCH_UIDS_CHANGED_UI_MSG: {
2165 dispatchUidsChanged();
2167 case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
2168 dispatchOomAdjObserver((String)msg.obj);
2170 case PUSH_TEMP_WHITELIST_UI_MSG: {
2171 pushTempWhitelist();
2177 final class MainHandler extends Handler {
2178 public MainHandler(Looper looper) {
2179 super(looper, null, true);
2183 public void handleMessage(Message msg) {
2185 case UPDATE_CONFIGURATION_MSG: {
2186 final ContentResolver resolver = mContext.getContentResolver();
2187 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
2190 case GC_BACKGROUND_PROCESSES_MSG: {
2191 synchronized (ActivityManagerService.this) {
2192 performAppGcsIfAppropriateLocked();
2195 case SERVICE_TIMEOUT_MSG: {
2196 mServices.serviceTimeout((ProcessRecord)msg.obj);
2198 case SERVICE_FOREGROUND_TIMEOUT_MSG: {
2199 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
2201 case SERVICE_FOREGROUND_CRASH_MSG: {
2202 mServices.serviceForegroundCrash(
2203 (ProcessRecord) msg.obj, msg.getData().getCharSequence(SERVICE_RECORD_KEY));
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++) {
2211 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2212 } catch (RemoteException e) {
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.
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) {
2226 r.thread.updateTimeZone();
2227 } catch (RemoteException ex) {
2228 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
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) {
2240 r.thread.clearDnsCache();
2241 } catch (RemoteException ex) {
2242 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2248 case UPDATE_HTTP_PROXY_MSG: {
2249 ProxyInfo proxy = (ProxyInfo)msg.obj;
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();
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) {
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);
2276 case PROC_START_TIMEOUT_MSG: {
2277 ProcessRecord app = (ProcessRecord)msg.obj;
2278 synchronized (ActivityManagerService.this) {
2279 processStartTimedOutLocked(app);
2282 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2283 ProcessRecord app = (ProcessRecord)msg.obj;
2284 synchronized (ActivityManagerService.this) {
2285 processContentProviderPublishTimedOutLocked(app);
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);
2299 case FINALIZE_PENDING_INTENT_MSG: {
2300 ((PendingIntentRecord)msg.obj).completeFinalize();
2302 case POST_HEAVY_NOTIFICATION_MSG: {
2303 INotificationManager inm = NotificationManager.getService();
2308 ActivityRecord root = (ActivityRecord)msg.obj;
2309 ProcessRecord process = root.app;
2310 if (process == null) {
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)
2325 .setColor(mContext.getColor(
2326 com.android.internal.R.color.system_notification_accent_color))
2327 .setContentTitle(text)
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)))
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) {
2343 } catch (NameNotFoundException e) {
2344 Slog.w(TAG, "Unable to create context for heavy notification", e);
2347 case CANCEL_HEAVY_NOTIFICATION_MSG: {
2348 INotificationManager inm = NotificationManager.getService();
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) {
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);
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);
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);
2386 mUpdateLock.acquire();
2388 mUpdateLock.release();
2393 case PERSIST_URI_GRANTS_MSG: {
2394 writeGrantedUriPermissions();
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) {
2405 r.thread.updateTimePrefs(msg.arg1);
2406 } catch (RemoteException ex) {
2407 Slog.w(TAG, "Failed to update preferences for: "
2408 + r.info.processName);
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) {
2420 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2421 } catch (RemoteException e) {
2427 case FINISH_BOOTING_MSG: {
2428 if (msg.arg1 != 0) {
2429 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2431 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2433 if (msg.arg2 != 0) {
2434 enableScreenAfterBoot();
2438 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
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);
2450 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2451 final int uid = msg.arg1;
2452 final byte[] firstPacket = (byte[]) msg.obj;
2454 synchronized (mPidsSelfLocked) {
2455 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2456 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2459 p.thread.notifyCleartextNetwork(firstPacket);
2460 } catch (RemoteException ignored) {
2467 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2468 final String procName;
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);
2477 val = mMemWatchProcesses.get(procName, 0);
2480 memLimit = val.first;
2481 reportPackage = val.second;
2484 reportPackage = null;
2487 if (procName == null) {
2491 if (DEBUG_PSS) Slog.d(TAG_PSS,
2492 "Showing dump heap notification from " + procName + "/" + uid);
2494 INotificationManager inm = NotificationManager.getService();
2499 String text = mContext.getString(R.string.dump_heap_notification, procName);
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);
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)
2517 .setAutoCancel(true)
2519 .setColor(mContext.getColor(
2520 com.android.internal.R.color.system_notification_accent_color))
2521 .setContentTitle(text)
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))
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) {
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;
2554 case REPORT_TIME_TRACKER_MSG: {
2555 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2556 tracker.deliverResult(mContext);
2558 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2559 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2561 connection.shutdown();
2562 } catch (RemoteException e) {
2563 Slog.w(TAG, "Error shutting down UiAutomationConnection");
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;
2569 case IDLE_UIDS_MSG: {
2572 case VR_MODE_CHANGE_MSG: {
2573 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
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);
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);
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);
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) {
2604 r.thread.handleTrustStorageUpdate();
2605 } catch (RemoteException ex) {
2606 Slog.w(TAG, "Failed to handle trust storage update for: " +
2607 r.info.processName);
2617 static final int COLLECT_PSS_BG_MSG = 1;
2619 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2621 public void handleMessage(Message msg) {
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();
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;
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.
2649 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
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,
2667 long[] tmp = new long[3];
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();
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)
2692 ProcessList.abortNextPssTime(proc.procStateMemTracker);
2693 if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2695 (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE-now) +
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) {
2709 ProcessList.commitNextPssTime(proc.procStateMemTracker);
2710 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2],
2711 statType, endTime-startTime, SystemClock.uptimeMillis());
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" : ""));
2729 public void setSystemProcess() {
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);
2742 ServiceManager.addService("permission", new PermissionController(this));
2743 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2745 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2746 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2747 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2749 synchronized (this) {
2750 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2751 app.persistent = true;
2753 app.maxAdj = ProcessList.SYSTEM_ADJ;
2754 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2755 synchronized (mPidsSelfLocked) {
2756 mPidsSelfLocked.put(app.pid, app);
2758 updateLruProcessLocked(app, false, null);
2759 updateOomAdjLocked();
2761 } catch (PackageManager.NameNotFoundException e) {
2762 throw new RuntimeException(
2763 "Unable to find android system package", e);
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);
2780 public void setWindowManager(WindowManagerService wm) {
2781 synchronized (this) {
2782 mWindowManager = wm;
2783 mStackSupervisor.setWindowManager(wm);
2784 mLockTaskController.setWindowManager(wm);
2788 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2789 mUsageStatsService = usageStatsManager;
2792 public void startObservingNativeCrashes() {
2793 final NativeCrashListener ncl = new NativeCrashListener(this);
2797 public IAppOpsService getAppOpsService() {
2798 return mAppOpsService;
2801 static class MemBinder extends Binder {
2802 ActivityManagerService mActivityManagerService;
2803 private final PriorityDump.PriorityDumper mPriorityDumper =
2804 new PriorityDump.PriorityDumper() {
2806 public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
2808 dump(fd, pw, new String[] {"-a"}, asProto);
2812 public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
2813 mActivityManagerService.dumpApplicationMemoryUsage(
2814 fd, pw, " ", args, false, null, asProto);
2818 MemBinder(ActivityManagerService activityManagerService) {
2819 mActivityManagerService = activityManagerService;
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);
2830 static class GraphicsBinder extends Binder {
2831 ActivityManagerService mActivityManagerService;
2832 GraphicsBinder(ActivityManagerService activityManagerService) {
2833 mActivityManagerService = activityManagerService;
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);
2844 static class DbBinder extends Binder {
2845 ActivityManagerService mActivityManagerService;
2846 DbBinder(ActivityManagerService activityManagerService) {
2847 mActivityManagerService = activityManagerService;
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);
2858 static class CpuBinder extends Binder {
2859 ActivityManagerService mActivityManagerService;
2860 private final PriorityDump.PriorityDumper mPriorityDumper =
2861 new PriorityDump.PriorityDumper() {
2863 public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
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()));
2876 CpuBinder(ActivityManagerService activityManagerService) {
2877 mActivityManagerService = activityManagerService;
2881 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2882 PriorityDump.dump(mPriorityDumper, fd, pw, args);
2886 public static final class Lifecycle extends SystemService {
2887 private final ActivityManagerService mService;
2889 public Lifecycle(Context context) {
2891 mService = new ActivityManagerService(context);
2895 public void onStart() {
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();
2909 public void onCleanupUser(int userId) {
2910 mService.mBatteryStatsService.onCleanupUser(userId);
2913 public ActivityManagerService getService() {
2919 * Encapsulates global settings related to hidden API enforcement behaviour, including tracking
2920 * the latest value via a content observer.
2922 static class HiddenApiSettings extends ContentObserver {
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;
2932 public HiddenApiSettings(Handler handler, Context context) {
2937 public void registerObserver() {
2938 mContext.getContentResolver().registerContentObserver(
2939 Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
2942 mContext.getContentResolver().registerContentObserver(
2943 Settings.Global.getUriFor(Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE),
2946 mContext.getContentResolver().registerContentObserver(
2947 Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS),
2950 mContext.getContentResolver().registerContentObserver(
2951 Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_P_APPS),
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();
2966 mBlacklistDisabled = false;
2967 mExemptions = TextUtils.isEmpty(exemptions)
2968 ? Collections.emptyList()
2969 : Arrays.asList(exemptions.split(","));
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();
2977 int logSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
2978 Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, -1);
2979 if (logSampleRate < 0 || logSampleRate > 0x10000) {
2982 if (logSampleRate != -1 && logSampleRate != mLogSampleRate) {
2983 mLogSampleRate = logSampleRate;
2984 zygoteProcess.setHiddenApiAccessLogSampleRate(mLogSampleRate);
2986 mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS);
2987 mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS);
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)) {
2996 return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
3000 boolean isDisabled() {
3001 return mBlacklistDisabled;
3004 @HiddenApiEnforcementPolicy int getPolicyForPrePApps() {
3008 @HiddenApiEnforcementPolicy int getPolicyForPApps() {
3012 public void onChange(boolean selfChange) {
3018 public ActivityManagerService(Injector injector) {
3019 mInjector = injector;
3020 mContext = mInjector.getContext();
3023 mActivityStartController = null;
3025 mAppWarnings = null;
3026 mAppOpsService = mInjector.getAppOpsService(null, null);
3027 mBatteryStatsService = null;
3028 mCompatModePackages = 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;
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;
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;
3061 mFactoryTest = FactoryTest.getMode();
3062 mSystemThread = ActivityThread.currentActivityThread();
3063 mUiContext = mSystemThread.getSystemUiContext();
3065 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
3067 mPermissionReviewRequired = mContext.getResources().getBoolean(
3068 com.android.internal.R.bool.config_permissionReviewRequired);
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);
3076 mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
3077 THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
3078 mProcStartHandlerThread.start();
3079 mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
3081 mConstants = new ActivityManagerConstants(this, mHandler);
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());
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;
3098 mServices = new ActiveServices(this);
3099 mProviderMap = new ProviderMap(this);
3100 mAppErrors = new AppErrors(mUiContext, this);
3102 File dataDir = Environment.getDataDirectory();
3103 File systemDir = new File(dataDir, "system");
3106 mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
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);
3116 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
3118 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
3120 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
3122 mUserController = new UserController(this);
3124 mVrController = new VrController(this);
3126 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
3127 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
3129 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
3130 mUseFifoUiScheduling = true;
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();
3150 mProcessCpuThread = new Thread("CpuTracker") {
3153 synchronized (mProcessCpuTracker) {
3154 mProcessCpuInitLatch.countDown();
3155 mProcessCpuTracker.init();
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;
3169 if (nextCpuDelay > 0) {
3170 mProcessCpuMutexFree.set(true);
3171 this.wait(nextCpuDelay);
3174 } catch (InterruptedException e) {
3176 updateCpuStatsNow();
3177 } catch (Exception e) {
3178 Slog.e(TAG, "Unexpected exception collecting process stats", e);
3184 mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);
3186 Watchdog.getInstance().addMonitor(this);
3187 Watchdog.getInstance().addThread(mHandler);
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();
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");
3202 protected ActivityStackSupervisor createStackSupervisor() {
3203 final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
3204 supervisor.initialize();
3208 protected RecentTasks createRecentTasks() {
3209 return new RecentTasks(this, mStackSupervisor);
3212 RecentTasks getRecentTasks() {
3213 return mRecentTasks;
3216 public void setSystemServiceManager(SystemServiceManager mgr) {
3217 mSystemServiceManager = mgr;
3220 public void setInstaller(Installer installer) {
3221 mInstaller = installer;
3224 private void start() {
3225 removeAllProcessGroups();
3226 mProcessCpuThread.start();
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.
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");
3244 void onUserStoppedLocked(int userId) {
3245 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
3246 mAllowAppSwitchUids.remove(userId);
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);
3258 private ArraySet<String> getBackgroundLaunchBroadcasts() {
3259 if (mBackgroundLaunchBroadcasts == null) {
3260 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
3262 return mBackgroundLaunchBroadcasts;
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());
3285 int N = procs.size();
3286 for (int i=0; i<N; i++) {
3287 Parcel data2 = Parcel.obtain();
3289 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
3290 Binder.FLAG_ONEWAY);
3291 } catch (RemoteException e) {
3297 return super.onTransact(code, data, reply, flags);
3298 } catch (RuntimeException e) {
3299 // The activity manager only throws certain exceptions intentionally, so let's
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);
3313 void updateCpuStats() {
3314 final long now = SystemClock.uptimeMillis();
3315 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3318 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3319 synchronized (mProcessCpuThread) {
3320 mProcessCpuThread.notify();
3325 void updateCpuStatsNow() {
3326 synchronized (mProcessCpuTracker) {
3327 mProcessCpuMutexFree.set(false);
3328 final long now = SystemClock.uptimeMillis();
3329 boolean haveNewCpuStats = false;
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() + "%");
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();
3350 int total = user + system + iowait + irq + softIrq + idle;
3351 if (total == 0) total = 1;
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);
3364 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3365 synchronized(bstats) {
3366 synchronized(mPidsSelfLocked) {
3367 if (haveNewCpuStats) {
3368 if (bstats.startAddingCpuLocked()) {
3371 final int N = mProcessCpuTracker.countStats();
3372 for (int i=0; i<N; i++) {
3373 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3377 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3378 totalUTime += st.rel_utime;
3379 totalSTime += st.rel_stime;
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);
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;
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);
3397 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
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);
3412 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3413 mLastWriteTime = now;
3414 mBatteryStatsService.scheduleWriteToDisk();
3421 public void batteryNeedsCpuUpdate() {
3422 updateCpuStatsNow();
3426 public void batteryPowerChanged(boolean onBattery) {
3427 // When plugging in, update the CPU stats first before changing
3429 updateCpuStatsNow();
3430 synchronized (this) {
3431 synchronized(mPidsSelfLocked) {
3432 mOnBattery = DEBUG_POWER ? true : onBattery;
3438 public void batteryStatsReset() {
3439 BinderCallsStatsService.reset();
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);
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.
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.
3460 if (mIsolatedAppBindArgs == null) {
3461 mIsolatedAppBindArgs = new ArrayMap<>(1);
3462 addServiceToMap(mIsolatedAppBindArgs, "package");
3464 return mIsolatedAppBindArgs;
3467 if (mAppBindArgs == null) {
3468 mAppBindArgs = new ArrayMap<>();
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");
3493 return mAppBindArgs;
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);
3501 Log.i(TAG, "Adding " + name + " to the pre-loaded service cache.");
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.
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;
3524 if (r.appTimeTracker != null) {
3525 mCurAppTimeTracker = r.appTimeTracker;
3526 startTimeTrackingFocusedActivityLocked();
3529 startTimeTrackingFocusedActivityLocked();
3532 r.appTimeTracker = null;
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);
3540 finishRunningVoiceLocked();
3542 if (mLastResumedActivity != null) {
3543 final IVoiceInteractionSession session;
3545 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3546 if (lastResumedActivityTask != null
3547 && lastResumedActivityTask.voiceSession != null) {
3548 session = lastResumedActivityTask.voiceSession;
3550 session = mLastResumedActivity.voiceSession;
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);
3563 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3564 mUserController.sendForegroundProfileChanged(r.userId);
3566 updateResumedAppTrace(r);
3567 mLastResumedActivity = r;
3569 mWindowManager.setFocusedApp(r.appToken, true);
3571 applyUpdateLockStateLocked(r);
3572 applyUpdateVrModeLocked(r);
3574 EventLogTags.writeAmSetResumedActivity(
3575 r == null ? -1 : r.userId,
3576 r == null ? "NULL" : r.shortComponentName,
3580 private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
3581 if (mTracedResumedActivity != null) {
3582 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
3583 constructResumedTraceName(mTracedResumedActivity.packageName), 0);
3585 if (resumed != null) {
3586 Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
3587 constructResumedTraceName(resumed.packageName), 0);
3589 mTracedResumedActivity = resumed;
3592 private String constructResumedTraceName(String packageName) {
3593 return "focused app: " + packageName;
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();
3602 synchronized (this) {
3603 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3604 if (stack == null) {
3605 Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3608 final ActivityRecord r = stack.topRunningActivityLocked();
3609 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3610 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3614 Binder.restoreCallingIdentity(callingId);
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();
3624 synchronized (this) {
3625 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3629 final ActivityRecord r = task.topRunningActivityLocked();
3630 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3631 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3635 Binder.restoreCallingIdentity(callingId);
3639 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3641 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3642 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3643 "registerTaskStackListener()");
3644 mTaskChangeNotificationController.registerTaskStackListener(listener);
3648 * Unregister a task stack listener so that it stops receiving callbacks.
3651 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3652 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3653 "unregisterTaskStackListener()");
3654 mTaskChangeNotificationController.unregisterTaskStackListener(listener);
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);
3663 r.getStack().notifyActivityDrawnLocked(r);
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));
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 */);
3693 mHandler.sendMessage(
3694 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
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);
3704 final AppWarnings getAppWarningsLocked() {
3705 return mAppWarnings;
3709 * Shows app warning dialogs, if necessary.
3711 * @param r activity record for which the warnings may be displayed
3713 final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3714 mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3715 mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3716 mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
3719 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3720 String what, Object obj, ProcessRecord srcApp) {
3721 app.lastActivityTime = now;
3723 if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3724 // Don't want to touch dependent processes that are hosting activities.
3728 int lrui = mLruProcesses.lastIndexOf(app);
3730 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3731 + what + " " + obj + " from " + srcApp);
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.
3741 if (lrui >= mLruProcessActivityStart) {
3742 // Don't want to touch dependent processes that are hosting activities.
3746 mLruProcesses.remove(lrui);
3750 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3751 + " in LRU list: " + app);
3752 mLruProcesses.add(index, app);
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));
3761 Slog.w(TAG, "Asked to kill process group before system bringup!");
3762 Process.killProcessGroup(uid, pid);
3766 final void removeLruProcessLocked(ProcessRecord app) {
3767 int lrui = mLruProcesses.lastIndexOf(app);
3770 if (app.persistent) {
3771 Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
3773 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3775 killProcessQuiet(app.pid);
3776 killProcessGroup(app.uid, app.pid);
3778 app.pendingStart = false;
3782 if (lrui <= mLruProcessActivityStart) {
3783 mLruProcessActivityStart--;
3785 if (lrui <= mLruProcessServiceStart) {
3786 mLruProcessServiceStart--;
3788 mLruProcesses.remove(lrui);
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.
3806 final long now = SystemClock.uptimeMillis();
3807 app.lastActivityTime = now;
3809 // First a quick reject: if the app is already at the position we will
3810 // put it, then there is nothing to do.
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);
3818 if (mLruProcessServiceStart > 0
3819 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3820 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3825 int lrui = mLruProcesses.lastIndexOf(app);
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);
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.
3838 boolean inActivity = false, inService = false;
3840 // Process has activities, put it at the very tipsy-top.
3841 addIndex = mLruProcesses.size();
3842 nextIndex = mLruProcessServiceStart;
3844 } else if (hasService) {
3845 // Process has services, put it at the top of the service list.
3846 addIndex = mLruProcessActivityStart;
3847 nextIndex = mLruProcessServiceStart;
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 "
3857 if (clientIndex >= 0 && addIndex > clientIndex) {
3858 addIndex = clientIndex;
3861 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3864 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3865 + mLruProcessActivityStart + "): " + app);
3869 if (lrui < mLruProcessActivityStart) {
3870 mLruProcessActivityStart--;
3872 if (lrui < mLruProcessServiceStart) {
3873 mLruProcessServiceStart--;
3876 if (addIndex > lrui) {
3879 if (nextIndex > lrui) {
3883 mLruProcesses.remove(lrui);
3887 mLruProcesses.add(addIndex, app);
3889 mLruProcessActivityStart++;
3892 mLruProcessActivityStart++;
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);
3926 // A gap, we can stop here.
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);
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++;
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.
3956 if (clientIndex >= 0 && index > clientIndex) {
3957 index = clientIndex;
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++;
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);
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);
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.
4002 return procs.valueAt(i);
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);
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);
4022 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
4028 void notifyPackageUse(String packageName, int reason) {
4029 synchronized(this) {
4030 getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
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;
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,
4064 return proc != null;
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 */);
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();
4087 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
4088 checkTime(startTime, "startProcess: after getProcessRecord");
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);
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,
4110 mAppErrors.clearBadProcessLocked(info);
4117 // If this is an isolated process, it can't re-use an existing process.
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
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");
4142 // An application record is attached to a previous process,
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");
4151 String hostingNameStr = hostingName != null
4152 ? hostingName.flattenToShortString() : null;
4155 checkTime(startTime, "startProcess: creating new process record");
4156 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
4158 Slog.w(TAG, "Failed making new process record for "
4159 + processName + "/" + info.uid + " isolated=" + isolated);
4162 app.crashHandler = crashHandler;
4163 app.isolatedEntryPoint = entryPoint;
4164 app.isolatedEntryPointArgs = entryPointArgs;
4165 checkTime(startTime, "startProcess: done creating new process record");
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");
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);
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");
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;
4192 boolean isAllowedWhileBooting(ApplicationInfo ai) {
4193 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
4197 private final void startProcessLocked(ProcessRecord app,
4198 String hostingType, String hostingNameStr) {
4199 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
4203 private final boolean startProcessLocked(ProcessRecord app,
4204 String hostingType, String hostingNameStr, String abiOverride) {
4205 return startProcessLocked(app, hostingType, hostingNameStr,
4206 false /* disableHiddenApiChecks */, abiOverride);
4210 * @return {@code true} if process start is successful, false otherwise.
4213 private final boolean startProcessLocked(ProcessRecord app, String hostingType,
4214 String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
4215 if (app.pendingStart) {
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);
4225 checkTime(startTime, "startProcess: done removing from pids map");
4230 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
4231 "startProcessLocked removing on hold: " + app);
4232 mProcessesOnHold.remove(app);
4234 checkTime(startTime, "startProcess: starting to update cpu stats");
4236 checkTime(startTime, "startProcess: done updating cpu stats");
4240 final int userId = UserHandle.getUserId(app.uid);
4241 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
4242 } catch (RemoteException e) {
4243 throw e.rethrowAsRuntimeException();
4248 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
4249 if (!app.isolated) {
4250 int[] permGids = null;
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();
4265 * Add shared application and profile GIDs so applications can share some
4266 * resources like shared libraries and access user-wide resources
4268 if (ArrayUtils.isEmpty(permGids)) {
4271 gids = new int[permGids.length + 3];
4272 System.arraycopy(permGids, 0, gids, 3, permGids.length);
4274 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
4275 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
4276 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
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];
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())) {
4289 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
4290 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
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;
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;
4308 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4309 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4311 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4312 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
4313 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4315 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
4316 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
4317 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
4319 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4320 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4322 if ("1".equals(SystemProperties.get("debug.assert"))) {
4323 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
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;
4333 if (app.info.isPrivilegedApp() &&
4334 DexManager.isPackageSelectedToRunOob(app.pkgList.keySet())) {
4335 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
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);
4348 runtimeFlags |= policyBits;
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();
4357 if (new File(wrapperFileName).exists()) {
4358 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4361 StrictMode.setThreadPolicy(oldPolicy);
4365 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4366 if (requiredAbi == null) {
4367 requiredAbi = Build.SUPPORTED_ABIS[0];
4370 String instructionSet = null;
4371 if (app.info.primaryCpuAbi != null) {
4372 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4376 app.requiredAbi = requiredAbi;
4377 app.instructionSet = instructionSet;
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 + ")"));
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";
4391 return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4392 runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4394 } catch (RuntimeException e) {
4395 Slog.e(TAG, "Failure starting process " + app.processName, e);
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");
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,
4414 app.pendingStart = true;
4415 app.killedByAm = false;
4416 app.removed = false;
4418 if (app.startSeq != 0) {
4419 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
4420 + " with non-zero startSeq:" + app.startSeq);
4423 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
4424 + " with non-zero pid:" + app.pid);
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(() -> {
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;
4441 app.usingWrapper = invokeWith != null
4442 || SystemProperties.get("wrap." + app.processName) != null;
4443 mPendingStarts.put(startSeq, app);
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);
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");
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,
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");
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,
4486 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
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});
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});
4503 checkTime(startTime, "startProcess: returned from zygote!");
4506 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
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;");
4517 if (mProcessNames.get(app.processName, app.uid) != app) {
4518 if (sb == null) sb = new StringBuilder();
4519 sb.append("No entry in mProcessNames;");
4521 if (!app.pendingStart) {
4522 if (sb == null) sb = new StringBuilder();
4523 sb.append("pendingStart=false;");
4525 if (app.startSeq > expectedStartSeq) {
4526 if (sb == null) sb = new StringBuilder();
4527 sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4529 return sb == null ? null : sb.toString();
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
4543 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4544 expectedStartSeq, false);
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
4555 app.pendingStart = false;
4556 Process.killProcessQuiet(pid);
4557 Process.killProcessGroup(app.uid, app.pid);
4560 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4561 checkTime(app.startTime, "startProcess: done updating battery stats");
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 : "");
4569 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4570 app.seInfo, app.info.sourceDir, pid);
4571 } catch (RemoteException ex) {
4575 if (app.persistent) {
4576 Watchdog.getInstance().processStarted(app.processName, pid);
4579 checkTime(app.startTime, "startProcess: building log message");
4580 StringBuilder buf = mStringBuilder;
4582 buf.append("Start proc ");
4585 buf.append(app.processName);
4587 UserHandle.formatUid(buf, app.startUid);
4588 if (app.isolatedEntryPoint != null) {
4590 buf.append(app.isolatedEntryPoint);
4593 buf.append(" for ");
4594 buf.append(app.hostingType);
4595 if (app.hostingNameStr != null) {
4597 buf.append(app.hostingNameStr);
4599 reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
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);
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
4614 + " belongs to another existing app:" + oldApp.processName
4615 + " startSeq:" + oldApp.startSeq);
4616 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4617 true /*replacingPid*/);
4619 synchronized (mPidsSelfLocked) {
4620 this.mPidsSelfLocked.put(pid, app);
4621 if (!procAttached) {
4622 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4624 mHandler.sendMessageDelayed(msg, usingWrapper
4625 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4628 checkTime(app.startTime, "startProcess: done updating pids map");
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);
4642 if (mUsageStatsService != null) {
4643 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4644 UsageEvents.Event.MOVE_TO_FOREGROUND);
4647 synchronized (stats) {
4648 stats.noteActivityResumedLocked(component.app.uid);
4651 if (mUsageStatsService != null) {
4652 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4653 UsageEvents.Event.MOVE_TO_BACKGROUND);
4655 synchronized (stats) {
4656 stats.noteActivityPausedLocked(component.app.uid);
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);
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.
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
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
4694 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4695 mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4698 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4704 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4705 ActivityInfo ai = null;
4706 ComponentName comp = intent.getComponent();
4710 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4712 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4714 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4718 ai = info.activityInfo;
4721 } catch (RemoteException e) {
4728 boolean getCheckedForSetup() {
4729 return mCheckedForSetup;
4732 void setCheckedForSetup(boolean checked) {
4733 mCheckedForSetup = checked;
4736 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4737 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4740 void enforceNotIsolatedCaller(String caller) {
4741 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4742 throw new SecurityException("Isolated process not allowed to call " + caller);
4747 public int getFrontActivityScreenCompatMode() {
4748 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4749 synchronized (this) {
4750 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4755 public void setFrontActivityScreenCompatMode(int mode) {
4756 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4757 "setFrontActivityScreenCompatMode");
4758 synchronized (this) {
4759 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4764 public int getPackageScreenCompatMode(String packageName) {
4765 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4766 synchronized (this) {
4767 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
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);
4781 public boolean getPackageAskScreenCompat(String packageName) {
4782 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4783 synchronized (this) {
4784 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
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);
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;
4804 return mode == AppOpsManager.MODE_ALLOWED;
4808 public int getPackageProcessState(String packageName, String callingPackage) {
4809 if (!hasUsageStatsPermission(callingPackage)) {
4810 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4811 "getPackageProcessState");
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;
4830 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4831 throws RemoteException {
4832 synchronized (this) {
4833 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4835 throw new IllegalArgumentException("Unknown process: " + process);
4837 if (app.thread == null) {
4838 throw new IllegalArgumentException("Process has no app thread");
4840 if (app.trimMemoryLevel >= level) {
4841 throw new IllegalArgumentException(
4842 "Unable to set a higher trim level than current level");
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");
4849 app.thread.scheduleTrimMemory(level);
4850 app.trimMemoryLevel = level;
4855 private void dispatchProcessesChanged() {
4857 synchronized (this) {
4858 N = mPendingProcessChanges.size();
4859 if (mActiveProcessChanges.length < N) {
4860 mActiveProcessChanges = new ProcessChangeItem[N];
4862 mPendingProcessChanges.toArray(mActiveProcessChanges);
4863 mPendingProcessChanges.clear();
4864 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4865 "*** Delivering " + N + " process changes");
4868 int i = mProcessObservers.beginBroadcast();
4871 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4872 if (observer != null) {
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);
4884 } catch (RemoteException e) {
4888 mProcessObservers.finishBroadcast();
4890 synchronized (this) {
4891 for (int j=0; j<N; j++) {
4892 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4897 private void dispatchProcessDied(int pid, int uid) {
4898 int i = mProcessObservers.beginBroadcast();
4901 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4902 if (observer != null) {
4904 observer.onProcessDied(pid, uid);
4905 } catch (RemoteException e) {
4909 mProcessObservers.finishBroadcast();
4913 void dispatchUidsChanged() {
4915 synchronized (this) {
4916 N = mPendingUidChanges.size();
4917 if (mActiveUidChanges.length < N) {
4918 mActiveUidChanges = new UidRecord.ChangeItem[N];
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;
4928 mPendingUidChanges.clear();
4929 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4930 "*** Delivering " + N + " uid changes");
4933 mUidChangeDispatchCount += N;
4934 int i = mUidObservers.beginBroadcast();
4937 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4938 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4940 mUidObservers.finishBroadcast();
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);
4948 UidRecord validateUid = mValidateUids.get(item.uid);
4949 if (validateUid == null) {
4950 validateUid = new UidRecord(item.uid);
4951 mValidateUids.put(item.uid, validateUid);
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;
4958 validateUid.curProcState = validateUid.setProcState = item.processState;
4959 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4964 synchronized (this) {
4965 for (int j = 0; j < N; j++) {
4966 mAvailUidChanges.add(mActiveUidChanges[j]);
4971 private void dispatchUidsChangedForObserver(IUidObserver observer,
4972 UidObserverRegistration reg, int changesSize) {
4973 if (observer == null) {
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.
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);
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);
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);
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);
5017 if (reg.lastProcStates != null) {
5018 reg.lastProcStates.delete(item.uid);
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;
5034 doReport = item.processState
5035 != ActivityManager.PROCESS_STATE_NONEXISTENT;
5039 if (reg.lastProcStates != null) {
5040 reg.lastProcStates.put(item.uid, item.processState);
5042 observer.onUidStateChanged(item.uid, item.processState,
5047 final int duration = (int) (SystemClock.uptimeMillis() - start);
5048 if (reg.mMaxDispatchTime < duration) {
5049 reg.mMaxDispatchTime = duration;
5051 if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
5052 reg.mSlowDispatchCount++;
5055 } catch (RemoteException e) {
5059 void dispatchOomAdjObserver(String msg) {
5060 OomAdjObserver observer;
5061 synchronized (this) {
5062 observer = mCurOomAdjObserver;
5065 if (observer != null) {
5066 observer.onOomAdjMessage(msg);
5070 void setOomAdjObserver(int uid, OomAdjObserver observer) {
5071 synchronized (this) {
5072 mCurOomAdjUid = uid;
5073 mCurOomAdjObserver = observer;
5077 void clearOomAdjObserver() {
5078 synchronized (this) {
5080 mCurOomAdjObserver = null;
5084 void reportOomAdjMessageLocked(String tag, String msg) {
5086 if (mCurOomAdjObserver != null) {
5087 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
5091 void reportUidInfoMessageLocked(String tag, String msg, int uid) {
5093 if (mCurOomAdjObserver != null && uid == mCurOomAdjUid) {
5094 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
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());
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*/);
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");
5123 userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
5124 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
5126 // TODO: Switch to user app stacks here.
5127 return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
5129 .setCallingPackage(callingPackage)
5130 .setResolvedType(resolvedType)
5131 .setResultTo(resultTo)
5132 .setResultWho(resultWho)
5133 .setRequestCode(requestCode)
5134 .setStartFlags(startFlags)
5135 .setProfilerInfo(profilerInfo)
5136 .setActivityOptions(bOptions)
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,
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");
5160 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
5161 if (sourceRecord == null) {
5162 throw new SecurityException("Called with bad activity token: " + resultTo);
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");
5168 if (sourceRecord.app == null) {
5169 throw new SecurityException("Called without a process attached to activity");
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);
5181 if (ignoreTargetSecurity) {
5182 if (intent.getComponent() == null) {
5183 throw new SecurityException(
5184 "Component must be specified with ignoreTargetSecurity");
5186 if (intent.getSelector() != null) {
5187 throw new SecurityException(
5188 "Selector not allowed with ignoreTargetSecurity");
5191 targetUid = sourceRecord.launchedFromUid;
5192 targetPackage = sourceRecord.launchedFromPackage;
5193 isResolver = sourceRecord.isResolverOrChildActivity();
5196 if (userId == UserHandle.USER_NULL) {
5197 userId = UserHandle.getUserId(sourceRecord.app.uid);
5200 // TODO: Switch to user app stacks here.
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)
5212 .setIgnoreTargetSecurity(ignoreTargetSecurity)
5213 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
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
5221 StringBuilder msg = new StringBuilder();
5222 msg.append("While launching");
5223 msg.append(intent.toString());
5225 msg.append(e.getMessage());
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")
5242 .setCallingPackage(callingPackage)
5243 .setResolvedType(resolvedType)
5244 .setResultTo(resultTo)
5245 .setResultWho(resultWho)
5246 .setRequestCode(requestCode)
5247 .setStartFlags(startFlags)
5248 .setActivityOptions(bOptions)
5250 .setProfilerInfo(profilerInfo)
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")
5266 .setCallingPackage(callingPackage)
5267 .setResolvedType(resolvedType)
5268 .setResultTo(resultTo)
5269 .setResultWho(resultWho)
5270 .setRequestCode(requestCode)
5271 .setStartFlags(startFlags)
5272 .setGlobalConfiguration(config)
5273 .setActivityOptions(bOptions)
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");
5289 if (!(target instanceof PendingIntentRecord)) {
5290 throw new IllegalArgumentException("Bad PendingIntent object");
5293 PendingIntentRecord pir = (PendingIntentRecord)target;
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;
5304 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
5305 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
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");
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)
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);
5341 return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
5342 .setCallingUid(callingUid)
5343 .setCallingPackage(callingPackage)
5344 .setResolvedType(resolvedType)
5345 .setActivityOptions(bOptions)
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();
5357 synchronized (this) {
5358 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
5359 final int recentsUid = mRecentTasks.getRecentsComponentUid();
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);
5368 Binder.restoreCallingIdentity(origId);
5373 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5374 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
5375 final long callingUid = Binder.getCallingUid();
5376 final long origId = Binder.clearCallingIdentity();
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);
5385 Binder.restoreCallingIdentity(origId);
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");
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");
5403 if (activity.pendingVoiceInteractionStart) {
5404 Slog.w(TAG, "Pending start of voice interaction already.");
5407 activity.pendingVoiceInteractionStart = true;
5409 LocalServices.getService(VoiceInteractionManagerInternal.class)
5410 .startLocalVoiceInteraction(callingActivity, options);
5414 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5415 LocalServices.getService(VoiceInteractionManagerInternal.class)
5416 .stopLocalVoiceInteraction(callingActivity);
5420 public boolean supportsLocalVoiceInteraction() throws RemoteException {
5421 return LocalServices.getService(VoiceInteractionManagerInternal.class)
5422 .supportsLocalVoiceInteraction();
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);
5432 // Inform the activity
5434 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5436 long token = Binder.clearCallingIdentity();
5438 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5440 Binder.restoreCallingIdentity(token);
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?
5451 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5452 synchronized (this) {
5453 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5455 mVoiceWakeLock.acquire();
5457 mVoiceWakeLock.release();
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");
5470 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5472 synchronized (this) {
5473 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5475 SafeActivityOptions.abort(options);
5478 if (r.app == null || r.app.thread == null) {
5479 // The caller is not running... d'oh!
5480 SafeActivityOptions.abort(options);
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);
5489 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5491 ActivityInfo aInfo = null;
5493 List<ResolveInfo> resolves =
5494 AppGlobals.getPackageManager().queryIntentActivities(
5495 intent, r.resolvedType,
5496 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5497 UserHandle.getCallingUserId()).getList();
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
5509 aInfo = resolves.get(i).activityInfo;
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));
5520 } catch (RemoteException e) {
5523 if (aInfo == null) {
5524 // Nobody who is next!
5525 SafeActivityOptions.abort(options);
5526 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
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));
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.
5543 final boolean wasFinishing = r.finishing;
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;
5551 if (resultTo != null) {
5552 resultTo.removeResultsLocked(r, resultWho, requestCode);
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)
5566 .setCallingUid(r.launchedFromUid)
5567 .setCallingPackage(r.launchedFromPackage)
5568 .setRealCallingPid(-1)
5569 .setRealCallingUid(r.launchedFromUid)
5570 .setActivityOptions(options)
5572 Binder.restoreCallingIdentity(origId);
5574 r.finishing = wasFinishing;
5575 if (res != ActivityManager.START_SUCCESS) {
5583 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5584 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5585 "startActivityFromRecents()");
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();
5592 synchronized (this) {
5593 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5597 Binder.restoreCallingIdentity(origId);
5602 public final int startActivities(IApplicationThread caller, String callingPackage,
5603 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
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 */);
5617 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5618 synchronized (this) {
5619 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5623 r.reportFullyDrawnLocked(restoredFromBundle);
5628 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5629 synchronized (this) {
5630 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5634 final long origId = Binder.clearCallingIdentity();
5636 r.setRequestedOrientation(requestedOrientation);
5638 Binder.restoreCallingIdentity(origId);
5644 public int getRequestedOrientation(IBinder token) {
5645 synchronized (this) {
5646 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5648 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5650 return r.getRequestedOrientation();
5655 * This is the internal entry point for handling Activity.finish().
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.
5662 * @return Returns true if the activity successfully finished, or false if it is still running.
5665 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5667 // Refuse possible leaked file descriptors
5668 if (resultData != null && resultData.hasFileDescriptors() == true) {
5669 throw new IllegalArgumentException("File descriptors passed in Intent");
5672 synchronized(this) {
5673 ActivityRecord r = ActivityRecord.isInStackLocked(token);
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");
5683 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5685 if (mLockTaskController.activityBlockedFromFinish(r)) {
5689 if (mController != null) {
5690 // Find the first activity that is not finishing.
5691 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5693 // ask watcher if this is allowed
5694 boolean resumeOK = true;
5696 resumeOK = mController.activityResuming(next.packageName);
5697 } catch (RemoteException e) {
5699 Watchdog.getInstance().setActivityController(null);
5703 Slog.i(TAG, "Not finishing activity because controller resumed");
5708 final long origId = Binder.clearCallingIdentity();
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");
5723 Slog.i(TAG, "Removing task failed to finish activity");
5726 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5727 resultData, "app-request", true);
5729 Slog.i(TAG, "Failed to finish by app-request");
5734 Binder.restoreCallingIdentity(origId);
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;
5748 throw new SecurityException(msg);
5751 synchronized(this) {
5752 final ProcessRecord proc = mHeavyWeightProcess;
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);
5766 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5768 mHeavyWeightProcess = null;
5773 public void crashApplication(int uid, int initialPid, String packageName, int userId,
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;
5782 throw new SecurityException(msg);
5785 synchronized(this) {
5786 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5791 public final void finishSubActivity(IBinder token, String resultWho,
5793 synchronized(this) {
5794 final long origId = Binder.clearCallingIdentity();
5795 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5797 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5799 Binder.restoreCallingIdentity(origId);
5804 public boolean finishActivityAffinity(IBinder token) {
5805 synchronized(this) {
5806 final long origId = Binder.clearCallingIdentity();
5808 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5813 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5815 final TaskRecord task = r.getTask();
5816 if (mLockTaskController.activityBlockedFromFinish(r)) {
5819 return task.getStack().finishActivityAffinityLocked(r);
5821 Binder.restoreCallingIdentity(origId);
5827 public void finishVoiceTask(IVoiceInteractionSession session) {
5828 synchronized (this) {
5829 final long origId = Binder.clearCallingIdentity();
5831 // TODO: VI Consider treating local voice interactions and voice tasks
5833 mStackSupervisor.finishVoiceTask(session);
5835 Binder.restoreCallingIdentity(origId);
5842 public boolean releaseActivityInstance(IBinder token) {
5843 synchronized(this) {
5844 final long origId = Binder.clearCallingIdentity();
5846 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5850 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5852 Binder.restoreCallingIdentity(origId);
5858 public void releaseSomeActivities(IApplicationThread appInt) {
5859 synchronized(this) {
5860 final long origId = Binder.clearCallingIdentity();
5862 ProcessRecord app = getRecordForAppLocked(appInt);
5863 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5865 Binder.restoreCallingIdentity(origId);
5871 public boolean willActivityBeVisible(IBinder token) {
5872 synchronized(this) {
5873 ActivityStack stack = ActivityRecord.getStackLocked(token);
5874 if (stack != null) {
5875 return stack.willActivityBeVisibleLocked(token);
5882 public void overridePendingTransition(IBinder token, String packageName,
5883 int enterAnim, int exitAnim) {
5884 synchronized(this) {
5885 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5890 final long origId = Binder.clearCallingIdentity();
5892 if (self.isState(ActivityState.RESUMED, ActivityState.PAUSING)) {
5893 mWindowManager.overridePendingAppTransition(packageName,
5894 enterAnim, exitAnim, null);
5897 Binder.restoreCallingIdentity(origId);
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
5907 private final void handleAppDiedLocked(ProcessRecord app,
5908 boolean restarting, boolean allowRestart) {
5910 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5911 false /*replacingPid*/);
5912 if (!kept && !restarting) {
5913 removeLruProcessLocked(app);
5915 ProcessList.remove(pid);
5919 if (mProfileProc == app) {
5920 clearProfilerLocked();
5923 // Remove this application's activities from active lists.
5924 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5926 app.clearRecentTasks();
5928 app.activities.clear();
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);
5938 mWindowManager.deferSurfaceLayout();
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);
5948 mWindowManager.continueSurfaceLayout();
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) {
5965 ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5966 if (thread == null) {
5970 int appIndex = getLRURecordIndexForAppLocked(thread);
5971 if (appIndex >= 0) {
5972 return mLruProcesses.get(appIndex);
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: "
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) {
6009 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6011 long now = SystemClock.uptimeMillis();
6012 if (now < (mLastMemUsageReportTime+5*60*1000)) {
6015 mLastMemUsageReportTime = now;
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) {
6028 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
6029 rec.setProcState, rec.adjType, rec.makeAdjReason()));
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;
6038 rec.lastRequestedGc = rec.lastLowMemory;
6040 rec.reportLowMemory = true;
6041 rec.lastLowMemory = now;
6042 mProcessesToGc.remove(rec);
6043 addProcessToGcListLocked(rec);
6047 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
6048 mHandler.sendMessage(msg);
6050 scheduleAppGcsLocked();
6055 final void appDiedLocked(ProcessRecord app) {
6056 appDiedLocked(app, app.pid, app.thread, false);
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);
6071 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6072 synchronized (stats) {
6073 stats.noteProcessDiedLocked(app.info.uid, pid);
6077 if (!fromBinderDied) {
6078 killProcessQuiet(pid);
6080 killProcessGroup(app.uid, pid);
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;
6096 // Note that we always want to do oom adj to update our state with the
6097 // new number of procs.
6098 mAllowLowerMemLevel = false;
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);
6108 updateOomAdjLocked();
6111 doLowMemReportIfNeededLocked(app);
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());
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.
6127 StatsLog.write(StatsLog.APP_DIED, SystemClock.elapsedRealtime());
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
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;
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();
6151 } catch (InterruptedException ignored) {
6154 processCpuTracker.update();
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);
6164 extraPids.add(stats.pid);
6165 } else if (DEBUG_ANR) {
6166 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
6172 boolean useTombstonedForJavaTraces = false;
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.
6182 // This mode of operation will be removed in the near future.
6185 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6186 if (globalTracesPath.isEmpty()) {
6187 Slog.w(TAG, "dumpStackTraces: no trace path configured");
6191 tracesFile = new File(globalTracesPath);
6193 if (clearTraces && tracesFile.exists()) {
6194 tracesFile.delete();
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);
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);
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
6213 tracesFile = createAnrDumpFile(tracesDir);
6214 if (tracesFile == null) {
6218 useTombstonedForJavaTraces = true;
6221 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
6222 useTombstonedForJavaTraces);
6226 @GuardedBy("ActivityManagerService.class")
6227 private static SimpleDateFormat sAnrFileDateFormat;
6229 private static synchronized File createAnrDumpFile(File tracesDir) {
6230 if (sAnrFileDateFormat == null) {
6231 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
6234 final String formattedDate = sAnrFileDateFormat.format(new Date());
6235 final File anrFile = new File(tracesDir, "anr_" + formattedDate);
6238 if (anrFile.createNewFile()) {
6239 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
6242 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
6244 } catch (IOException ioe) {
6245 Slog.w(TAG, "Exception creating ANR dump file:", ioe);
6252 * Prune all trace files that are more than a day old.
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.
6258 private static void maybePruneOldTraces(File tracesDir) {
6259 final long now = System.currentTimeMillis();
6260 final File[] traceFiles = tracesDir.listFiles();
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);
6274 * Legacy code, do not use. Existing users will be deleted.
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
6283 private final String mTracesPath;
6284 private boolean mClosed;
6286 public DumpStackFileObserver(String tracesPath) {
6287 super(tracesPath, FileObserver.CLOSE_WRITE);
6288 mTracesPath = tracesPath;
6292 public synchronized void onEvent(int event, String path) {
6297 public long dumpWithTimeout(int pid, long timeout) {
6298 sendSignal(pid, SIGNAL_QUIT);
6299 final long start = SystemClock.elapsedRealtime();
6301 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
6302 synchronized (this) {
6304 wait(waitTime); // Wait for traces file to be closed.
6305 } catch (InterruptedException e) {
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) {
6318 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
6319 ". Attempting native stack collection.");
6321 final long nativeDumpTimeoutMs = Math.min(
6322 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
6324 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
6325 (int) (nativeDumpTimeoutMs / 1000));
6328 final long end = SystemClock.elapsedRealtime();
6331 return (end - start);
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
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));
6349 return SystemClock.elapsedRealtime() - timeStart;
6352 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6353 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6354 boolean useTombstonedForJavaTraces) {
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) {
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);
6368 // We must complete all stack dumps within 20 seconds.
6369 long remainingTime = 20 * 1000;
6371 if (observer != null) {
6372 observer.startWatching();
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);
6385 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6388 remainingTime -= timeTaken;
6389 if (remainingTime <= 0) {
6390 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6391 "); deadline exceeded.");
6396 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
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);
6407 final long start = SystemClock.elapsedRealtime();
6408 Debug.dumpNativeBacktraceToFileTimeout(
6409 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6410 final long timeTaken = SystemClock.elapsedRealtime() - start;
6412 remainingTime -= timeTaken;
6413 if (remainingTime <= 0) {
6414 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6415 "); deadline exceeded.");
6420 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
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);
6430 final long timeTaken;
6431 if (useTombstonedForJavaTraces) {
6432 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6434 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6437 remainingTime -= timeTaken;
6438 if (remainingTime <= 0) {
6439 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6440 "); deadline exceeded.");
6445 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6450 if (observer != null) {
6451 observer.stopWatching();
6456 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6457 if (true || Build.IS_USER) {
6460 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6461 if (tracesPath == null || tracesPath.length() == 0) {
6465 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6466 StrictMode.allowThreadDiskWrites();
6468 final File tracesFile = new File(tracesPath);
6469 final File tracesDir = tracesFile.getParentFile();
6470 final File tracesTmp = new File(tracesDir, "__tmp__");
6472 if (tracesFile.exists()) {
6474 tracesFile.renameTo(tracesTmp);
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"));
6481 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6482 sb.append(" since ");
6484 FileOutputStream fos = new FileOutputStream(tracesFile);
6485 fos.write(sb.toString().getBytes());
6487 fos.write("\n*** No application process!".getBytes());
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);
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 */);
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);
6511 curTracesFile.delete();
6514 lastTracesFile = curTracesFile;
6516 tracesFile.renameTo(curTracesFile);
6517 if (tracesTmp.exists()) {
6518 tracesTmp.renameTo(tracesFile);
6521 StrictMode.setThreadPolicy(oldPolicy);
6526 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6527 if (!mLaunchWarningShown) {
6528 mLaunchWarningShown = true;
6529 mUiHandler.post(new Runnable() {
6532 synchronized (ActivityManagerService.this) {
6533 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6535 mUiHandler.postDelayed(new Runnable() {
6538 synchronized (ActivityManagerService.this) {
6540 mLaunchWarningShown = false;
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);
6559 final ApplicationInfo appInfo;
6560 final boolean isInstantApp;
6562 long callingId = Binder.clearCallingIdentity();
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);
6573 ApplicationInfo applicationInfo = null;
6575 applicationInfo = pm.getApplicationInfo(packageName,
6576 MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6577 } catch (RemoteException e) {
6580 appInfo = applicationInfo;
6582 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
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);
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;
6601 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6602 && !canAccessInstantApps)) {
6603 Slog.w(TAG, "Invalid packageName: " + packageName);
6604 if (observer != null) {
6606 observer.onRemoveCompleted(packageName, false);
6607 } catch (RemoteException e) {
6608 Slog.i(TAG, "Observer no longer exists.");
6614 if (appInfo != null) {
6615 forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6616 mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6620 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6622 public void onRemoveCompleted(String packageName, boolean succeeded)
6623 throws RemoteException {
6624 if (appInfo != null) {
6625 synchronized (ActivityManagerService.this) {
6626 finishForceStopPackageLocked(packageName, appInfo.uid);
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);
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,
6640 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6641 null, null, null, null, false, false, resolvedUserId);
6644 if (observer != null) {
6645 observer.onRemoveCompleted(packageName, succeeded);
6651 // Clear application user data
6652 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
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.
6659 synchronized (this) {
6660 // Remove all permissions granted from/to this package
6661 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
6665 // Reset notification state
6666 INotificationManager inm = NotificationManager.getService();
6667 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6670 // Clear its scheduled jobs
6671 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6672 js.cancelJobsForUid(appInfo.uid, "clear data");
6674 // Clear its pending alarms
6675 AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6676 ami.removeAlarmsForUid(appInfo.uid);
6678 } catch (RemoteException e) {
6681 Binder.restoreCallingIdentity(callingId);
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;
6697 throw new SecurityException(msg);
6700 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6701 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6702 final int[] userIds = mUserController.expandUserId(userId);
6704 long callingId = Binder.clearCallingIdentity();
6706 IPackageManager pm = AppGlobals.getPackageManager();
6707 for (int targetUserId : userIds) {
6710 appId = UserHandle.getAppId(
6711 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6713 } catch (RemoteException e) {
6716 Slog.w(TAG, "Invalid packageName: " + packageName);
6719 synchronized (this) {
6720 killPackageProcessesLocked(packageName, appId, targetUserId,
6721 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6725 Binder.restoreCallingIdentity(callingId);
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;
6737 throw new SecurityException(msg);
6740 final long callingId = Binder.clearCallingIdentity();
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.
6756 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6763 final int N = procs.size();
6764 for (int i = 0; i < N; i++) {
6765 removeProcessLocked(procs.get(i), false, true, "kill all background");
6768 mAllowLowerMemLevel = true;
6770 updateOomAdjLocked();
6771 doLowMemReportIfNeededLocked(null);
6774 Binder.restoreCallingIdentity(callingId);
6779 * Kills all background processes, except those matching any of the
6780 * specified properties.
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
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;
6794 throw new SecurityException(msg);
6797 final long callingId = Binder.clearCallingIdentity();
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);
6809 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6810 && (maxProcState < 0 || app.setProcState > maxProcState)) {
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");
6823 Binder.restoreCallingIdentity(callingId);
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;
6836 throw new SecurityException(msg);
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();
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);
6857 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6859 } catch (RemoteException e) {
6862 Slog.w(TAG, "Invalid packageName: " + packageName);
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);
6872 if (mUserController.isUserRunning(user, 0)) {
6873 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6874 finishForceStopPackageLocked(packageName, pkgUid);
6879 Binder.restoreCallingIdentity(callingId);
6884 public void addPackageDependency(String packageName) {
6885 synchronized (this) {
6886 int callingPid = Binder.getCallingPid();
6887 if (callingPid == myPid()) {
6892 synchronized (mPidsSelfLocked) {
6893 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6896 if (proc.pkgDeps == null) {
6897 proc.pkgDeps = new ArraySet<String>(1);
6899 proc.pkgDeps.add(packageName);
6905 * The pkg name and app id have to be specified.
6908 public void killApplication(String pkg, int appId, int userId, String reason) {
6912 // Make sure the uid is valid.
6914 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
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);
6924 Bundle bundle = new Bundle();
6925 bundle.putString("pkg", pkg);
6926 bundle.putString("reason", reason);
6928 mHandler.sendMessage(msg);
6930 throw new SecurityException(callerUid + " cannot kill pkg: " +
6936 public void closeSystemDialogs(String reason) {
6937 enforceNotIsolatedCaller("closeSystemDialogs");
6939 final int pid = Binder.getCallingPid();
6940 final int uid = Binder.getCallingUid();
6941 final long origId = Binder.clearCallingIdentity();
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) {
6948 synchronized (mPidsSelfLocked) {
6949 proc = mPidsSelfLocked.get(pid);
6951 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6952 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6953 + " from background process " + proc);
6957 closeSystemDialogsLocked(reason);
6960 Binder.restoreCallingIdentity(origId);
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);
6972 mWindowManager.closeSystemDialogs(reason);
6974 mStackSupervisor.closeSystemDialogsLocked();
6976 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6977 OP_NONE, null, false, false,
6978 -1, SYSTEM_UID, UserHandle.USER_ALL);
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--) {
6988 synchronized (this) {
6989 synchronized (mPidsSelfLocked) {
6990 proc = mPidsSelfLocked.get(pids[i]);
6991 oomAdj = proc != null ? proc.setAdj : 0;
6994 infos[i] = new Debug.MemoryInfo();
6995 long startTime = SystemClock.currentThreadTimeMillis();
6996 Debug.getMemoryInfo(pids[i], infos[i]);
6997 long endTime = SystemClock.currentThreadTimeMillis();
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,
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--) {
7020 synchronized (this) {
7021 synchronized (mPidsSelfLocked) {
7022 proc = mPidsSelfLocked.get(pids[i]);
7023 oomAdj = proc != null ? proc.setAdj : 0;
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();
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);
7044 public void killApplicationProcess(String processName, int uid) {
7045 if (processName == null) {
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) {
7056 app.thread.scheduleSuicide();
7057 } catch (RemoteException e) {
7058 // If the other end already died, then our work here is done.
7061 Slog.w(TAG, "Process/uid not found attempting kill of "
7062 + processName + " / " + uid);
7066 throw new SecurityException(callerUid + " cannot kill app process: " +
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);
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);
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));
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<>();
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
7119 // Skip process if it doesn't meet our oom adj requirement.
7120 if (app.setAdj < minOomAdj) {
7124 // If no package is specified, we call all processes under the
7126 if (packageName == null) {
7127 if (userId != UserHandle.USER_ALL && app.userId != userId) {
7130 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
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.
7137 final boolean isDep = app.pkgDeps != null
7138 && app.pkgDeps.contains(packageName);
7139 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
7142 if (userId != UserHandle.USER_ALL && app.userId != userId) {
7145 if (!app.pkgList.containsKey(packageName) && !isDep) {
7150 // Process has passed all conditions, kill it!
7159 int N = procs.size();
7160 for (int i=0; i<N; i++) {
7161 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
7163 updateOomAdjLocked();
7167 private void cleanupDisabledPackageComponentsLocked(
7168 String packageName, int userId, boolean killProcess, String[] changedClasses) {
7170 Set<String> disabledClasses = null;
7171 boolean packageDisabled = false;
7172 IPackageManager pm = AppGlobals.getPackageManager();
7174 if (changedClasses == null) {
7175 // Nothing changed...
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];
7184 if (changedClass.equals(packageName)) {
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.
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;
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.
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);
7216 disabledClasses.add(changedClass);
7221 if (!packageDisabled && disabledClasses == null) {
7222 // Nothing to do here...
7226 // Clean-up disabled activities.
7227 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7228 packageName, disabledClasses, true, false, userId) && mBooted) {
7229 mStackSupervisor.resumeFocusedStackTopActivityLocked();
7230 mStackSupervisor.scheduleIdleLocked();
7233 // Clean-up disabled tasks
7234 mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
7236 // Clean-up disabled services.
7237 mServices.bringDownDisabledPackageServicesLocked(
7238 packageName, disabledClasses, userId, false, killProcess, true);
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);
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);
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);
7262 return didSomething;
7266 final boolean forceStopPackageLocked(String packageName, int appId,
7267 boolean callerWillRestart, boolean purgeCache, boolean doit,
7268 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
7271 if (userId == UserHandle.USER_ALL && packageName == null) {
7272 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
7275 if (appId < 0 && packageName != null) {
7277 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
7278 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
7279 } catch (RemoteException e) {
7284 if (packageName != null) {
7285 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
7286 + " user=" + userId + ": " + reason);
7288 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
7291 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
7294 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
7295 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
7296 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
7298 didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
7300 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7301 packageName, null, doit, evenPersistent, userId)) {
7305 didSomething = true;
7308 if (mServices.bringDownDisabledPackageServicesLocked(
7309 packageName, null, userId, evenPersistent, true, doit)) {
7313 didSomething = true;
7316 if (packageName == null) {
7317 // Remove all sticky broadcasts from this user.
7318 mStickyBroadcasts.remove(userId);
7321 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7322 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
7323 userId, providers)) {
7327 didSomething = true;
7329 for (i = providers.size() - 1; i >= 0; i--) {
7330 removeDyingProviderLocked(null, providers.get(i), true);
7333 // Remove transient permissions granted from/to this package/user
7334 removeUriPermissionsForPackageLocked(packageName, userId, false, false);
7337 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
7338 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7339 packageName, null, userId, doit);
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();
7357 PendingIntentRecord pir = wpir.get();
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.
7369 if (UserHandle.getAppId(pir.uid) != appId) {
7370 // Different app id, skip it.
7373 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7374 // Different user, skip it.
7377 if (!pir.key.packageName.equals(packageName)) {
7378 // Different package, skip it.
7385 didSomething = true;
7387 makeIntentSenderCanceledLocked(pir);
7388 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7389 pir.key.activity.pendingResults.remove(pir.ref);
7396 if (purgeCache && packageName != null) {
7397 AttributeCache ac = AttributeCache.instance();
7399 ac.removePackage(packageName);
7403 mStackSupervisor.resumeFocusedStackTopActivityLocked();
7404 mStackSupervisor.scheduleIdleLocked();
7408 return didSomething;
7411 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7412 return removeProcessNameLocked(name, uid, null);
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);
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);
7435 old.uidRecord = null;
7437 mIsolatedProcesses.remove(uid);
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);
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;
7461 uidRec.updateHasInternetPermission();
7462 mActiveUids.put(proc.uid, uidRec);
7463 EventLogTags.writeAmUidRunning(uidRec.uid);
7464 noteUidProcessState(uidRec.uid, uidRec.curProcState);
7466 proc.uidRecord = uidRec;
7468 // Reset render thread tid if it was already set, so new process can set it again.
7469 proc.renderThreadTid = 0;
7471 mProcessNames.put(proc.processName, proc.uid, proc);
7472 if (proc.isolated) {
7473 mIsolatedProcesses.put(proc.uid, proc);
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 + ")");
7485 ProcessRecord old = mProcessNames.get(name, uid);
7487 // This process is no longer active, so nothing to do.
7488 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7491 removeProcessNameLocked(name, uid);
7492 if (mHeavyWeightProcess == app) {
7493 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7494 mHeavyWeightProcess.userId, 0));
7495 mHeavyWeightProcess = null;
7497 boolean needRestart = false;
7498 if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7501 synchronized (mPidsSelfLocked) {
7502 mPidsSelfLocked.remove(pid);
7503 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7505 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7507 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7508 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7511 boolean willRestart = false;
7512 if (app.persistent && !app.isolated) {
7513 if (!callerWillRestart) {
7519 app.kill(reason, true);
7520 handleAppDiedLocked(app, willRestart, allowRestart);
7522 removeLruProcessLocked(app);
7523 addAppLocked(app.info, null, false, null /* ABI override */);
7526 mRemovedProcesses.add(app);
7533 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7534 cleanupAppInLaunchingProvidersLocked(app, true);
7535 removeProcessLocked(app, false, true, "timeout publishing content providers");
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);
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;
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);
7566 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
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() {
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
7584 if (isPendingBroadcastProcessLocked(pid)) {
7585 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7586 skipPendingBroadcastLocked(pid);
7589 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7594 private final boolean attachApplicationLocked(IApplicationThread thread,
7595 int pid, int callingUid, long startSeq) {
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.
7601 long startTime = SystemClock.uptimeMillis();
7602 if (pid != MY_PID && pid >= 0) {
7603 synchronized (mPidsSelfLocked) {
7604 app = mPidsSelfLocked.get(pid);
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;
7612 final String msg = "attachApplicationLocked process:" + processName
7613 + " startSeq:" + startSeq
7615 + " belongs to another existing app:" + app.processName
7616 + " startSeq:" + app.startSeq;
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);
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,
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);
7650 thread.scheduleExit();
7651 } catch (Exception e) {
7652 // Ignore exceptions.
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);
7664 // Tell the process all about itself.
7666 if (DEBUG_ALL) Slog.v(
7667 TAG, "Binding process pid " + pid + " to record " + app);
7669 final String processName = app.processName;
7671 AppDeathRecipient adr = new AppDeathRecipient(
7673 thread.asBinder().linkToDeath(adr, 0);
7674 app.deathRecipient = adr;
7675 } catch (RemoteException e) {
7676 app.resetPackageList(mProcessStats);
7677 startProcessLocked(app, "link fail", processName);
7681 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
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;
7691 app.killedByAm = false;
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);
7700 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7702 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7703 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7705 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7706 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7708 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7711 checkTime(startTime, "attachApplicationLocked: before bindApplication");
7714 Slog.i(TAG, "Launching preboot mode app: " + app);
7717 if (DEBUG_ALL) Slog.v(
7718 TAG, "New app record " + app
7719 + " thread=" + thread.asBinder() + " pid=" + pid);
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;
7733 boolean enableTrackAllocation = false;
7734 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7735 enableTrackAllocation = true;
7736 mTrackAllocationApp = null;
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));
7748 if (app.instr != null) {
7749 notifyPackageUse(app.instr.mClass.getPackageName(),
7750 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
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);
7757 ProfilerInfo profilerInfo = null;
7758 String preBindAgent = null;
7759 if (mProfileApp != null && mProfileApp.equals(processName)) {
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;
7771 } else if (app.instr != null && app.instr.mProfileFile != null) {
7772 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
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);
7790 if (profilerInfo != null && profilerInfo.profileFd != null) {
7791 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7792 if (TextUtils.equals(mProfileApp, processName) && mProfilerInfo != null) {
7793 clearProfilerLocked();
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;
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)) {
7818 aInstr.mRunningProcesses.add(app);
7821 for (String proc : aInstr.mTargetProcesses) {
7822 if (proc.equals(app.processName)) {
7824 aInstr.mRunningProcesses.add(app);
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);
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);
7846 isAutofillCompatEnabled = afm.isCompatibilityModeRequested(
7847 app.info.packageName, app.info.versionCode, app.userId);
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,
7860 profilerInfo, app.instr.mArguments,
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);
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);
7879 if (profilerInfo != null) {
7880 profilerInfo.closeFd();
7881 profilerInfo = null;
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);
7893 app.resetPackageList(mProcessStats);
7894 app.unlinkDeathRecipient();
7895 startProcessLocked(app, "bind fail", processName);
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);
7905 boolean badApp = false;
7906 boolean didSomething = false;
7908 // See if the top visible activity is waiting to run in this process...
7911 if (mStackSupervisor.attachApplicationLocked(app)) {
7912 didSomething = true;
7914 } catch (Exception e) {
7915 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7920 // Find any services that should be running in this process...
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);
7931 // Check if a next-broadcast receiver is in this process...
7932 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
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);
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);
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);
7960 app.kill("error during init", true);
7961 handleAppDiedLocked(app, false, true);
7965 if (!didSomething) {
7966 updateOomAdjLocked();
7967 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
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);
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) {
7991 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7992 false /* processPausingActivities */, config);
7993 if (stopProfiling) {
7994 if ((mProfileProc == r.app) && mProfilerInfo != null) {
7995 clearProfilerLocked();
8000 Binder.restoreCallingIdentity(origId);
8003 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
8004 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
8005 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
8008 void enableScreenAfterBoot() {
8009 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
8010 SystemClock.uptimeMillis());
8011 mWindowManager.enableScreenAfterBoot();
8013 synchronized (this) {
8014 updateEventDispatchingLocked();
8019 public void showBootMessage(final CharSequence msg, final boolean always) {
8020 if (Binder.getCallingUid() != myUid()) {
8021 throw new SecurityException();
8023 mWindowManager.showBootMessage(msg, always);
8027 public void keyguardGoingAway(int flags) {
8028 enforceNotIsolatedCaller("keyguardGoingAway");
8029 final long token = Binder.clearCallingIdentity();
8031 synchronized (this) {
8032 mKeyguardController.keyguardGoingAway(flags);
8035 Binder.restoreCallingIdentity(token);
8040 * @return whther the keyguard is currently locked.
8042 boolean isKeyguardLocked() {
8043 return mKeyguardController.isKeyguardLocked();
8046 final void finishBooting() {
8047 synchronized (this) {
8048 if (!mBootAnimationComplete) {
8049 mCallFinishBooting = true;
8052 mCallFinishBooting = false;
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)) {
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() +")");
8066 completedIsas.add(instructionSet);
8070 IntentFilter pkgFilter = new IntentFilter();
8071 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
8072 pkgFilter.addDataScheme("package");
8073 mContext.registerReceiver(new BroadcastReceiver() {
8075 public void onReceive(Context context, Intent intent) {
8076 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
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);
8091 IntentFilter dumpheapFilter = new IntentFilter();
8092 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
8093 mContext.registerReceiver(new BroadcastReceiver() {
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);
8099 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
8104 // Let system services know.
8105 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
8107 synchronized (this) {
8108 // Ensure that any processes we had put on hold are now started
8110 final int NP = mProcessesOnHold.size();
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: "
8117 startProcessLocked(procs.get(ip), "on-hold", null);
8120 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
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");
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");
8134 mUserController.sendBootCompleted(
8135 new IIntentReceiver.Stub() {
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);
8145 mUserController.scheduleStartProfiles();
8150 public void bootAnimationComplete() {
8151 final boolean callFinishBooting;
8152 synchronized (this) {
8153 callFinishBooting = mCallFinishBooting;
8154 mBootAnimationComplete = true;
8156 if (callFinishBooting) {
8157 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8159 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8163 final void ensureBootCompleted() {
8165 boolean enableScreen;
8166 synchronized (this) {
8169 enableScreen = !mBooted;
8174 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8176 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8180 enableScreenAfterBoot();
8185 public final void activityResumed(IBinder token) {
8186 final long origId = Binder.clearCallingIdentity();
8187 synchronized(this) {
8188 ActivityRecord.activityResumedLocked(token);
8189 mWindowManager.notifyAppResumedFinished(token);
8191 Binder.restoreCallingIdentity(origId);
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);
8203 Binder.restoreCallingIdentity(origId);
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);
8211 // Refuse possible leaked file descriptors
8212 if (icicle != null && icicle.hasFileDescriptors()) {
8213 throw new IllegalArgumentException("File descriptors passed in Bundle");
8216 final long origId = Binder.clearCallingIdentity();
8218 synchronized (this) {
8219 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8221 r.activityStoppedLocked(icicle, persistentState, description);
8227 Binder.restoreCallingIdentity(origId);
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");
8242 public final void activityRelaunched(IBinder token) {
8243 final long origId = Binder.clearCallingIdentity();
8244 synchronized (this) {
8245 mStackSupervisor.activityRelaunchedLocked(token);
8247 Binder.restoreCallingIdentity(origId);
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);
8261 record.setSizeConfigurations(horizontalSizeConfiguration,
8262 verticalSizeConfigurations, smallestSizeConfigurations);
8267 public final void notifyLaunchTaskBehindComplete(IBinder token) {
8268 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
8272 public final void notifyEnterAnimationComplete(IBinder token) {
8273 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
8277 public String getCallingPackage(IBinder token) {
8278 synchronized (this) {
8279 ActivityRecord r = getCallingRecordLocked(token);
8280 return r != null ? r.info.packageName : null;
8285 public ComponentName getCallingActivity(IBinder token) {
8286 synchronized (this) {
8287 ActivityRecord r = getCallingRecordLocked(token);
8288 return r != null ? r.intent.getComponent() : null;
8292 private ActivityRecord getCallingRecordLocked(IBinder token) {
8293 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8301 public ComponentName getActivityClassForToken(IBinder token) {
8302 synchronized(this) {
8303 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8307 return r.intent.getComponent();
8312 public String getPackageForToken(IBinder token) {
8313 synchronized(this) {
8314 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8318 return r.packageName;
8323 public boolean isRootVoiceInteraction(IBinder token) {
8324 synchronized(this) {
8325 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8329 return r.rootVoiceInteraction;
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");
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");
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");
8355 intents[i] = new Intent(intent);
8358 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
8359 throw new IllegalArgumentException(
8360 "Intent array length does not match resolvedTypes length");
8363 if (bOptions != null) {
8364 if (bOptions.hasFileDescriptors()) {
8365 throw new IllegalArgumentException("File descriptors passed in options");
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;
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;
8392 throw new SecurityException(msg);
8396 return getIntentSenderLocked(type, packageName, callingUid, userId,
8397 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
8399 } catch (RemoteException e) {
8400 throw new SecurityException(e);
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,
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");
8417 if (activity.finishing) {
8418 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
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);
8430 Bundle.setDefusable(bOptions, true);
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);
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;
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);
8451 if (intents != null) {
8452 intents[intents.length-1] = rec.key.requestIntent;
8453 rec.key.allIntents = intents;
8454 rec.key.allResolvedTypes = resolvedTypes;
8456 rec.key.allIntents = null;
8457 rec.key.allResolvedTypes = null;
8462 makeIntentSenderCanceledLocked(rec);
8463 mIntentSenderRecords.remove(key);
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>>();
8475 activity.pendingResults.add(rec.ref);
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);
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);
8498 target.send(code, intent, resolvedType, whitelistToken, null,
8499 requiredPermission, options);
8500 } catch (RemoteException e) {
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) {
8508 finishedReceiver.performReceive(intent, 0,
8509 null, null, false, false, UserHandle.getCallingUserId());
8510 } catch (RemoteException e) {
8518 public void cancelIntentSender(IIntentSender sender) {
8519 if (!(sender instanceof PendingIntentRecord)) {
8522 synchronized(this) {
8523 PendingIntentRecord rec = (PendingIntentRecord)sender;
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;
8534 throw new SecurityException(msg);
8536 } catch (RemoteException e) {
8537 throw new SecurityException(e);
8539 cancelIntentSenderLocked(rec, true);
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);
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();
8560 public String getPackageForIntentSender(IIntentSender pendingResult) {
8561 if (!(pendingResult instanceof PendingIntentRecord)) {
8565 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8566 return res.key.packageName;
8567 } catch (ClassCastException e) {
8573 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8574 if (!(sender instanceof PendingIntentRecord)) {
8577 boolean isCancelled;
8578 synchronized(this) {
8579 PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
8580 isCancelled = pendingIntent.canceled;
8582 pendingIntent.registerCancelListenerLocked(receiver);
8587 receiver.send(Activity.RESULT_CANCELED, null);
8588 } catch (RemoteException e) {
8594 public void unregisterIntentSenderCancelListener(IIntentSender sender,
8595 IResultReceiver receiver) {
8596 if (!(sender instanceof PendingIntentRecord)) {
8599 synchronized(this) {
8600 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8605 public int getUidForIntentSender(IIntentSender sender) {
8606 if (sender instanceof PendingIntentRecord) {
8608 PendingIntentRecord res = (PendingIntentRecord)sender;
8610 } catch (ClassCastException e) {
8617 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8618 if (!(pendingResult instanceof PendingIntentRecord)) {
8622 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8623 if (res.key.allIntents == null) {
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) {
8633 } catch (ClassCastException e) {
8639 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8640 if (!(pendingResult instanceof PendingIntentRecord)) {
8644 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8645 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8649 } catch (ClassCastException e) {
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;
8664 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8665 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8666 "getIntentForIntentSender()");
8667 if (!(pendingResult instanceof PendingIntentRecord)) {
8671 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8672 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8673 } catch (ClassCastException e) {
8679 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8680 if (!(pendingResult instanceof PendingIntentRecord)) {
8684 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8685 synchronized (this) {
8686 return getTagForIntentSenderLocked(res, prefix);
8688 } catch (ClassCastException e) {
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))) {
8700 res.lastTagPrefix = prefix;
8701 final StringBuilder sb = new StringBuilder(128);
8702 if (prefix != null) {
8705 if (intent.getAction() != null) {
8706 sb.append(intent.getAction());
8707 } else if (intent.getComponent() != null) {
8708 intent.getComponent().appendShortString(sb);
8712 return res.lastTag = sb.toString();
8718 public void setProcessLimit(int max) {
8719 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8720 "setProcessLimit()");
8721 synchronized (this) {
8722 mConstants.setOverrideMaxCachedProcesses(max);
8728 public int getProcessLimit() {
8729 synchronized (this) {
8730 return mConstants.getOverrideMaxCachedProcesses();
8734 void importanceTokenDied(ImportanceToken token) {
8735 synchronized (ActivityManagerService.this) {
8736 synchronized (mPidsSelfLocked) {
8738 = mImportantProcesses.get(token.pid);
8742 mImportantProcesses.remove(token.pid);
8743 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8747 pr.forcingToImportant = null;
8748 updateProcessForegroundLocked(pr, false, false);
8750 updateOomAdjLocked();
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;
8761 synchronized (mPidsSelfLocked) {
8762 ProcessRecord pr = mPidsSelfLocked.get(pid);
8763 if (pr == null && isForeground) {
8764 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8767 ImportanceToken oldToken = mImportantProcesses.get(pid);
8768 if (oldToken != null) {
8769 oldToken.token.unlinkToDeath(oldToken, 0);
8770 mImportantProcesses.remove(pid);
8772 pr.forcingToImportant = null;
8776 if (isForeground && token != null) {
8777 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8779 public void binderDied() {
8780 importanceTokenDied(this);
8784 token.linkToDeath(newToken, 0);
8785 mImportantProcesses.put(pid, newToken);
8786 pr.forcingToImportant = newToken;
8788 } catch (RemoteException e) {
8789 // If the process died while doing this, we will later
8790 // do the cleanup with the process death link.
8796 updateOomAdjLocked();
8802 public boolean isAppForeground(int uid) {
8803 int callerUid = Binder.getCallingUid();
8804 if (UserHandle.isCore(callerUid) || callerUid == uid) {
8805 return isAppForegroundInternal(uid);
8810 private boolean isAppForegroundInternal(int uid) {
8811 synchronized (this) {
8812 UidRecord uidRec = mActiveUids.get(uid);
8813 if (uidRec == null || uidRec.idle) {
8816 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
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);
8828 int getUidStateLocked(int uid) {
8829 UidRecord uidRec = mActiveUids.get(uid);
8830 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8834 public boolean isInMultiWindowMode(IBinder token) {
8835 final long origId = Binder.clearCallingIdentity();
8837 synchronized(this) {
8838 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8842 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8843 return r.inMultiWindowMode();
8846 Binder.restoreCallingIdentity(origId);
8851 public boolean isInPictureInPictureMode(IBinder token) {
8852 final long origId = Binder.clearCallingIdentity();
8854 synchronized(this) {
8855 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8858 Binder.restoreCallingIdentity(origId);
8862 private boolean isInPictureInPictureMode(ActivityRecord r) {
8863 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8864 || r.getStack().isInStackLocked(r) == null) {
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();
8876 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8877 final long origId = Binder.clearCallingIdentity();
8879 synchronized(this) {
8880 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8881 "enterPictureInPictureMode", token, params);
8883 // If the activity is already in picture in picture mode, then just return early
8884 if (isInPictureInPictureMode(r)) {
8888 // Activity supports picture-in-picture, now check that we can enter PiP at this
8890 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8891 false /* beforeStopping */)) {
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);
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).
8917 dismissKeyguard(token, new KeyguardDismissCallback() {
8919 public void onDismissSucceeded() throws RemoteException {
8920 mHandler.post(enterPipRunnable);
8922 }, null /* message */);
8923 } catch (RemoteException e) {
8927 // Enter picture in picture immediately otherwise
8928 enterPipRunnable.run();
8933 Binder.restoreCallingIdentity(origId);
8938 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8939 final long origId = Binder.clearCallingIdentity();
8941 synchronized(this) {
8942 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8943 "setPictureInPictureParams", token, params);
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());
8958 logPictureInPictureArgs(params);
8961 Binder.restoreCallingIdentity(origId);
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
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());
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);
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.
8988 * @return the activity record for the given {@param token} if all the checks pass.
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.");
8997 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8999 throw new IllegalStateException(caller
9000 + ": Can't find activity for token=" + token);
9003 if (!r.supportsPictureInPicture()) {
9004 throw new IllegalStateException(caller
9005 + ": Current activity does not support picture-in-picture.");
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));
9020 // Truncate the number of actions if necessary
9021 params.truncateActions(getMaxNumPictureInPictureActions(token));
9026 // =========================================================
9028 // =========================================================
9030 static class ProcessInfoService extends IProcessInfoService.Stub {
9031 final ActivityManagerService mActivityManagerService;
9032 ProcessInfoService(ActivityManagerService activityManagerService) {
9033 mActivityManagerService = activityManagerService;
9037 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
9038 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
9039 /*in*/ pids, /*out*/ states, null);
9043 public void getProcessStatesAndOomScoresFromPids(
9044 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
9045 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
9046 /*in*/ pids, /*out*/ states, /*out*/ scores);
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.
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()");
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!");
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 :
9079 if (scores != null) {
9080 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
9086 // =========================================================
9088 // =========================================================
9090 static class PermissionController extends IPermissionController.Stub {
9091 ActivityManagerService mActivityManagerService;
9092 PermissionController(ActivityManagerService activityManagerService) {
9093 mActivityManagerService = activityManagerService;
9097 public boolean checkPermission(String permission, int pid, int uid) {
9098 return mActivityManagerService.checkPermission(permission, pid,
9099 uid) == PackageManager.PERMISSION_GRANTED;
9103 public int noteOp(String op, int uid, String packageName) {
9104 return mActivityManagerService.mAppOpsService
9105 .noteOperation(AppOpsManager.strOpToOp(op), uid, packageName);
9109 public String[] getPackagesForUid(int uid) {
9110 return mActivityManagerService.mContext.getPackageManager()
9111 .getPackagesForUid(uid);
9115 public boolean isRuntimePermission(String permission) {
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);
9128 public int getPackageUid(String packageName, int flags) {
9130 return mActivityManagerService.mContext.getPackageManager()
9131 .getPackageUid(packageName, flags);
9132 } catch (NameNotFoundException nnfe) {
9138 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
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);
9147 public Object getAMSLock() {
9148 return ActivityManagerService.this;
9152 int checkComponentPermission(String permission, int pid, int uid,
9153 int owningUid, boolean exported) {
9154 if (pid == MY_PID) {
9155 return PackageManager.PERMISSION_GRANTED;
9157 return ActivityManager.checkComponentPermission(permission, uid,
9158 owningUid, exported);
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.)
9168 * This can be called with or without the global lock held.
9171 public int checkPermission(String permission, int pid, int uid) {
9172 if (permission == null) {
9173 return PackageManager.PERMISSION_DENIED;
9175 return checkComponentPermission(permission, pid, uid, -1, true);
9179 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
9180 if (permission == null) {
9181 return PackageManager.PERMISSION_DENIED;
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;
9195 return checkComponentPermission(permission, pid, uid, -1, true);
9199 * Binder IPC calls go through the public entry point.
9200 * This can be called with or without the global lock held.
9202 int checkCallingPermission(String permission) {
9203 return checkPermission(permission,
9204 Binder.getCallingPid(),
9205 UserHandle.getAppId(Binder.getCallingUid()));
9209 * This can be called with or without the global lock held.
9211 void enforceCallingPermission(String permission, String func) {
9212 if (checkCallingPermission(permission)
9213 == PackageManager.PERMISSION_GRANTED) {
9217 String msg = "Permission Denial: " + func + " from pid="
9218 + Binder.getCallingPid()
9219 + ", uid=" + Binder.getCallingUid()
9220 + " requires " + permission;
9222 throw new SecurityException(msg);
9226 * This can be called with or without the global lock held.
9228 void enforcePermission(String permission, int pid, int uid, String func) {
9229 if (checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) {
9233 String msg = "Permission Denial: " + func + " from pid=" + pid + ", uid=" + uid
9234 + " requires " + permission;
9236 throw new SecurityException(msg);
9240 * This can be called with or without the global lock held.
9242 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
9243 if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
9244 enforceCallingPermission(permission, func);
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}.
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) {
9263 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
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) {
9270 } else if (!pi.exported) {
9274 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
9275 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
9277 // check if target holds top-level <provider> permissions
9278 if (!readMet && pi.readPermission != null && considerUidPermissions
9279 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
9282 if (!writeMet && pi.writePermission != null && considerUidPermissions
9283 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
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;
9292 // check if target holds any <path-permission> that match uri
9293 final PathPermission[] pps = pi.pathPermissions;
9295 final String path = grantUri.uri.getPath();
9297 while (i > 0 && (!readMet || !writeMet)) {
9299 PathPermission pp = pps[i];
9300 if (pp.match(path)) {
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) {
9312 allowDefaultRead = false;
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) {
9327 allowDefaultWrite = false;
9335 // grant unprotected <provider> read/write, if not blocked by
9336 // <path-permission> above
9337 if (allowDefaultRead) readMet = true;
9338 if (allowDefaultWrite) writeMet = true;
9340 } catch (RemoteException e) {
9344 return readMet && writeMet;
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;
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");
9361 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9363 // ...and legacy apps get an AppOp check
9364 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
9366 if (DEBUG_BACKGROUND_CHECK) {
9367 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + 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");
9379 return ActivityManager.APP_START_MODE_DELAYED;
9381 return ActivityManager.APP_START_MODE_NORMAL;
9382 case AppOpsManager.MODE_IGNORED:
9383 return ActivityManager.APP_START_MODE_DELAYED;
9385 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
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) {
9394 if (mPackageManagerInt.isPackagePersistent(packageName)) {
9395 if (DEBUG_BACKGROUND_CHECK) {
9396 Slog.i(TAG, "App " + uid + "/" + packageName
9397 + " is persistent; not restricted in background");
9399 return ActivityManager.APP_START_MODE_NORMAL;
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");
9408 return ActivityManager.APP_START_MODE_NORMAL;
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");
9417 return ActivityManager.APP_START_MODE_NORMAL;
9420 // None of the service-policy criteria apply, so we apply the common criteria
9421 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
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) {
9432 if (uidRec == null) {
9433 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
9434 UserHandle.getUserId(uid), packageName);
9436 ephemeral = uidRec.ephemeral;
9440 // We are hard-core about ephemeral apps not running in the background.
9441 return ActivityManager.APP_START_MODE_DISABLED;
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;
9450 final int startMode = (alwaysRestrict)
9451 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
9452 : appServicesRestrictedInBackgroundLocked(uid, packageName,
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));
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) {
9466 synchronized (mPidsSelfLocked) {
9467 proc = mPidsSelfLocked.get(callingPid);
9470 !ActivityManager.isProcStateBackground(proc.curProcState)) {
9471 // Whoever is instigating this is in the foreground, so we will allow it
9473 return ActivityManager.APP_START_MODE_NORMAL;
9480 return ActivityManager.APP_START_MODE_NORMAL;
9484 * @return whether a UID is in the system, user or temp doze whitelist.
9486 boolean isOnDeviceIdleWhitelistLocked(int uid, boolean allowExceptIdleToo) {
9487 final int appId = UserHandle.getAppId(uid);
9489 final int[] whitelist = allowExceptIdleToo
9490 ? mDeviceIdleExceptIdleWhitelist
9491 : mDeviceIdleWhitelist;
9493 return Arrays.binarySearch(whitelist, appId) >= 0
9494 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9495 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9498 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9499 ProviderInfo pi = null;
9500 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9505 pi = AppGlobals.getPackageManager().resolveContentProvider(
9506 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9508 } catch (RemoteException ex) {
9514 void grantEphemeralAccessLocked(int userId, Intent intent,
9515 int targetAppId, int ephemeralAppId) {
9516 getPackageManagerInternalLocked().
9517 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
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);
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);
9538 UriPermission perm = targetUris.get(grantUri);
9540 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9541 targetUris.put(grantUri, perm);
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;
9554 // Root gets to do everything.
9559 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9560 if (perms == null) return false;
9562 // First look for exact match
9563 final UriPermission exactPerm = perms.get(grantUri);
9564 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
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) {
9582 * @param uri This uri must NOT contain an embedded userId.
9583 * @param userId The userId in which the uri is to be resolved.
9586 public int checkUriPermission(Uri uri, int pid, int uid,
9587 final int modeFlags, int userId, IBinder callerToken) {
9588 enforceNotIsolatedCaller("checkUriPermission");
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;
9598 // Our own process gets to do everything.
9599 if (pid == MY_PID) {
9600 return PackageManager.PERMISSION_GRANTED;
9602 synchronized (this) {
9603 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9604 ? PackageManager.PERMISSION_GRANTED
9605 : PackageManager.PERMISSION_DENIED;
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.
9619 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9620 final int modeFlags, int lastTargetUid) {
9621 if (!Intent.isAccessUriMode(modeFlags)) {
9625 if (targetPkg != null) {
9626 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9627 "Checking grant " + targetPkg + " permission to " + grantUri);
9630 final IPackageManager pm = AppGlobals.getPackageManager();
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);
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
9649 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9650 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9655 final String authority = grantUri.uri.getAuthority();
9656 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9657 MATCH_DEBUG_TRIAGED_MISSING);
9659 Slog.w(TAG, "No content provider found for permission check: " +
9660 grantUri.uri.toSafeString());
9664 int targetUid = lastTargetUid;
9665 if (targetUid < 0 && targetPkg != null) {
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);
9674 } catch (RemoteException ex) {
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;
9687 // Otherwise, we can return "-1" to indicate that no grant data
9688 // structures need to be created
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;
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) {
9708 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9709 if (pi.writePermission != null) {
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) {
9723 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9724 if (pi.pathPermissions[i].getWritePermission() != null) {
9733 return allowedResult;
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.
9743 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9744 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9745 modeFlags, false /*without considering the uid permissions*/);
9747 // Second... is the provider allowing granting of URI permissions?
9748 if (!specialCrossUserGrant) {
9749 if (!pi.grantUriPermissions) {
9750 throw new SecurityException("Provider " + pi.packageName
9752 + " does not allow granting of Uri permissions (uri "
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())) {
9766 throw new SecurityException("Provider " + pi.packageName
9768 + " does not allow granting of permission to path of Uri "
9774 // Third... does the caller itself have permission to access
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");
9785 throw new SecurityException(
9786 "UID " + callingUid + " does not have permission to " + grantUri);
9794 * @param uri This uri must NOT contain an embedded userId.
9795 * @param userId The userId in which the uri is to be resolved.
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);
9808 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9809 final int modeFlags, UriPermissionOwner owner) {
9810 if (!Intent.isAccessUriMode(modeFlags)) {
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
9818 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9819 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9821 final String authority = grantUri.uri.getAuthority();
9822 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9823 MATCH_DEBUG_TRIAGED_MISSING);
9825 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9829 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9830 grantUri.prefix = true;
9832 final UriPermission perm = findOrCreateUriPermissionLocked(
9833 pi.packageName, targetPkg, targetUid, grantUri);
9834 perm.grantModes(modeFlags, owner);
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");
9844 final IPackageManager pm = AppGlobals.getPackageManager();
9846 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9847 } catch (RemoteException ex) {
9851 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9853 if (targetUid < 0) {
9857 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9861 static class NeededUriGrants extends ArrayList<GrantUri> {
9862 final String targetPkg;
9863 final int targetUid;
9866 NeededUriGrants(String targetPkg, int targetUid, int flags) {
9867 this.targetPkg = targetPkg;
9868 this.targetUid = targetUid;
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);
9878 final int N = this.size();
9879 for (int i=0; i<N; i++) {
9880 this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9887 * Like checkGrantUriPermissionLocked, but takes an Intent.
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));
9898 if (targetPkg == null) {
9899 throw new NullPointerException("targetPkg");
9902 if (intent == null) {
9905 Uri data = intent.getData();
9906 ClipData clip = intent.getClipData();
9907 if (data == null && clip == null) {
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);
9915 final IPackageManager pm = AppGlobals.getPackageManager();
9917 if (needed != null) {
9918 targetUid = needed.targetUid;
9921 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9923 } catch (RemoteException ex) {
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);
9934 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9935 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9937 if (targetUid > 0) {
9938 if (needed == null) {
9939 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9941 needed.add(grantUri);
9945 for (int i=0; i<clip.getItemCount(); i++) {
9946 Uri uri = clip.getItemAt(i).getUri();
9948 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9949 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9951 if (targetUid > 0) {
9952 if (needed == null) {
9953 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9955 needed.add(grantUri);
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) {
9974 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
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);
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) {
9997 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
10001 * @param uri This uri must NOT contain an embedded userId.
10002 * @param userId The userId in which the uri is to be resolved.
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);
10012 throw new SecurityException("Unable to find app for caller "
10014 + " when granting permission to uri " + grantUri);
10016 if (targetPkg == null) {
10017 throw new IllegalArgumentException("null target");
10019 if (grantUri == null) {
10020 throw new IllegalArgumentException("null uri");
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);
10028 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
10029 UserHandle.getUserId(r.uid));
10034 void removeUriPermissionIfNeededLocked(UriPermission perm) {
10035 if (perm.modeFlags == 0) {
10036 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10038 if (perms != null) {
10039 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10040 "Removing " + perm.targetUid + " permission to " + perm.uri);
10042 perms.remove(perm.uri);
10043 if (perms.isEmpty()) {
10044 mGrantedUriPermissions.remove(perm.targetUid);
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);
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);
10061 Slog.w(TAG, "No content provider found for permission revoke: "
10062 + grantUri.toSafeString());
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)) {
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) {
10090 if (perms.isEmpty()) {
10091 mGrantedUriPermissions.remove(callingUid);
10093 if (persistChanged) {
10094 schedulePersistUriGrants();
10100 boolean persistChanged = false;
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);
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)) {
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) {
10125 if (perms.isEmpty()) {
10126 mGrantedUriPermissions.removeAt(i);
10130 if (persistChanged) {
10131 schedulePersistUriGrants();
10136 * @param uri This uri must NOT contain an embedded userId.
10137 * @param userId The userId in which the uri is to be resolved.
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);
10146 throw new SecurityException("Unable to find app for caller "
10148 + " when revoking permission to uri " + uri);
10151 Slog.w(TAG, "revokeUriPermission: null uri");
10155 if (!Intent.isAccessUriMode(modeFlags)) {
10159 final String authority = uri.getAuthority();
10160 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
10161 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
10163 Slog.w(TAG, "No content provider found for permission revoke: "
10164 + uri.toSafeString());
10168 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
10174 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
10177 * @param packageName Package name to match, or {@code null} to apply to all
10179 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
10181 * @param persistable If persistable grants should be removed.
10182 * @param targetOnly When {@code true}, only remove permissions where the app is the target,
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");
10192 boolean persistChanged = false;
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);
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();
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;
10214 persistChanged |= perm.revokeModes(persistable
10215 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
10217 // Only remove when no modes remain; any persisted grants
10218 // will keep this alive.
10219 if (perm.modeFlags == 0) {
10225 if (perms.isEmpty()) {
10226 mGrantedUriPermissions.remove(targetUid);
10233 if (persistChanged) {
10234 schedulePersistUriGrants();
10239 public IBinder newUriPermissionOwner(String name) {
10240 enforceNotIsolatedCaller("newUriPermissionOwner");
10241 synchronized(this) {
10242 UriPermissionOwner owner = new UriPermissionOwner(this, name);
10243 return owner.getExternalTokenLocked();
10248 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
10249 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
10250 synchronized(this) {
10251 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10253 throw new IllegalArgumentException("Activity does not exist; token="
10256 return r.getUriPermissionsLocked().getExternalTokenLocked();
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.
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);
10275 if (fromUid != Binder.getCallingUid()) {
10276 if (Binder.getCallingUid() != myUid()) {
10277 // Only system code can grant URI permissions on behalf
10279 throw new SecurityException("nice try");
10282 if (targetPkg == null) {
10283 throw new IllegalArgumentException("null target");
10286 throw new IllegalArgumentException("null uri");
10289 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
10290 modeFlags, owner, targetUserId);
10295 * @param uri This uri must NOT contain an embedded userId.
10296 * @param userId The userId in which the uri is to be resolved.
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);
10307 owner.removeUriPermissionsLocked(mode);
10309 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
10310 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
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);
10322 private void writeGrantedUriPermissions() {
10323 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
10325 final long startTime = SystemClock.uptimeMillis();
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());
10341 FileOutputStream fos = null;
10343 fos = mGrantFile.startWrite(startTime);
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);
10361 out.endTag(null, TAG_URI_GRANTS);
10364 mGrantFile.finishWrite(fos);
10365 } catch (IOException e) {
10367 mGrantFile.failWrite(fos);
10373 private void readGrantedUriPermissionsLocked() {
10374 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
10376 final long now = System.currentTimeMillis();
10378 FileInputStream fis = null;
10380 fis = mGrantFile.openRead();
10381 final XmlPullParser in = Xml.newPullParser();
10382 in.setInput(fis, StandardCharsets.UTF_8.name());
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;
10398 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
10399 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
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);
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;
10417 targetUid = AppGlobals.getPackageManager().getPackageUid(
10418 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
10419 } catch (RemoteException e) {
10421 if (targetUid != -1) {
10422 final UriPermission perm = findOrCreateUriPermissionLocked(
10423 sourcePkg, targetPkg, targetUid,
10424 new GrantUri(sourceUserId, uri, prefix));
10425 perm.initPersistedModes(modeFlags, createdTime);
10428 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
10429 + " but instead found " + pi);
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);
10441 IoUtils.closeQuietly(fis);
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
10449 * @param userId The userId in which the uri is to be resolved.
10452 public void takePersistableUriPermission(Uri uri, final int modeFlags,
10453 @Nullable String toPackage, int userId) {
10455 if (toPackage != null) {
10456 enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10457 "takePersistableUriPermission");
10458 uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10460 enforceNotIsolatedCaller("takePersistableUriPermission");
10461 uid = Binder.getCallingUid();
10464 Preconditions.checkFlagsArgument(modeFlags,
10465 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10467 synchronized (this) {
10468 boolean persistChanged = false;
10469 GrantUri grantUri = new GrantUri(userId, uri, false);
10471 UriPermission exactPerm = findUriPermissionLocked(uid, grantUri);
10472 UriPermission prefixPerm = findUriPermissionLocked(uid,
10473 new GrantUri(userId, uri, true));
10475 final boolean exactValid = (exactPerm != null)
10476 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
10477 final boolean prefixValid = (prefixPerm != null)
10478 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
10480 if (!(exactValid || prefixValid)) {
10481 throw new SecurityException("No persistable permission grants found for UID "
10482 + uid + " and Uri " + grantUri.toSafeString());
10486 persistChanged |= exactPerm.takePersistableModes(modeFlags);
10489 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
10492 persistChanged |= maybePrunePersistedUriGrantsLocked(uid);
10494 if (persistChanged) {
10495 schedulePersistUriGrants();
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.
10507 public void releasePersistableUriPermission(Uri uri, final int modeFlags,
10508 @Nullable String toPackage, int userId) {
10511 if (toPackage != null) {
10512 enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10513 "releasePersistableUriPermission");
10514 uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10516 enforceNotIsolatedCaller("releasePersistableUriPermission");
10517 uid = Binder.getCallingUid();
10520 Preconditions.checkFlagsArgument(modeFlags,
10521 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10523 synchronized (this) {
10524 boolean persistChanged = false;
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());
10535 if (exactPerm != null) {
10536 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10537 removeUriPermissionIfNeededLocked(exactPerm);
10539 if (prefixPerm != null) {
10540 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10541 removeUriPermissionIfNeededLocked(prefixPerm);
10544 if (persistChanged) {
10545 schedulePersistUriGrants();
10551 * Prune any older {@link UriPermission} for the given UID until outstanding
10552 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10554 * @return if any mutations occured that require persisting.
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;
10562 final ArrayList<UriPermission> persisted = Lists.newArrayList();
10563 for (UriPermission perm : perms.values()) {
10564 if (perm.persistedModeFlags != 0) {
10565 persisted.add(perm);
10569 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10570 if (trimCount <= 0) return false;
10572 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10573 for (int i = 0; i < trimCount; i++) {
10574 final UriPermission perm = persisted.get(i);
10576 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10577 "Trimming grant created at " + perm.persistedCreateTime);
10579 perm.releasePersistableModes(~0);
10580 removeUriPermissionIfNeededLocked(perm);
10587 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10588 String packageName, boolean incoming) {
10589 enforceNotIsolatedCaller("getPersistedUriPermissions");
10590 Preconditions.checkNotNull(packageName, "packageName");
10592 final int callingUid = Binder.getCallingUid();
10593 final int callingUserId = UserHandle.getUserId(callingUid);
10594 final IPackageManager pm = AppGlobals.getPackageManager();
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);
10602 } catch (RemoteException e) {
10603 throw new SecurityException("Failed to verify package name ownership");
10606 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10607 synchronized (this) {
10609 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10611 if (perms == null) {
10612 Slog.w(TAG, "No permission grants found for " + packageName);
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());
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());
10635 return new ParceledListSlice<android.content.UriPermission>(result);
10639 public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
10640 @Nullable String packageName, int userId) {
10641 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10642 "getGrantedUriPermissions");
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());
10659 return new ParceledListSlice<>(result);
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);
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;
10678 Message msg = Message.obtain();
10679 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10681 msg.arg1 = waiting ? 1 : 0;
10682 mUiHandler.sendMessage(msg);
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);
10703 // =========================================================
10705 // =========================================================
10708 public List<IBinder> getAppTasks(String callingPackage) {
10709 int callingUid = Binder.getCallingUid();
10710 long ident = Binder.clearCallingIdentity();
10712 synchronized(this) {
10713 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10716 Binder.restoreCallingIdentity(ident);
10721 public List<RunningTaskInfo> getTasks(int maxNum) {
10722 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
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<>();
10731 synchronized(this) {
10732 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10734 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10736 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10737 ignoreWindowingMode, callingUid, allowed);
10743 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10744 if (mRecentTasks.isCallerRecents(callingUid)) {
10745 // Always allow the recents component to get tasks
10749 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10750 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
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.
10759 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10761 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10762 + " is using old GET_TASKS but privileged; allowing");
10764 } catch (RemoteException e) {
10769 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10770 + " does not hold REAL_GET_TASKS; limiting output");
10776 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
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(),
10783 final boolean detailed = checkCallingPermission(
10784 android.Manifest.permission.GET_DETAILED_TASKS)
10785 == PackageManager.PERMISSION_GRANTED;
10787 synchronized (this) {
10788 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
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);
10800 return tr.lastTaskDescription;
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();
10813 synchronized (this) {
10814 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10816 throw new IllegalArgumentException("Activity does not exist; token="
10819 ComponentName comp = intent.getComponent();
10820 if (comp == null) {
10821 throw new IllegalArgumentException("Intent " + intent
10822 + " must specify explicit component");
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);
10830 if (intent.getSelector() != null) {
10831 intent.setSelector(null);
10833 if (intent.getSourceBounds() != null) {
10834 intent.setSourceBounds(null);
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);
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);
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;
10860 task.lastTaskDescription.copyFrom(description);
10862 // TODO: Send the thumbnail to WM to store it.
10864 return task.taskId;
10867 Binder.restoreCallingIdentity(callingIdent);
10872 public Point getAppTaskThumbnailSize() {
10873 synchronized (this) {
10874 return new Point(mThumbnailWidth, mThumbnailHeight);
10879 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10880 synchronized (this) {
10881 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10883 r.setTaskDescription(td);
10884 final TaskRecord task = r.getTask();
10885 task.updateTaskDescription();
10886 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
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");
10900 task.setResizeMode(resizeableMode);
10905 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10906 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10907 long ident = Binder.clearCallingIdentity();
10909 synchronized (this) {
10910 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10911 if (task == null) {
10912 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
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);
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);
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;
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);
10948 Binder.restoreCallingIdentity(ident);
10953 public Rect getTaskBounds(int taskId) {
10954 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10955 long ident = Binder.clearCallingIdentity();
10956 Rect rect = new Rect();
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");
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);
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);
10980 Binder.restoreCallingIdentity(ident);
10986 public void cancelTaskWindowTransition(int taskId) {
10987 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10988 "cancelTaskWindowTransition()");
10989 final long ident = Binder.clearCallingIdentity();
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");
10998 task.cancelWindowTransition();
11001 Binder.restoreCallingIdentity(ident);
11006 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
11007 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
11008 final long ident = Binder.clearCallingIdentity();
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");
11019 // Don't call this while holding the lock as this operation might hit the disk.
11020 return task.getSnapshot(reducedResolution);
11022 Binder.restoreCallingIdentity(ident);
11027 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
11028 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11029 userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
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);
11039 return mRecentTasks.getTaskDescriptionIcon(filePath);
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)
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");
11055 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
11056 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
11057 activityOptions.getCustomInPlaceResId());
11058 mWindowManager.executeAppTransition();
11062 public void removeStack(int stackId) {
11063 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
11064 synchronized (this) {
11065 final long ident = Binder.clearCallingIdentity();
11067 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11068 if (stack == null) {
11069 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
11072 if (!stack.isActivityTypeStandardOrUndefined()) {
11073 throw new IllegalArgumentException(
11074 "Removing non-standard stack is not allowed.");
11076 mStackSupervisor.removeStack(stack);
11078 Binder.restoreCallingIdentity(ident);
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
11088 public void removeStacksInWindowingModes(int[] windowingModes) {
11089 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11090 "removeStacksInWindowingModes()");
11091 synchronized (this) {
11092 final long ident = Binder.clearCallingIdentity();
11094 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
11096 Binder.restoreCallingIdentity(ident);
11102 public void removeStacksWithActivityTypes(int[] activityTypes) {
11103 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11104 "removeStacksWithActivityTypes()");
11105 synchronized (this) {
11106 final long ident = Binder.clearCallingIdentity();
11108 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
11110 Binder.restoreCallingIdentity(ident);
11116 * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
11119 String getPendingTempWhitelistTagForUidLocked(int uid) {
11120 final PendingTempWhitelist ptw = mPendingTempWhitelist.get(uid);
11121 return ptw != null ? ptw.tag : null;
11125 boolean isActivityStartsLoggingEnabled() {
11126 return mConstants.mFlagActivityStartsLoggingEnabled;
11130 public void moveStackToDisplay(int stackId, int displayId) {
11131 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
11133 synchronized (this) {
11134 final long ident = Binder.clearCallingIdentity();
11136 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
11137 + " to displayId=" + displayId);
11138 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
11140 Binder.restoreCallingIdentity(ident);
11146 public boolean removeTask(int taskId) {
11147 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
11148 synchronized (this) {
11149 final long ident = Binder.clearCallingIdentity();
11151 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
11154 Binder.restoreCallingIdentity(ident);
11160 * TODO: Add mController hook
11163 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
11164 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
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 */);
11173 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
11174 boolean fromRecents) {
11176 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11177 Binder.getCallingUid(), -1, -1, "Task to front")) {
11178 SafeActivityOptions.abort(options);
11181 final long origId = Binder.clearCallingIdentity();
11183 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11184 if (task == null) {
11185 Slog.d(TAG, "Could not find task for id: "+ taskId);
11188 if (mLockTaskController.isLockTaskModeViolation(task)) {
11189 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
11192 ActivityOptions realOptions = options != null
11193 ? options.getOptions(mStackSupervisor)
11195 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
11196 false /* forceNonResizable */);
11198 final ActivityRecord topActivity = task.getTopActivity();
11199 if (topActivity != null) {
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);
11207 Binder.restoreCallingIdentity(origId);
11209 SafeActivityOptions.abort(options);
11213 * Attempts to move a task backwards in z-order (the order of activities within the task is
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
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.
11232 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
11233 enforceNotIsolatedCaller("moveActivityTaskToBack");
11234 synchronized(this) {
11235 final long origId = Binder.clearCallingIdentity();
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);
11243 Binder.restoreCallingIdentity(origId);
11250 public void moveTaskBackwards(int task) {
11251 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
11252 "moveTaskBackwards()");
11254 synchronized(this) {
11255 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11256 Binder.getCallingUid(), -1, -1, "Task backwards")) {
11259 final long origId = Binder.clearCallingIdentity();
11260 moveTaskBackwardsLocked(task);
11261 Binder.restoreCallingIdentity(origId);
11265 private final void moveTaskBackwardsLocked(int task) {
11266 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
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;
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,
11282 return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
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;
11293 return DEFAULT_DISPLAY;
11298 public void exitFreeformMode(IBinder token) throws RemoteException {
11299 synchronized (this) {
11300 long ident = Binder.clearCallingIdentity();
11302 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11304 throw new IllegalArgumentException(
11305 "exitFreeformMode: No activity record matching token=" + token);
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.");
11314 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11316 Binder.restoreCallingIdentity(ident);
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 */);
11328 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
11329 synchronized (this) {
11330 final long ident = Binder.clearCallingIdentity();
11332 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11333 if (task == null) {
11334 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
11338 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
11339 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
11341 if (!task.isActivityTypeStandardOrUndefined()) {
11342 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11343 + " non-standard task " + taskId + " to windowing mode="
11347 final ActivityStack stack = task.getStack();
11349 stack.moveToFront("setTaskWindowingMode", task);
11351 stack.setWindowingMode(windowingMode);
11353 Binder.restoreCallingIdentity(ident);
11359 * Moves the specified task to the primary-split-screen stack.
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}
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.
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();
11382 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11383 if (task == null) {
11384 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
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");
11395 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
11396 final int windowingMode = task.getWindowingMode();
11397 final ActivityStack stack = task.getStack();
11399 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
11401 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
11402 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
11403 return windowingMode != task.getWindowingMode();
11405 Binder.restoreCallingIdentity(ident);
11411 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
11412 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
11413 synchronized (this) {
11414 long ident = Binder.clearCallingIdentity();
11416 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11417 if (task == null) {
11418 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
11422 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
11423 + " to stackId=" + stackId + " toTop=" + toTop);
11425 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11426 if (stack == null) {
11427 throw new IllegalStateException(
11428 "moveTaskToStack: No stack for stackId=" + stackId);
11430 if (!stack.isActivityTypeStandardOrUndefined()) {
11431 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
11432 + taskId + " to stack " + stackId);
11434 if (stack.inSplitScreenPrimaryWindowingMode()) {
11435 mWindowManager.setDockedStackCreateState(
11436 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
11438 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
11439 "moveTaskToStack");
11441 Binder.restoreCallingIdentity(ident);
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.
11451 public void dismissSplitScreenMode(boolean toTop) {
11452 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
11453 final long ident = Binder.clearCallingIdentity();
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.");
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");
11478 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11481 Binder.restoreCallingIdentity(ident);
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.
11492 public void dismissPip(boolean animate, int animationDuration) {
11493 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
11494 final long ident = Binder.clearCallingIdentity();
11496 synchronized (this) {
11497 final PinnedActivityStack stack =
11498 mStackSupervisor.getDefaultDisplay().getPinnedStack();
11499 if (stack == null) {
11500 Slog.w(TAG, "dismissPip: pinned stack not found.");
11503 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11504 throw new IllegalArgumentException("Stack: " + stack
11505 + " doesn't support animated resize.");
11508 stack.animateResizePinnedStack(null /* sourceHintBounds */,
11509 null /* destBounds */, animationDuration, false /* fromFullscreen */);
11511 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
11515 Binder.restoreCallingIdentity(ident);
11520 * Moves the top activity in the input stackId to the pinned stack.
11522 * @param stackId Id of stack to move the top activity to pinned stack.
11523 * @param bounds Bounds to use for pinned stack.
11525 * @return True if the top activity of the input stack was successfully moved to the pinned
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");
11538 long ident = Binder.clearCallingIdentity();
11540 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
11542 Binder.restoreCallingIdentity(ident);
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();
11553 synchronized (this) {
11555 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
11556 if (stack == null) {
11557 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11560 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11561 throw new IllegalArgumentException("Stack: " + stackId
11562 + " doesn't support animated resize.");
11564 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11565 animationDuration, false /* fromFullscreen */);
11567 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11568 if (stack == null) {
11569 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11572 mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11573 null /* tempTaskInsetBounds */, preserveWindows,
11574 allowResizeInDockedMode, !DEFER_RESUME);
11578 Binder.restoreCallingIdentity(ident);
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();
11589 synchronized (this) {
11590 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11591 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11595 Binder.restoreCallingIdentity(ident);
11600 public void setSplitScreenResizing(boolean resizing) {
11601 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
11602 final long ident = Binder.clearCallingIdentity();
11604 synchronized (this) {
11605 mStackSupervisor.setSplitScreenResizing(resizing);
11608 Binder.restoreCallingIdentity(ident);
11613 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11614 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11615 final long ident = Binder.clearCallingIdentity();
11617 synchronized (this) {
11618 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11621 Binder.restoreCallingIdentity(ident);
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
11631 public void positionTaskInStack(int taskId, int stackId, int position) {
11632 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11633 synchronized (this) {
11634 long ident = Binder.clearCallingIdentity();
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="
11644 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11646 if (stack == null) {
11647 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11650 if (!stack.isActivityTypeStandardOrUndefined()) {
11651 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11652 + " the position of task " + taskId + " in/to non-standard stack");
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);
11661 // Reparent to new stack.
11662 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11663 !DEFER_RESUME, "positionTaskInStack");
11666 Binder.restoreCallingIdentity(ident);
11672 public List<StackInfo> getAllStackInfos() {
11673 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11674 long ident = Binder.clearCallingIdentity();
11676 synchronized (this) {
11677 return mStackSupervisor.getAllStackInfosLocked();
11680 Binder.restoreCallingIdentity(ident);
11685 public StackInfo getStackInfo(int windowingMode, int activityType) {
11686 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11687 long ident = Binder.clearCallingIdentity();
11689 synchronized (this) {
11690 return mStackSupervisor.getStackInfo(windowingMode, activityType);
11693 Binder.restoreCallingIdentity(ident);
11698 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11699 synchronized(this) {
11700 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
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");
11710 synchronized (this) {
11711 mDeviceOwnerName = packageName;
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()");
11722 synchronized (this) {
11723 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11724 Arrays.toString(packages));
11725 mLockTaskController.updateLockTaskPackages(userId, packages);
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()");
11736 synchronized (this) {
11737 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11738 Integer.toHexString(flags));
11739 mLockTaskController.updateLockTaskFeatures(userId, flags);
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) {
11749 final ActivityStack stack = mStackSupervisor.getFocusedStack();
11750 if (stack == null || task != stack.topTask()) {
11751 throw new IllegalArgumentException("Invalid task, not in foreground");
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();
11763 // When a task is locked, dismiss the pinned stack if it exists
11764 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11766 mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11768 Binder.restoreCallingIdentity(ident);
11773 public void startLockTaskModeByToken(IBinder token) {
11774 synchronized (this) {
11775 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11779 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
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();
11789 synchronized (this) {
11790 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11792 // When starting lock task mode the stack must be in front and focused
11793 task.getStack().moveToFront("startSystemLockTaskMode");
11794 startLockTaskModeLocked(task, true /* isSystemCaller */);
11797 Binder.restoreCallingIdentity(ident);
11802 public void stopLockTaskModeByToken(IBinder token) {
11803 synchronized (this) {
11804 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11808 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
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.
11817 public void stopSystemLockTaskMode() throws RemoteException {
11818 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11819 stopLockTaskModeInternal(null, true /* isSystemCaller */);
11822 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11823 final int callingUid = Binder.getCallingUid();
11824 long ident = Binder.clearCallingIdentity();
11826 synchronized (this) {
11827 mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
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);
11833 tm.showInCallScreen(false);
11836 Binder.restoreCallingIdentity(ident);
11841 public boolean isInLockTaskMode() {
11842 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11846 public int getLockTaskModeState() {
11847 synchronized (this) {
11848 return mLockTaskController.getLockTaskModeState();
11853 public void showLockTaskEscapeMessage(IBinder token) {
11854 synchronized (this) {
11855 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11859 mLockTaskController.showLockTaskToast();
11864 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11865 throws RemoteException {
11866 synchronized (this) {
11867 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11869 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11873 final long origId = Binder.clearCallingIdentity();
11875 r.setDisablePreviewScreenshots(disable);
11877 Binder.restoreCallingIdentity(origId);
11882 // =========================================================
11883 // CONTENT PROVIDERS
11884 // =========================================================
11886 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11887 List<ProviderInfo> providers = null;
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)
11894 } catch (RemoteException ex) {
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
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);
11919 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11920 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11922 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11923 mProviderMap.putProviderByClass(comp, cpr);
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,
11936 notifyPackageUse(cpi.applicationInfo.packageName,
11937 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11944 * Check if the calling UID has a possible chance at accessing the provider
11945 * at the given authority and user.
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();
11954 ProviderInfo cpi = null;
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,
11962 } catch (RemoteException ignored) {
11965 return "Failed to find provider " + authority + " for user " + userId
11966 + "; expected to find a valid ContentProvider for this authority";
11969 ProcessRecord r = null;
11970 synchronized (mPidsSelfLocked) {
11971 r = mPidsSelfLocked.get(Binder.getCallingPid());
11974 return "Failed to find PID " + Binder.getCallingPid();
11977 synchronized (this) {
11978 return checkContentProviderPermissionLocked(cpi, r, userId, true);
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}.
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;
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)) {
11999 checkedGrants = true;
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;
12011 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
12012 cpi.applicationInfo.uid, cpi.exported)
12013 == PackageManager.PERMISSION_GRANTED) {
12016 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
12017 cpi.applicationInfo.uid, cpi.exported)
12018 == PackageManager.PERMISSION_GRANTED) {
12022 PathPermission[] pps = cpi.pathPermissions;
12024 int i = pps.length;
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) {
12034 String ppwperm = pp.getWritePermission();
12035 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
12036 cpi.applicationInfo.uid, cpi.exported)
12037 == PackageManager.PERMISSION_GRANTED) {
12042 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
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";
12052 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
12054 final String msg = "Permission Denial: opening provider " + cpi.name
12055 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
12056 + ", uid=" + callingUid + ")" + suffix;
12062 * Returns if the ContentProvider has granted a uri to callingUid
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)) {
12080 * Returns true if the uri authority is one of the authorities specified in the provider.
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);
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;
12096 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
12097 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
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);
12108 conn.stableCount++;
12109 conn.numStableIncs++;
12111 conn.unstableCount++;
12112 conn.numUnstableIncs++;
12117 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
12119 conn.stableCount = 1;
12120 conn.numStableIncs = 1;
12122 conn.unstableCount = 1;
12123 conn.numUnstableIncs = 1;
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);
12131 cpr.addExternalProcessHandleLocked(externalProcessToken);
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);
12145 conn.stableCount--;
12147 conn.unstableCount--;
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();
12160 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
12165 cpr.removeExternalProcessHandleLocked(externalProcessToken);
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);
12177 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
12179 PROC_SPACE_TERM|PROC_PARENS,
12180 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
12183 private final long[] mProcessStateStatsLongs = new long[1];
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);
12190 if (proc.procStatFile == null) {
12191 proc.procStatFile = "/proc/" + proc.pid + "/stat";
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);
12199 final long state = mProcessStateStatsLongs[0];
12200 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
12202 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
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;
12212 synchronized(this) {
12213 long startTime = SystemClock.uptimeMillis();
12215 ProcessRecord r = null;
12216 if (caller != null) {
12217 r = getRecordForAppLocked(caller);
12219 throw new SecurityException(
12220 "Unable to find app for caller " + caller
12221 + " (pid=" + Binder.getCallingPid()
12222 + ") when getting content provider " + name);
12226 boolean checkCrossUser = true;
12228 checkTime(startTime, "getContentProviderImpl: getProviderByName");
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);
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;
12250 if (cpr != null && cpr.proc != null) {
12251 providerRunning = !cpr.proc.killed;
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();
12262 appDiedLocked(cpr.proc);
12264 Binder.restoreCallingIdentity(iden);
12266 checkTime(startTime, "getContentProviderImpl: after appDied (killedByAm)");
12270 if (providerRunning) {
12273 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12274 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
12276 throw new SecurityException(msg);
12278 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
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;
12291 // Don't expose providers between normal apps and instant apps
12293 if (AppGlobals.getPackageManager()
12294 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
12297 } catch (RemoteException e) {
12300 final long origId = Binder.clearCallingIdentity();
12302 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
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");
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)) {
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.
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");
12349 // This wasn't the last ref our process had on
12350 // the provider... we have now been killed, bail.
12353 providerRunning = false;
12356 cpr.proc.verifiedAdj = cpr.proc.setAdj;
12359 Binder.restoreCallingIdentity(origId);
12362 if (!providerRunning) {
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) {
12374 // If the provider is a singleton AND
12375 // (it's a call within the same user || the provider is a
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);
12382 userId = UserHandle.USER_SYSTEM;
12384 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
12385 checkTime(startTime, "getContentProviderImpl: got app info for user");
12388 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12389 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
12391 throw new SecurityException(msg);
12393 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
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");
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!");
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");
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;
12428 final long ident = Binder.clearCallingIdentity();
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)) {
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");
12448 Slog.w(TAG, "No package info for content provider "
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.
12457 Binder.restoreCallingIdentity(ident);
12461 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
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);
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));
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
12478 final int N = mLaunchingProviders.size();
12480 for (i = 0; i < N; i++) {
12481 if (mLaunchingProviders.get(i) == cpr) {
12486 // If the provider is not already being launched, then get it
12489 final long origId = Binder.clearCallingIdentity();
12492 // Content provider is now in use, its package can't be stopped.
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);
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);
12515 proc.thread.scheduleInstallProvider(cpi);
12516 } catch (RemoteException e) {
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");
12534 cpr.launchingApp = proc;
12535 mLaunchingProviders.add(cpr);
12537 Binder.restoreCallingIdentity(origId);
12541 checkTime(startTime, "getContentProviderImpl: updating data structures");
12543 // Make sure the provider is published (the same provider class
12544 // may be published under multiple names).
12546 mProviderMap.putProviderByClass(comp, cpr);
12549 mProviderMap.putProviderByName(name, cpr);
12550 conn = incProviderCountLocked(r, cpr, token, stable);
12551 if (conn != null) {
12552 conn.waiting = true;
12555 checkTime(startTime, "getContentProviderImpl: done!");
12557 grantEphemeralAccessLocked(userId, null /*intent*/,
12558 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
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);
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;
12585 if (cpr.provider == null) {
12586 Slog.wtf(TAG, "Timeout waiting for provider "
12587 + cpi.applicationInfo.packageName + "/"
12588 + cpi.applicationInfo.uid + " for provider "
12590 + " providerRunning=" + providerRunning);
12593 } catch (InterruptedException ex) {
12595 if (conn != null) {
12596 conn.waiting = false;
12601 return cpr != null ? cpr.newHolder(conn) : null;
12604 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
12605 ProcessRecord r, final int userId) {
12606 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
12607 cpi.packageName, userId)) {
12609 final boolean callerForeground = r == null || r.setSchedGroup
12610 != ProcessList.SCHED_GROUP_BACKGROUND;
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");
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);
12624 if (DEBUG_PERMISSIONS_REVIEW) {
12625 Slog.i(TAG, "u" + userId + " Launching permission review "
12626 + "for package " + cpi.packageName);
12629 final UserHandle userHandle = new UserHandle(userId);
12630 mHandler.post(new Runnable() {
12632 public void run() {
12633 mContext.startActivityAsUser(intent, userHandle);
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
12648 IPackageManager getPackageManager() {
12649 return AppGlobals.getPackageManager();
12652 ActivityStartController getActivityStartController() {
12653 return mActivityStartController;
12656 LockTaskController getLockTaskController() {
12657 return mLockTaskController;
12660 ClientLifecycleManager getLifecycleManager() {
12661 return mLifecycleManager;
12664 PackageManagerInternal getPackageManagerInternalLocked() {
12665 if (mPackageManagerInt == null) {
12666 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12668 return mPackageManagerInt;
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 "
12679 throw new SecurityException(msg);
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);
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);
12695 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12696 IBinder token, int userId) {
12697 return getContentProviderImpl(null, name, token, true, userId);
12701 * Drop a content provider from a ProcessRecord's bookkeeping
12703 public void removeContentProvider(IBinder connection, boolean stable) {
12704 enforceNotIsolatedCaller("removeContentProvider");
12705 long ident = Binder.clearCallingIdentity();
12707 synchronized (this) {
12708 ContentProviderConnection conn;
12710 conn = (ContentProviderConnection)connection;
12711 } catch (ClassCastException e) {
12712 String msg ="removeContentProvider: " + connection
12713 + " not a ContentProviderConnection";
12715 throw new IllegalArgumentException(msg);
12717 if (conn == null) {
12718 throw new NullPointerException("connection is null");
12720 if (decProviderCountLocked(conn, null, null, stable)) {
12721 updateOomAdjLocked();
12725 Binder.restoreCallingIdentity(ident);
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();
12735 removeContentProviderExternalUnchecked(name, token, userId);
12737 Binder.restoreCallingIdentity(ident);
12741 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12742 synchronized (this) {
12743 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12745 //remove from mProvidersByClass
12746 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
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();
12757 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12758 + " with no external reference for token: "
12762 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12763 + " with no external references.");
12768 public final void publishContentProviders(IApplicationThread caller,
12769 List<ContentProviderHolder> providers) {
12770 if (providers == null) {
12774 enforceNotIsolatedCaller("publishContentProviders");
12775 synchronized (this) {
12776 final ProcessRecord r = getRecordForAppLocked(caller);
12777 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12779 throw new SecurityException(
12780 "Unable to find app for caller " + caller
12781 + " (pid=" + Binder.getCallingPid()
12782 + ") when publishing content providers");
12785 final long origId = Binder.clearCallingIdentity();
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) {
12793 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12794 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
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);
12803 int launchingCount = mLaunchingProviders.size();
12805 boolean wasInLaunchingProviders = false;
12806 for (j = 0; j < launchingCount; j++) {
12807 if (mLaunchingProviders.get(j) == dst) {
12808 mLaunchingProviders.remove(j);
12809 wasInLaunchingProviders = true;
12814 if (wasInLaunchingProviders) {
12815 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12817 synchronized (dst) {
12818 dst.provider = src.provider;
12822 updateOomAdjLocked(r, true);
12823 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12824 src.info.authority);
12828 Binder.restoreCallingIdentity(origId);
12832 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12833 ContentProviderConnection conn;
12835 conn = (ContentProviderConnection)connection;
12836 } catch (ClassCastException e) {
12837 String msg ="refContentProvider: " + connection
12838 + " not a ContentProviderConnection";
12840 throw new IllegalArgumentException(msg);
12842 if (conn == null) {
12843 throw new NullPointerException("connection is null");
12846 synchronized (this) {
12848 conn.numStableIncs += stable;
12850 stable = conn.stableCount + stable;
12852 throw new IllegalStateException("stableCount < 0: " + stable);
12855 if (unstable > 0) {
12856 conn.numUnstableIncs += unstable;
12858 unstable = conn.unstableCount + unstable;
12859 if (unstable < 0) {
12860 throw new IllegalStateException("unstableCount < 0: " + unstable);
12863 if ((stable+unstable) <= 0) {
12864 throw new IllegalStateException("ref counts can't go to zero here: stable="
12865 + stable + " unstable=" + unstable);
12867 conn.stableCount = stable;
12868 conn.unstableCount = unstable;
12873 public void unstableProviderDied(IBinder connection) {
12874 ContentProviderConnection conn;
12876 conn = (ContentProviderConnection)connection;
12877 } catch (ClassCastException e) {
12878 String msg ="refContentProvider: " + connection
12879 + " not a ContentProviderConnection";
12881 throw new IllegalArgumentException(msg);
12883 if (conn == null) {
12884 throw new NullPointerException("connection is null");
12887 // Safely retrieve the content provider associated with the connection.
12888 IContentProvider provider;
12889 synchronized (this) {
12890 provider = conn.provider.provider;
12893 if (provider == null) {
12894 // Um, yeah, we're way ahead of you.
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");
12908 // Well look at that! It's dead!
12909 synchronized (this) {
12910 if (conn.provider.provider != provider) {
12911 // But something changed... good enough.
12915 ProcessRecord proc = conn.provider.proc;
12916 if (proc == null || proc.thread == null) {
12917 // Seems like the process is already cleaned up.
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",
12927 final long ident = Binder.clearCallingIdentity();
12929 appDiedLocked(proc);
12931 Binder.restoreCallingIdentity(ident);
12937 public void appNotRespondingViaProvider(IBinder connection) {
12938 enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12940 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12941 if (conn == null) {
12942 Slog.w(TAG, "ContentProviderConnection is null");
12946 final ProcessRecord host = conn.provider.proc;
12947 if (host == null) {
12948 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12952 mHandler.post(new Runnable() {
12954 public void run() {
12955 mAppErrors.appNotResponding(host, null, null, false,
12956 "ContentProvider not responding");
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);
12977 if (providers != null) {
12978 mSystemThread.installSystemProviders(providers);
12981 synchronized (this) {
12982 mSystemProvidersInstalled = true;
12985 mConstants.start(mContext.getContentResolver());
12986 mCoreSettingsObserver = new CoreSettingsObserver(this);
12987 mFontScaleSettingObserver = new FontScaleSettingObserver();
12988 mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
12989 GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12991 // Now that the settings provider is published we can consider sending
12992 // in a rescue party.
12993 RescueParty.onSettingsProviderPublished(mContext);
12995 //mUsageStatsService.monitorPackages();
12998 void startPersistentApps(int matchFlags) {
12999 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
13001 synchronized (this) {
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 */);
13010 } catch (RemoteException ex) {
13016 * When a user is unlocked, we need to install encryption-unaware providers
13017 * belonging to any running apps.
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;
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;
13034 final int NG = app.pkgList.size();
13035 for (int ig = 0; ig < NG; ig++) {
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);
13052 Log.v(TAG, "Skipping " + pi);
13056 } catch (RemoteException ignored) {
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.
13070 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
13072 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
13073 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
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();
13081 boolean clearedIdentity = false;
13082 userId = mUserController.unsafeConvertIncomingUser(userId);
13083 if (canClearIdentity(callingPid, callingUid, userId)) {
13084 clearedIdentity = true;
13085 ident = Binder.clearCallingIdentity();
13087 ContentProviderHolder holder = null;
13089 holder = getContentProviderExternalUnchecked(name, null, userId);
13090 if (holder != null) {
13091 return holder.provider.getType(uri);
13093 } catch (RemoteException e) {
13094 Log.w(TAG, "Content provider dead retrieving " + uri, e);
13096 } catch (Exception e) {
13097 Log.w(TAG, "Exception while determining type of " + uri, e);
13100 // We need to clear the identity to call removeContentProviderExternalUnchecked
13101 if (!clearedIdentity) {
13102 ident = Binder.clearCallingIdentity();
13105 if (holder != null) {
13106 removeContentProviderExternalUnchecked(name, null, userId);
13109 Binder.restoreCallingIdentity(ident);
13116 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
13117 if (UserHandle.getUserId(callingUid) == userId) {
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) {
13129 // =========================================================
13130 // GLOBAL MANAGEMENT
13131 // =========================================================
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;
13141 if (isolatedUid == 0) {
13142 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
13144 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
13145 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
13146 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
13148 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
13149 mNextIsolatedProcessUid++;
13150 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
13151 // No process for this uid, use it.
13155 if (stepsLeft <= 0) {
13160 // Special case for startIsolatedProcess (internal only), where
13161 // the uid of the isolated process is specified by the caller.
13164 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
13166 // Register the isolated UID with this application so BatteryStats knows to
13167 // attribute resource usage to the application.
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);
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;
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;
13189 addProcessNameLocked(r);
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]) {
13206 public boolean isBackgroundRestricted(String packageName) {
13207 final int callingUid = Binder.getCallingUid();
13208 final IPackageManager pm = AppGlobals.getPackageManager();
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);
13216 } catch (RemoteException exc) {
13219 return isBackgroundRestrictedNoCheck(callingUid, packageName);
13222 boolean isBackgroundRestrictedNoCheck(final int uid, final String packageName) {
13223 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
13225 return mode != AppOpsManager.MODE_ALLOWED;
13229 public void backgroundWhitelistUid(final int uid) {
13230 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13231 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
13234 if (DEBUG_BACKGROUND_CHECK) {
13235 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
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;
13247 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13248 String abiOverride) {
13249 return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
13253 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13254 boolean disableHiddenApiChecks, String abiOverride) {
13257 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
13264 app = newProcessRecordLocked(info, customProcess, isolated, 0);
13265 updateLruProcessLocked(app, false, null);
13266 updateOomAdjLocked();
13269 // This package really, really can not be stopped.
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);
13279 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
13280 app.persistent = true;
13281 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
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,
13293 public void unhandledBack() {
13294 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
13295 "unhandledBack()");
13297 synchronized(this) {
13298 final long origId = Binder.clearCallingIdentity();
13300 getFocusedStack().unhandledBackLocked();
13302 Binder.restoreCallingIdentity(origId);
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;
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
13322 Binder token = new Binder();
13323 sCallerIdentity.set(new Identity(
13324 token, Binder.getCallingPid(), Binder.getCallingUid()));
13326 pfd = cph.provider.openFile(null, uri, "r", null, token);
13327 } catch (FileNotFoundException e) {
13328 // do nothing; pfd will be returned null
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);
13336 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
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;
13347 boolean isShuttingDownLocked() {
13348 return mShuttingDown;
13351 boolean isSleepingLocked() {
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);
13365 void reportCurWakefulnessUsageEventLocked() {
13366 reportGlobalUsageEventLocked(mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE
13367 ? UsageEvents.Event.SCREEN_INTERACTIVE
13368 : UsageEvents.Event.SCREEN_NON_INTERACTIVE);
13371 void reportCurKeyguardUsageEventLocked() {
13372 reportGlobalUsageEventLocked(mKeyguardShown
13373 ? UsageEvents.Event.KEYGUARD_SHOWN
13374 : UsageEvents.Event.KEYGUARD_HIDDEN);
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;
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)
13390 updateOomAdjLocked();
13395 void finishRunningVoiceLocked() {
13396 if (mRunningVoice != null) {
13397 mRunningVoice = null;
13398 mVoiceWakeLock.release();
13399 updateSleepIfNeededLocked();
13403 void startTimeTrackingFocusedActivityLocked() {
13404 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
13405 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
13406 mCurAppTimeTracker.start(resumedActivity.packageName);
13411 void updateSleepIfNeededLocked() {
13412 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
13413 final boolean wasSleeping = mSleeping;
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.
13421 startTimeTrackingFocusedActivityLocked();
13422 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
13423 mStackSupervisor.comeOutOfSleepIfNeededLocked();
13425 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
13427 updateOomAdjLocked();
13429 } else if (!mSleeping && shouldSleep) {
13431 if (mCurAppTimeTracker != null) {
13432 mCurAppTimeTracker.stop();
13434 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
13435 mStackSupervisor.goingToSleepLocked();
13436 updateResumedAppTrace(null /* resumed */);
13437 updateOomAdjLocked();
13441 /** Pokes the task persister. */
13442 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
13443 mRecentTasks.notifyTaskPersisterLocked(task, flush);
13447 * Notifies all listeners when the pinned stack animation starts.
13450 public void notifyPinnedStackAnimationStarted() {
13451 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
13455 * Notifies all listeners when the pinned stack animation ends.
13458 public void notifyPinnedStackAnimationEnded() {
13459 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
13463 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
13464 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
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);
13475 boolean timedout = false;
13477 synchronized(this) {
13478 mShuttingDown = true;
13479 mStackSupervisor.prepareForShutdownLocked();
13480 updateEventDispatchingLocked();
13481 timedout = mStackSupervisor.shutdownLocked(timeout);
13484 mAppOpsService.shutdown();
13485 if (mUsageStatsService != null) {
13486 mUsageStatsService.prepareShutdown();
13488 mBatteryStatsService.shutdown();
13489 synchronized (this) {
13490 mProcessStats.shutdownLocked();
13491 notifyTaskPersisterLocked(null, true);
13497 public final void activitySlept(IBinder token) {
13498 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
13500 final long origId = Binder.clearCallingIdentity();
13502 synchronized (this) {
13503 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13505 mStackSupervisor.activitySleptLocked(r);
13509 Binder.restoreCallingIdentity(origId);
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();
13526 private void updateEventDispatchingLocked() {
13527 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
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);
13539 synchronized(this) {
13540 long ident = Binder.clearCallingIdentity();
13541 if (mKeyguardShown != keyguardShowing) {
13542 mKeyguardShown = keyguardShowing;
13543 reportCurKeyguardUsageEventLocked();
13546 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
13547 secondaryDisplayShowing);
13549 Binder.restoreCallingIdentity(ident);
13553 mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
13558 public void notifyLockedProfile(@UserIdInt int userId) {
13560 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
13561 throw new SecurityException("Only privileged app can call notifyLockedProfile");
13563 } catch (RemoteException ex) {
13564 throw new SecurityException("Fail to check is caller a privileged app", ex);
13567 synchronized (this) {
13568 final long ident = Binder.clearCallingIdentity();
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");
13576 mStackSupervisor.lockAllProfileTasks(userId);
13579 Binder.restoreCallingIdentity(ident);
13585 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
13586 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
13587 synchronized (this) {
13588 final long ident = Binder.clearCallingIdentity();
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);
13601 Binder.restoreCallingIdentity(ident);
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);
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;
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) {
13639 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
13640 int callingPid, int callingUid, String name) {
13641 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
13645 if (mRecentTasks.isCallerRecents(sourceUid)) {
13649 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
13650 if (perm == PackageManager.PERMISSION_GRANTED) {
13653 if (checkAllowAppSwitchUid(sourceUid)) {
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) {
13664 if (checkAllowAppSwitchUid(callingUid)) {
13669 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
13673 public void setDebugApp(String packageName, boolean waitForDebugger,
13674 boolean persistent) {
13675 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
13678 long ident = Binder.clearCallingIdentity();
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
13684 final ContentResolver resolver = mContext.getContentResolver();
13685 Settings.Global.putString(
13686 resolver, Settings.Global.DEBUG_APP,
13688 Settings.Global.putInt(
13689 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13690 waitForDebugger ? 1 : 0);
13693 synchronized (this) {
13695 mOrigDebugApp = mDebugApp;
13696 mOrigWaitForDebugger = mWaitForDebugger;
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");
13707 Binder.restoreCallingIdentity(ident);
13712 * Set or remove an agent to be run whenever an app with the given process name starts.
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
13718 * Instead, do the check when an application is started and matched to a stored agent.
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.
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);
13735 if (agent == null) {
13736 if (mAppAgentMap != null) {
13737 mAppAgentMap.remove(packageName);
13738 if (mAppAgentMap.isEmpty()) {
13739 mAppAgentMap = null;
13743 if (mAppAgentMap == null) {
13744 mAppAgentMap = new HashMap<>();
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
13752 mAppAgentMap.put(packageName, agent);
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);
13766 mTrackAllocationApp = processName;
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);
13778 mProfileApp = processName;
13780 if (mProfilerInfo != null) {
13781 if (mProfilerInfo.profileFd != null) {
13783 mProfilerInfo.profileFd.close();
13784 } catch (IOException e) {
13788 mProfilerInfo = new ProfilerInfo(profilerInfo);
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);
13800 mNativeDebuggingApp = processName;
13804 public void setAlwaysFinish(boolean enabled) {
13805 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13806 "setAlwaysFinish()");
13808 long ident = Binder.clearCallingIdentity();
13810 Settings.Global.putInt(
13811 mContext.getContentResolver(),
13812 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13814 synchronized (this) {
13815 mAlwaysFinishActivities = enabled;
13818 Binder.restoreCallingIdentity(ident);
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);
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);
13842 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13843 throw new SecurityException("Only an instrumentation process "
13844 + "with a UiAutomation can call setUserIsMonkey");
13847 mUserIsMonkey = userIsMonkey;
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));
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.
13866 public void requestBugReport(int bugreportType) {
13867 String extraOptions = null;
13868 switch (bugreportType) {
13869 case ActivityManager.BUGREPORT_OPTION_FULL:
13870 // Default options.
13872 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13873 extraOptions = "bugreportplus";
13875 case ActivityManager.BUGREPORT_OPTION_REMOTE:
13876 extraOptions = "bugreportremote";
13878 case ActivityManager.BUGREPORT_OPTION_WEAR:
13879 extraOptions = "bugreportwear";
13881 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13882 extraOptions = "bugreporttelephony";
13884 case ActivityManager.BUGREPORT_OPTION_WIFI:
13885 extraOptions = "bugreportwifi";
13888 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
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());
13895 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13896 if (extraOptions != null) {
13897 SystemProperties.set("dumpstate.options", extraOptions);
13899 SystemProperties.set("ctl.start", "bugreport");
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.
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);
13916 if (!TextUtils.isEmpty(shareDescription)) {
13919 length = shareDescription.getBytes("UTF-8").length;
13920 } catch (UnsupportedEncodingException e) {
13921 String errorStr = "shareDescription: UnsupportedEncodingException";
13922 throw new IllegalArgumentException(errorStr);
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);
13929 SystemProperties.set("dumpstate.options.description", shareDescription);
13932 SystemProperties.set("dumpstate.options.title", shareTitle);
13936 Slog.d(TAG, "Bugreport notification title " + shareTitle
13937 + " description " + shareDescription);
13938 requestBugReport(bugreportType);
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.
13948 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13949 requestBugReportWithDescription(shareTitle, shareDescription,
13950 ActivityManager.BUGREPORT_OPTION_TELEPHONY);
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.
13960 public void requestWifiBugReport(String shareTitle, String shareDescription) {
13961 requestBugReportWithDescription(shareTitle, shareDescription,
13962 ActivityManager.BUGREPORT_OPTION_WIFI);
13966 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13967 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13970 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13971 if (r != null && (r.instr != null || r.usingWrapper)) {
13972 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13974 return KEY_DISPATCHING_TIMEOUT;
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);
13984 ProcessRecord proc;
13986 synchronized (this) {
13987 synchronized (mPidsSelfLocked) {
13988 proc = mPidsSelfLocked.get(pid);
13990 timeout = getInputDispatchingTimeoutLocked(proc);
13993 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
14001 * Handle input dispatching timeouts.
14002 * Returns whether input dispatching should be aborted or not.
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);
14013 final String annotation;
14014 if (reason == null) {
14015 annotation = "Input dispatching timed out";
14017 annotation = "Input dispatching timed out (" + reason + ")";
14020 if (proc != null) {
14021 synchronized (this) {
14022 if (proc.debugging) {
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);
14034 mHandler.post(new Runnable() {
14036 public void run() {
14037 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
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);
14053 synchronized (pae) {
14054 while (!pae.haveResult) {
14057 } catch (InterruptedException e) {
14061 synchronized (this) {
14062 buildAssistBundleLocked(pae, pae.result);
14063 mPendingAssistExtras.remove(pae);
14064 mUiHandler.removeCallbacks(pae);
14070 public boolean isAssistDataAllowedOnCurrentActivity() {
14072 synchronized (this) {
14073 final ActivityStack focusedStack = getFocusedStack();
14074 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
14078 final ActivityRecord activity = focusedStack.getTopActivity();
14079 if (activity == null) {
14082 userId = activity.userId;
14084 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
14088 public boolean showAssistFromActivity(IBinder token, Bundle args) {
14089 long ident = Binder.clearCallingIdentity();
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);
14099 if (!top.nowVisible) {
14100 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
14101 + " is not visible");
14105 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
14108 Binder.restoreCallingIdentity(ident);
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;
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;
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,
14132 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
14133 "enqueueAssistContext()");
14135 synchronized (this) {
14136 ActivityRecord activity = getFocusedStack().getTopActivity();
14137 if (activity == null) {
14138 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
14141 if (activity.app == null || activity.app.thread == null) {
14142 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
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);
14155 activity = ActivityRecord.forTokenLocked(activityToken);
14156 if (activity == null) {
14157 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
14158 + " couldn't be found");
14161 if (activity.app == null || activity.app.thread == null) {
14162 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
14167 PendingAssistExtras pae;
14168 Bundle extras = new Bundle();
14169 if (args != null) {
14170 extras.putAll(args);
14172 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
14173 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
14175 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
14177 pae.isHome = activity.isActivityTypeHome();
14179 // Increment the sessionId if necessary
14180 if (newSessionId) {
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);
14196 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
14197 IAssistDataReceiver receiver;
14198 synchronized (this) {
14199 mPendingAssistExtras.remove(pae);
14200 receiver = pae.receiver;
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);
14208 pae.receiver.onHandleAssistData(sendBundle);
14209 } catch (RemoteException e) {
14214 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
14215 if (result != null) {
14216 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
14218 if (pae.hint != null) {
14219 pae.extras.putBoolean(pae.hint, true);
14223 /** Called from an app when assist data is ready. */
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);
14235 if (structure != null) {
14236 structure.setHomeActivity(pae.isHome);
14238 pae.haveResult = true;
14240 if (pae.intent == null && pae.receiver == null) {
14241 // Caller is just waiting for the result.
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);
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);
14266 if (sendReceiver != null) {
14268 sendReceiver.onHandleAssistData(sendBundle);
14269 } catch (RemoteException e) {
14274 final long ident = Binder.clearCallingIdentity();
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));
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");
14288 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
14289 } catch (ActivityNotFoundException e) {
14290 Slog.w(TAG, "No activity to handle assist action.", e);
14294 Binder.restoreCallingIdentity(ident);
14298 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
14300 return enqueueAssistContext(requestType, intent, hint, null, null, null,
14301 true /* focused */, true /* newSessionId */, userHandle, args,
14302 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
14305 public void registerProcessObserver(IProcessObserver observer) {
14306 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
14307 "registerProcessObserver()");
14308 synchronized (this) {
14309 mProcessObservers.register(observer);
14314 public void unregisterProcessObserver(IProcessObserver observer) {
14315 synchronized (this) {
14316 mProcessObservers.unregister(observer);
14321 public int getUidProcessState(int uid, String callingPackage) {
14322 if (!hasUsageStatsPermission(callingPackage)) {
14323 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14324 "getUidProcessState");
14327 synchronized (this) {
14328 UidRecord uidRec = mActiveUids.get(uid);
14329 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
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");
14340 synchronized (this) {
14341 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
14342 callingPackage, which, cutpoint));
14347 public void unregisterUidObserver(IUidObserver observer) {
14348 synchronized (this) {
14349 mUidObservers.unregister(observer);
14354 public boolean isUidActive(int uid, String callingPackage) {
14355 if (!hasUsageStatsPermission(callingPackage)) {
14356 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14359 synchronized (this) {
14360 return isUidActiveLocked(uid);
14364 boolean isUidActiveLocked(int uid) {
14365 final UidRecord uidRecord = mActiveUids.get(uid);
14366 return uidRecord != null && !uidRecord.setIdle;
14370 public boolean convertFromTranslucent(IBinder token) {
14371 final long origId = Binder.clearCallingIdentity();
14373 synchronized (this) {
14374 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14378 final boolean translucentChanged = r.changeWindowTranslucency(true);
14379 if (translucentChanged) {
14380 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14382 mWindowManager.setAppFullscreen(token, true);
14383 return translucentChanged;
14386 Binder.restoreCallingIdentity(origId);
14391 public boolean convertToTranslucent(IBinder token, Bundle options) {
14392 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
14393 final long origId = Binder.clearCallingIdentity();
14395 synchronized (this) {
14396 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14400 final TaskRecord task = r.getTask();
14401 int index = task.mActivities.lastIndexOf(r);
14403 ActivityRecord under = task.mActivities.get(index - 1);
14404 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
14406 final boolean translucentChanged = r.changeWindowTranslucency(false);
14407 if (translucentChanged) {
14408 r.getStack().convertActivityToTranslucent(r);
14410 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14411 mWindowManager.setAppFullscreen(token, false);
14412 return translucentChanged;
14415 Binder.restoreCallingIdentity(origId);
14420 public Bundle getActivityOptions(IBinder token) {
14421 final long origId = Binder.clearCallingIdentity();
14423 synchronized (this) {
14424 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14426 final ActivityOptions activityOptions = r.takeOptionsLocked();
14427 return activityOptions == null ? null : activityOptions.toBundle();
14432 Binder.restoreCallingIdentity(origId);
14437 public void setImmersive(IBinder token, boolean immersive) {
14438 synchronized(this) {
14439 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14441 throw new IllegalArgumentException();
14443 r.immersive = immersive;
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);
14454 public boolean isImmersive(IBinder token) {
14455 synchronized (this) {
14456 ActivityRecord r = ActivityRecord.isInStackLocked(token);
14458 throw new IllegalArgumentException();
14460 return r.immersive;
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);
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;
14484 throw new SecurityException(msg);
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);
14497 * Schedule the given thread a normal scheduling priority.
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.
14502 * @return {@code true} if this succeeded.
14504 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
14506 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
14508 } catch (IllegalArgumentException e) {
14509 if (!suppressLogs) {
14510 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14512 } catch (SecurityException e) {
14513 if (!suppressLogs) {
14514 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14521 * Schedule the given thread an FIFO scheduling priority.
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.
14526 * @return {@code true} if this succeeded.
14528 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
14530 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
14532 } catch (IllegalArgumentException e) {
14533 if (!suppressLogs) {
14534 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14536 } catch (SecurityException e) {
14537 if (!suppressLogs) {
14538 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14545 * Check that we have the features required for VR-related API calls, and throw an exception if
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!");
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);
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");
14572 proc.renderThreadTid = tid;
14573 if (DEBUG_OOM_ADJ) {
14574 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
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);
14583 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
14587 if (DEBUG_OOM_ADJ) {
14588 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
14589 "PID: " + pid + ", TID: " + tid + " FIFO: " +
14590 mUseFifoUiScheduling);
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.
14601 * @param tid the tid of the RenderThread
14603 private void demoteSystemServerRenderThread(int tid) {
14604 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
14608 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
14609 enforceSystemHasVrFeature();
14611 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14614 synchronized (this) {
14615 r = ActivityRecord.isInStackLocked(token);
14619 throw new IllegalArgumentException();
14623 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
14624 VrManagerInternal.NO_ERROR) {
14628 // Clear the binder calling uid since this path may call moveToTask().
14629 final long callingId = Binder.clearCallingIdentity();
14631 synchronized(this) {
14632 r.requestedVrComponent = (enabled) ? packageName : null;
14634 // Update associated state if this activity is currently focused
14635 if (r == mStackSupervisor.getResumedActivityLocked()) {
14636 applyUpdateVrModeLocked(r);
14641 Binder.restoreCallingIdentity(callingId);
14646 public boolean isVrModePackageEnabled(ComponentName packageName) {
14647 enforceSystemHasVrFeature();
14649 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14651 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
14652 VrManagerInternal.NO_ERROR;
14655 public boolean isTopActivityImmersive() {
14656 enforceNotIsolatedCaller("startActivity");
14657 synchronized (this) {
14658 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
14659 return (r != null) ? r.immersive : false;
14664 * @return whether the system should disable UI modes incompatible with VR mode.
14666 boolean shouldDisableNonVrUiLocked() {
14667 return mVrController.shouldDisableNonVrUiLocked();
14671 public boolean isTopOfTask(IBinder token) {
14672 synchronized (this) {
14673 ActivityRecord r = ActivityRecord.isInStackLocked(token);
14675 throw new IllegalArgumentException();
14677 return r.getTask().getTopActivity() == r;
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;
14689 throw new SecurityException(msg);
14691 final int pid = Binder.getCallingPid();
14692 final long origId = Binder.clearCallingIdentity();
14694 synchronized (this) {
14695 boolean changed = false;
14697 synchronized (mPidsSelfLocked) {
14698 pr = mPidsSelfLocked.get(pid);
14700 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
14703 if (pr.hasTopUi != hasTopUi) {
14704 if (DEBUG_OOM_ADJ) {
14705 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
14707 pr.hasTopUi = hasTopUi;
14712 updateOomAdjLocked(pr, true);
14716 Binder.restoreCallingIdentity(origId);
14720 void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
14721 if (pid == Process.myPid()) {
14722 Slog.wtf(TAG, "system can't run remote animation");
14725 synchronized (ActivityManagerService.this) {
14726 final ProcessRecord pr;
14727 synchronized (mPidsSelfLocked) {
14728 pr = mPidsSelfLocked.get(pid);
14730 Slog.w(TAG, "setRunningRemoteAnimation called on unknown pid: " + pid);
14734 if (pr.runningRemoteAnimation == runningRemoteAnimation) {
14737 pr.runningRemoteAnimation = runningRemoteAnimation;
14738 if (DEBUG_OOM_ADJ) {
14739 Slog.i(TAG, "Setting runningRemoteAnimation=" + pr.runningRemoteAnimation
14740 + " for pid=" + pid);
14742 updateOomAdjLocked(pr, true);
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) {
14752 AppGlobals.getPackageManager().enterSafeMode();
14753 } catch (RemoteException e) {
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);
14778 public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
14779 String sourcePkg, String tag) {
14780 if (workSource != null && workSource.isEmpty()) {
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)) {
14791 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14792 final int callerUid = Binder.getCallingUid();
14793 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
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.
14802 Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
14803 + ", workSource=" + workSource + ", tag=" + tag + "]");
14806 mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
14810 public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14812 if (workSource != null && workSource.isEmpty()) {
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)) {
14823 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14824 final int callerUid = Binder.getCallingUid();
14825 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
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.
14834 Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14835 ", tag=" + tag + "]");
14838 mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14842 public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14844 if (workSource != null && workSource.isEmpty()) {
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)) {
14855 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14856 final int callerUid = Binder.getCallingUid();
14857 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
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.
14866 Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14867 ", tag=" + tag + "]");
14870 mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
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");
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.
14881 boolean killed = false;
14882 synchronized (mPidsSelfLocked) {
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) {
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;
14901 // If this is not a secure call, don't let it kill processes that
14903 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14904 worstType = ProcessList.SERVICE_ADJ;
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) {
14913 int adj = proc.setAdj;
14914 if (adj >= worstType && !proc.killedByAm) {
14915 proc.kill(reason, true);
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();
14929 killPackageProcessesLocked(null, appId, userId,
14930 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14931 reason != null ? reason : "kill uid");
14933 Binder.restoreCallingIdentity(identity);
14939 public boolean killProcessesBelowForeground(String reason) {
14940 if (Binder.getCallingUid() != SYSTEM_UID) {
14941 throw new SecurityException("killProcessesBelowForeground() only available to system");
14944 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14947 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14948 if (Binder.getCallingUid() != SYSTEM_UID) {
14949 throw new SecurityException("killProcessesBelowAdj() only available to system");
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;
14960 final int adj = proc.setAdj;
14961 if (adj > belowAdj && !proc.killedByAm) {
14962 proc.kill(reason, true);
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);
14978 final IBinder.DeathRecipient death = new DeathRecipient() {
14980 public void binderDied() {
14981 synchronized (this) {
14988 who.linkToDeath(death, 0);
14989 } catch (RemoteException e) {
14990 Slog.w(TAG, "hang: given caller IBinder is already dead.");
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()) {
15001 } catch (InterruptedException e) {
15005 Watchdog.getInstance().setAllowRestart(true);
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);
15017 Log.i(TAG, "Sending shutdown broadcast...");
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...");
15024 Log.i(TAG, "Shutdown complete, restarting!");
15025 killProcess(myPid());
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);
15038 br.onReceive(mContext, intent);
15041 private long getLowRamTimeSinceIdle(long now) {
15042 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
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);
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;
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());
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);
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);
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);
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);
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);
15118 final long ident = Binder.clearCallingIdentity();
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);
15126 Binder.restoreCallingIdentity(ident);
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;
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();
15157 // Transfer any global setting for forcing RTL layout, into a System Property
15158 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
15160 final Configuration configuration = new Configuration();
15161 Settings.System.getConfiguration(resolver, configuration);
15163 // This will take care of setting the correct layout direction flags
15164 configuration.setLayoutDirection(configuration.locale);
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;
15184 mSupportsMultiWindow = false;
15185 mSupportsFreeformWindowManagement = false;
15186 mSupportsSplitScreenMultiWindow = false;
15187 mSupportsPictureInPicture = false;
15188 mSupportsMultiDisplay = false;
15190 mWindowManager.setForceResizableTasks(mForceResizableActivities);
15191 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
15192 // This happens before any activities are started, so we can change global configuration
15194 updateConfigurationLocked(configuration, null, true);
15195 final Configuration globalConfig = getGlobalConfiguration();
15196 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
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);
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;
15216 mFullscreenThumbnailScale = res.getFraction(
15217 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
15219 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
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();
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;
15249 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
15250 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
15252 } catch (RemoteException e) {}
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>();
15262 procsToKill.add(proc);
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");
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;
15282 Slog.i(TAG, "System now ready");
15283 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
15284 SystemClock.uptimeMillis());
15286 synchronized(this) {
15287 // Make sure we have no pre-ready processes sitting around.
15289 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
15290 ResolveInfo ri = mContext.getPackageManager()
15291 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
15293 CharSequence errorMsg = 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;
15300 mTopComponent = new ComponentName(app.packageName,
15303 errorMsg = mContext.getResources().getText(
15304 com.android.internal.R.string.factorytest_not_system);
15307 errorMsg = mContext.getResources().getText(
15308 com.android.internal.R.string.factorytest_no_action);
15310 if (errorMsg != 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);
15322 retrieveSettings();
15323 final int currentUserId = mUserController.getCurrentUserId();
15324 synchronized (this) {
15325 readGrantedUriPermissionsLocked();
15328 final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
15330 pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
15331 state -> updateForceBackgroundCheck(state.batterySaverEnabled));
15332 updateForceBackgroundCheck(
15333 pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
15335 Slog.wtf(TAG, "PowerManagerInternal not found.");
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);
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);
15351 // Start up initial activity.
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);
15361 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
15362 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
15363 UserHandle.USER_SYSTEM);
15364 } catch (RemoteException e) {
15365 throw e.rethrowAsRuntimeException();
15368 startHomeActivityLocked(currentUserId, "systemReady");
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();
15376 } catch (RemoteException e) {
15379 if (!Build.isBuildConsistent()) {
15380 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
15381 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
15384 long ident = Binder.clearCallingIdentity();
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,
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() {
15400 public void performReceive(Intent intent, int resultCode, String data,
15401 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
15402 throws RemoteException {
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);
15410 Binder.restoreCallingIdentity(ident);
15412 mStackSupervisor.resumeFocusedStackTopActivityLocked();
15413 mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
15415 BinderInternal.nSetBinderProxyCountWatermarks(6000,5500);
15416 BinderInternal.nSetBinderProxyCountEnabled(true);
15417 BinderInternal.setBinderProxyCountCallback(
15418 new BinderInternal.BinderProxyLimitListener() {
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)");
15426 killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
15427 "Too many Binders sent to SYSTEM");
15432 traceLog.traceEnd(); // ActivityManagerStartApps
15433 traceLog.traceEnd(); // PhaseActivityManagerReady
15437 private void updateForceBackgroundCheck(boolean enabled) {
15438 synchronized (this) {
15439 if (mForceBackgroundCheck != enabled) {
15440 mForceBackgroundCheck = enabled;
15442 if (DEBUG_BACKGROUND_CHECK) {
15443 Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
15446 if (mForceBackgroundCheck) {
15447 // Stop background services for idle UIDs.
15448 doStopUidForIdleUidsLocked();
15454 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
15455 synchronized (this) {
15456 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
15460 void skipCurrentReceiverLocked(ProcessRecord app) {
15461 for (BroadcastQueue queue : mBroadcastQueues) {
15462 queue.skipCurrentReceiverLocked(app);
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
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);
15478 handleApplicationCrashInner("crash", r, processName, crashInfo);
15481 /* Native crash reporting uses this inner version because it needs to be somewhat
15482 * decoupled from the AM-managed cleanup lifecycle
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);
15494 StatsLog.write(StatsLog.APP_CRASH_OCCURRED,
15495 Binder.getCallingUid(),
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
15510 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
15512 mAppErrors.crashApplication(r, crashInfo);
15515 public void handleApplicationStrictModeViolation(
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");
15523 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
15524 Integer stackFingerprint = info.hashCode();
15525 boolean logIt = true;
15526 synchronized (mAlreadyLoggedViolatedStacks) {
15527 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
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.
15536 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
15537 mAlreadyLoggedViolatedStacks.clear();
15539 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
15543 logStrictModeViolationToDropBox(r, info);
15547 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
15548 AppErrorResult result = new AppErrorResult();
15549 synchronized (this) {
15550 final long origId = Binder.clearCallingIdentity();
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);
15560 mUiHandler.sendMessage(msg);
15562 Binder.restoreCallingIdentity(origId);
15564 int res = result.get();
15565 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
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) {
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);
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;
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");
15599 if (info.numAnimationsRunning != 0) {
15600 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
15602 if (info.broadcastIntentAction != null) {
15603 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
15605 if (info.durationMillis != -1) {
15606 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
15608 if (info.numInstances != -1) {
15609 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
15611 if (info.tags != null) {
15612 for (String tag : info.tags) {
15613 sb.append("Span-Tag: ").append(tag).append("\n");
15617 sb.append(info.getStackTrace());
15619 if (info.getViolationDetails() != null) {
15620 sb.append(info.getViolationDetails());
15625 final String res = sb.toString();
15626 IoThread.getHandler().post(() -> {
15627 dbox.addText(dropboxTag, res);
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)
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();
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);
15656 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
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;
15663 if (isFatal && !isSystem) {
15664 mAppErrors.crashApplication(r, crashInfo);
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);
15677 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
15678 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
15680 StatsLog.write(StatsLog.WTF_OCCURRED, callingUid, tag, processName,
15683 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
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
15692 private ProcessRecord findAppProcess(IBinder app, String reason) {
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) {
15710 Slog.w(TAG, "Can't find mystery application for " + reason
15711 + " from pid=" + Binder.getCallingPid()
15712 + " uid=" + Binder.getCallingUid() + ": " + app);
15718 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
15719 * to append various headers to the dropbox log text.
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");
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);
15746 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
15748 sb.append(" v").append(pi.getLongVersionCode());
15749 if (pi.versionName != null) {
15750 sb.append(" (").append(pi.versionName).append(")");
15753 } catch (RemoteException e) {
15754 Slog.e(TAG, "Error getting package info: " + pkg, e);
15758 if (process.info.isInstantApp()) {
15759 sb.append("Instant-App: true\n");
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";
15774 private volatile long mWtfClusterStart;
15775 private volatile int mWtfClusterCount;
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
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.
15796 // Bail early if not published yet
15797 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
15798 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
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;
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;
15811 if (mWtfClusterCount++ >= 5) return;
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")
15821 if (activity != null) {
15822 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15824 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15825 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15827 if (parent != null && parent != activity) {
15828 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15830 if (subject != null) {
15831 sb.append("Subject: ").append(subject).append("\n");
15833 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15834 if (Debug.isDebuggerConnected()) {
15835 sb.append("Debugger: Connected\n");
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) {
15843 public void run() {
15844 if (report != null) {
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;
15853 if (dataFile != null && maxDataFileSize > 0) {
15855 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15856 "\n\n[[TRUNCATED]]"));
15857 } catch (IOException e) {
15858 Slog.e(TAG, "Error reading " + dataFile, e);
15861 if (crashInfo != null && crashInfo.stackTrace != null) {
15862 sb.append(crashInfo.stackTrace);
15868 // Merge several logcat streams, and take the last N lines
15869 InputStreamReader input = null;
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();
15877 try { logcat.getOutputStream().close(); } catch (IOException e) {}
15878 try { logcat.getErrorStream().close(); } catch (IOException e) {}
15879 input = new InputStreamReader(logcat.getInputStream());
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);
15887 if (input != null) try { input.close(); } catch (IOException e) {}
15891 dbox.addText(dropboxTag, sb.toString());
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();
15902 StrictMode.setThreadPolicyMask(oldMask);
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;
15915 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15916 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15917 int userId = UserHandle.getUserId(Binder.getCallingUid());
15919 synchronized (this) {
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) {
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;
15937 if (report != null) {
15938 if (errList == null) {
15939 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15941 errList.add(report);
15943 Slog.w(TAG, "Missing app error report, app = " + app.processName +
15944 " crashing = " + app.crashing +
15945 " notResponding = " + app.notResponding);
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;
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;
15975 if (app.persistent) {
15976 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15978 if (app.activities.size() > 0) {
15979 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
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;
15990 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15991 enforceNotIsolatedCaller("getRunningAppProcesses");
15993 final int callingUid = Binder.getCallingUid();
15994 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
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);
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)) {
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;
16027 if (app.adjTarget instanceof ComponentName) {
16028 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
16030 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
16031 // + " lru=" + currApp.lru);
16032 if (runList == null) {
16033 runList = new ArrayList<>();
16035 runList.add(currApp);
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) {
16056 IPackageManager pm = AppGlobals.getPackageManager();
16057 for (String pkg : extList) {
16059 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
16060 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
16063 } catch (RemoteException e) {
16071 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outState) {
16072 if (outState == null) {
16073 throw new IllegalArgumentException("outState is null");
16075 enforceNotIsolatedCaller("getMyMemoryState");
16077 final int callingUid = Binder.getCallingUid();
16078 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
16080 synchronized (this) {
16081 ProcessRecord proc;
16082 synchronized (mPidsSelfLocked) {
16083 proc = mPidsSelfLocked.get(Binder.getCallingPid());
16085 if (proc != null) {
16086 fillInProcMemInfo(proc, outState, clientTargetSdk);
16092 public int getMemoryTrimLevel() {
16093 enforceNotIsolatedCaller("getMyMemoryState");
16094 synchronized (this) {
16095 return mLastMemoryLevel;
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);
16107 SleepToken acquireSleepToken(String tag, int displayId) {
16108 synchronized (this) {
16109 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
16110 updateSleepIfNeededLocked();
16116 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
16117 PriorityDump.dump(mPriorityDumper, fd, pw, args);
16121 * Wrapper function to print out debug data filtered by specified arguments.
16123 private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
16124 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
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;
16136 while (opti < args.length) {
16137 String opt = args[opti];
16138 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16142 if ("-a".equals(opt)) {
16144 } else if ("-c".equals(opt)) {
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];
16155 pw.println("Error: -p option requires package argument");
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);
16169 pw.println("Unknown argument: " + opt + "; use -h for help");
16173 long origId = Binder.clearCallingIdentity();
16176 final ProtoOutputStream proto = new ProtoOutputStream(fd);
16177 String cmd = opti < args.length ? args[opti] : "";
16180 if ("activities".equals(cmd) || "a".equals(cmd)) {
16181 // output proto is ActivityManagerServiceDumpActivitiesProto
16182 synchronized (this) {
16183 writeActivitiesToProtoLocked(proto);
16185 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
16186 // output proto is ActivityManagerServiceDumpBroadcastsProto
16187 synchronized (this) {
16188 writeBroadcastsToProtoLocked(proto);
16190 } else if ("provider".equals(cmd)) {
16193 if (opti >= args.length) {
16195 newArgs = EMPTY_STRING_ARRAY;
16199 newArgs = new String[args.length - opti];
16200 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16201 args.length - opti);
16203 if (!dumpProviderProto(fd, pw, name, newArgs)) {
16204 pw.println("No providers match: " + name);
16205 pw.println("Use -h for help.");
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];
16215 // output proto is ProcessProto
16216 synchronized (this) {
16217 writeProcessesToProtoLocked(proto, dumpPackage);
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);
16226 long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
16227 writeBroadcastsToProtoLocked(proto);
16228 proto.end(broadcastToken);
16230 long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
16231 mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
16232 proto.end(serviceToken);
16234 long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
16235 writeProcessesToProtoLocked(proto, dumpPackage);
16236 proto.end(processToken);
16240 Binder.restoreCallingIdentity(origId);
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];
16250 if ("activities".equals(cmd) || "a".equals(cmd)) {
16251 synchronized (this) {
16252 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16254 } else if ("lastanr".equals(cmd)) {
16255 synchronized (this) {
16256 dumpLastANRLocked(pw);
16258 } else if ("starter".equals(cmd)) {
16259 synchronized (this) {
16260 dumpActivityStarterLocked(pw, dumpPackage);
16262 } else if ("containers".equals(cmd)) {
16263 synchronized (this) {
16264 dumpActivityContainersLocked(pw);
16266 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
16267 synchronized (this) {
16268 if (mRecentTasks != null) {
16269 mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
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");
16277 String uid = args[opti];
16279 // Ensure Binder Proxy Count is as up to date as possible
16281 System.runFinalization();
16283 pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
16285 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
16286 if (opti < args.length) {
16287 dumpPackage = args[opti];
16290 synchronized (this) {
16291 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
16293 } else if ("broadcast-stats".equals(cmd)) {
16294 if (opti < args.length) {
16295 dumpPackage = args[opti];
16298 synchronized (this) {
16299 if (dumpCheckinFormat) {
16300 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
16303 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
16306 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
16307 if (opti < args.length) {
16308 dumpPackage = args[opti];
16311 synchronized (this) {
16312 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
16314 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
16315 if (opti < args.length) {
16316 dumpPackage = args[opti];
16319 synchronized (this) {
16320 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
16322 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
16323 synchronized (this) {
16324 dumpOomLocked(fd, pw, args, opti, true);
16326 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
16327 synchronized (this) {
16328 dumpPermissionsLocked(fd, pw, args, opti, true, null);
16330 } else if ("provider".equals(cmd)) {
16333 if (opti >= args.length) {
16335 newArgs = EMPTY_STRING_ARRAY;
16339 newArgs = new String[args.length - opti];
16340 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16342 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
16343 pw.println("No providers match: " + name);
16344 pw.println("Use -h for help.");
16346 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
16347 synchronized (this) {
16348 dumpProvidersLocked(fd, pw, args, opti, true, null);
16350 } else if ("service".equals(cmd)) {
16353 if (opti >= args.length) {
16355 newArgs = EMPTY_STRING_ARRAY;
16359 newArgs = new String[args.length - opti];
16360 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16361 args.length - opti);
16363 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
16364 pw.println("No services match: " + name);
16365 pw.println("Use -h for help.");
16367 } else if ("package".equals(cmd)) {
16369 if (opti >= args.length) {
16370 pw.println("package: no package name specified");
16371 pw.println("Use -h for help.");
16373 dumpPackage = args[opti];
16375 newArgs = new String[args.length - opti];
16376 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16377 args.length - opti);
16382 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
16383 synchronized (this) {
16384 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16386 } else if ("settings".equals(cmd)) {
16387 synchronized (this) {
16388 mConstants.dump(pw);
16390 } else if ("services".equals(cmd) || "s".equals(cmd)) {
16392 ActiveServices.ServiceDumper dumper;
16393 synchronized (this) {
16394 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16397 dumper.dumpWithClient();
16399 synchronized (this) {
16400 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16401 dumpPackage).dumpLocked();
16404 } else if ("locks".equals(cmd)) {
16405 LockGuard.dump(fd, pw, args);
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));
16414 pw.println("Bad activity command, or no activities match: " + cmd);
16415 pw.println("Use -h for help.");
16420 Binder.restoreCallingIdentity(origId);
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);
16434 pw.println("-------------------------------------------------------------------------------");
16436 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16439 pw.println("-------------------------------------------------------------------------------");
16441 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16444 pw.println("-------------------------------------------------------------------------------");
16446 if (dumpAll || dumpPackage != null) {
16447 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16450 pw.println("-------------------------------------------------------------------------------");
16453 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16456 pw.println("-------------------------------------------------------------------------------");
16458 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16461 pw.println("-------------------------------------------------------------------------------");
16463 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
16466 sdumper.dumpWithClient();
16468 synchronized (this) {
16470 pw.println("-------------------------------------------------------------------------------");
16472 if (mRecentTasks != null) {
16473 mRecentTasks.dump(pw, dumpAll, dumpPackage);
16477 pw.println("-------------------------------------------------------------------------------");
16479 dumpLastANRLocked(pw);
16482 pw.println("-------------------------------------------------------------------------------");
16484 dumpActivityStarterLocked(pw, dumpPackage);
16487 pw.println("-------------------------------------------------------------------------------");
16489 dumpActivityContainersLocked(pw);
16492 pw.println("-------------------------------------------------------------------------------");
16494 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16495 if (mAssociations.size() > 0) {
16498 pw.println("-------------------------------------------------------------------------------");
16500 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16504 pw.println("-------------------------------------------------------------------------------");
16506 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16510 synchronized (this) {
16511 mConstants.dump(pw);
16514 pw.println("-------------------------------------------------------------------------------");
16516 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16519 pw.println("-------------------------------------------------------------------------------");
16521 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16524 pw.println("-------------------------------------------------------------------------------");
16526 if (dumpAll || dumpPackage != null) {
16527 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16530 pw.println("-------------------------------------------------------------------------------");
16533 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16536 pw.println("-------------------------------------------------------------------------------");
16538 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16541 pw.println("-------------------------------------------------------------------------------");
16543 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
16547 pw.println("-------------------------------------------------------------------------------");
16549 if (mRecentTasks != null) {
16550 mRecentTasks.dump(pw, dumpAll, dumpPackage);
16554 pw.println("-------------------------------------------------------------------------------");
16556 dumpLastANRLocked(pw);
16559 pw.println("-------------------------------------------------------------------------------");
16561 dumpActivityStarterLocked(pw, dumpPackage);
16564 pw.println("-------------------------------------------------------------------------------");
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){
16572 pw.println("-------------------------------------------------------------------------------");
16574 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16576 if (mAssociations.size() > 0) {
16579 pw.println("-------------------------------------------------------------------------------");
16581 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16585 pw.println("-------------------------------------------------------------------------------");
16587 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16590 Binder.restoreCallingIdentity(origId);
16593 private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
16594 // The output proto of "activity --proto activities" is ActivityManagerServiceDumpActivitiesProto
16595 mStackSupervisor.writeToProto(proto, ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
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>");
16603 pw.println(mLastANRState);
16607 private void dumpActivityContainersLocked(PrintWriter pw) {
16608 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
16609 mStackSupervisor.dumpChildrenNames(pw, " ");
16613 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
16614 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
16615 mActivityStartController.dump(pw, "", dumpPackage);
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)");
16624 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16625 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
16626 pw.println(header);
16628 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
16630 boolean needSep = printedAnything;
16632 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
16633 mStackSupervisor.getResumedActivityLocked(),
16634 dumpPackage, needSep, " ResumedActivity: ");
16636 printedAnything = true;
16640 if (dumpPackage == null) {
16644 printedAnything = true;
16645 mStackSupervisor.dump(pw, " ");
16648 if (!printedAnything) {
16649 pw.println(" (nothing)");
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)");
16658 if (dumpPackage != null) {
16659 IPackageManager pm = AppGlobals.getPackageManager();
16661 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
16662 } catch (RemoteException e) {
16666 boolean printedAnything = false;
16668 final long now = SystemClock.uptimeMillis();
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) {
16686 printedAnything = true;
16688 pw.print(ass.mTargetProcess);
16690 UserHandle.formatUid(pw, ass.mTargetUid);
16692 pw.print(ass.mSourceProcess);
16694 UserHandle.formatUid(pw, ass.mSourceUid);
16697 pw.print(ass.mTargetComponent.flattenToShortString());
16700 long dur = ass.mTime;
16701 if (ass.mNesting > 0) {
16702 dur += now - ass.mStartTime;
16704 TimeUtils.formatDuration(dur, pw);
16706 pw.print(ass.mCount);
16707 pw.print(" times)");
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;
16716 pw.print(ProcessList.makeProcStateString(
16717 i + ActivityManager.MIN_PROCESS_STATE));
16719 TimeUtils.formatDuration(amt, pw);
16720 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16726 if (ass.mNesting > 0) {
16727 pw.print(" Currently active: ");
16728 TimeUtils.formatDuration(now - ass.mStartTime, pw);
16737 if (!printedAnything) {
16738 pw.println(" (nothing)");
16742 private int getAppId(String dumpPackage) {
16743 if (dumpPackage != null) {
16745 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
16747 return UserHandle.getAppId(info.uid);
16748 } catch (NameNotFoundException e) {
16749 e.printStackTrace();
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) {
16769 pw.println(header);
16772 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
16773 pw.print(": "); pw.println(uidRec);
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);
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]);
16796 pw.print("NO PACKAGE NAME FOUND");
16807 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16808 int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
16809 boolean needSep = false;
16812 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
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)) {
16825 pw.println(" All known processes:");
16828 pw.print(r.persistent ? " *PERS*" : " *APP*");
16829 pw.print(" UID "); pw.print(procs.keyAt(ia));
16830 pw.print(" "); pw.println(r);
16832 if (r.persistent) {
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)) {
16850 pw.println(" Isolated process list (sorted by uid):");
16854 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
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)) {
16871 pw.println(" Active instrumentation:");
16875 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
16881 if (mActiveUids.size() > 0) {
16882 if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16887 if (mValidateUids.size() > 0) {
16888 if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16895 if (mLruProcesses.size() > 0) {
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);
16905 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
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)) {
16918 if (needSep) pw.println();
16920 pw.println(" PID mappings:");
16923 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16924 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
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))) {
16940 if (needSep) pw.println();
16942 pw.println(" Foreground Processes:");
16945 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
16946 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16951 if (mPersistentStartingProcesses.size() > 0) {
16952 if (needSep) pw.println();
16954 pw.println(" Persisent processes that are starting:");
16955 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
16956 "Starting Norm", "Restarting PERS", dumpPackage);
16959 if (mRemovedProcesses.size() > 0) {
16960 if (needSep) pw.println();
16962 pw.println(" Processes that are being removed:");
16963 dumpProcessList(pw, this, mRemovedProcesses, " ",
16964 "Removed Norm", "Removed PERS", dumpPackage);
16967 if (mProcessesOnHold.size() > 0) {
16968 if (needSep) pw.println();
16970 pw.println(" Processes that are on old until the system is ready:");
16971 dumpProcessList(pw, this, mProcessesOnHold, " ",
16972 "OnHold Norm", "OnHold PERS", dumpPackage);
16975 needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16977 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16979 if (dumpPackage == null) {
16982 mUserController.dump(pw, dumpAll);
16984 if (mHomeProcess != null && (dumpPackage == null
16985 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16990 pw.println(" mHomeProcess: " + mHomeProcess);
16992 if (mPreviousProcess != null && (dumpPackage == null
16993 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16998 pw.println(" mPreviousProcess: " + mPreviousProcess);
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);
17007 if (mHeavyWeightProcess != null && (dumpPackage == null
17008 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
17013 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
17015 if (dumpAll && mPendingStarts.size() > 0) {
17016 if (needSep) pw.println();
17018 pw.println(" mPendingStarts: ");
17019 for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
17020 pw.println(" " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
17023 if (dumpPackage == null) {
17024 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
17025 mStackSupervisor.dumpDisplayConfigs(pw, " ");
17028 if (dumpPackage == null) {
17029 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
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)) {
17041 pw.println(" mScreenCompatPackages:");
17044 pw.print(" "); pw.print(pkg); pw.print(": ");
17045 pw.print(mode); pw.println();
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)) {
17055 pw.println(" mUidObservers:");
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) {
17063 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
17066 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
17069 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
17070 pw.print(" STATE");
17071 pw.print(" (cut="); pw.print(reg.cutpoint);
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));
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);
17094 UserHandle.formatUid(pw, ptw.targetUid);
17096 TimeUtils.formatDuration(ptw.duration, pw);
17098 pw.println(ptw.tag);
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);
17112 pw.println(" mVrController=" + mVrController);
17114 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17115 || mOrigWaitForDebugger) {
17116 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17117 || dumpPackage.equals(mOrigDebugApp)) {
17122 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
17123 + " mDebugTransient=" + mDebugTransient
17124 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
17127 if (mCurAppTimeTracker != null) {
17128 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
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++) {
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);
17150 pw.println(sb.toString());
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);
17158 if (mTrackAllocationApp != null) {
17159 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17164 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
17167 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17168 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17169 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
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);
17185 if (mNativeDebuggingApp != null) {
17186 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17191 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
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) {
17206 pw.println(" mAllowAppSwitchUids:");
17209 pw.print(" User ");
17210 pw.print(mAllowAppSwitchUids.keyAt(i));
17211 pw.print(": Type ");
17212 pw.print(types.keyAt(j));
17214 UserHandle.formatUid(pw, types.valueAt(j).intValue());
17220 if (dumpPackage == null) {
17221 if (mAlwaysFinishActivities) {
17222 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
17224 if (mController != null) {
17225 pw.println(" mController=" + mController
17226 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
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);
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);
17258 pw.print(" mUidChangeDispatchCount=");
17259 pw.print(mUidChangeDispatchCount);
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);
17268 pw.print(mUidObservers.getBroadcastItem(i).getClass().getTypeName());
17270 pw.print(r.mSlowDispatchCount);
17271 pw.print(" / Max ");
17272 pw.print(r.mMaxDispatchTime);
17275 mUidObservers.finishBroadcast();
17278 pw.println(" ServiceManager statistics:");
17279 ServiceManager.sStatLogger.dump(pw, " ");
17283 pw.println(" mForceBackgroundCheck=" + mForceBackgroundCheck);
17287 void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
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)) {
17299 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS);
17300 if (r.persistent) {
17306 for (int i=0; i<mIsolatedProcesses.size(); i++) {
17307 ProcessRecord r = mIsolatedProcesses.valueAt(i);
17308 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17311 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS);
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)) {
17320 ai.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_INSTRUMENTATIONS);
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) {
17329 uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
17332 for (int i=0; i<mValidateUids.size(); i++) {
17333 UidRecord uidRec = mValidateUids.valueAt(i);
17334 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
17337 uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
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);
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)) {
17358 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
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))) {
17372 it.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
17377 for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
17378 ProcessRecord r = mPersistentStartingProcesses.get(i);
17379 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17382 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
17385 for (int i=0; i<mRemovedProcesses.size(); i++) {
17386 ProcessRecord r = mRemovedProcesses.get(i);
17387 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17390 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
17393 for (int i=0; i<mProcessesOnHold.size(); i++) {
17394 ProcessRecord r = mProcessesOnHold.get(i);
17395 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17398 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
17401 writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS, dumpPackage);
17402 mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS, dumpPackage);
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);
17410 if (mHomeProcess != null && (dumpPackage == null
17411 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
17412 mHomeProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC);
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);
17421 if (mHeavyWeightProcess != null && (dumpPackage == null
17422 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
17423 mHeavyWeightProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
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);
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);
17446 for (int v : mDeviceIdleWhitelist) {
17447 proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_WHITELIST, v);
17450 for (int v : mDeviceIdleTempWhitelist) {
17451 proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
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);
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());
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);
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);
17480 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
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);
17496 if (mCurAppTimeTracker != null) {
17497 mCurAppTimeTracker.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
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);
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);
17530 if (mTrackAllocationApp != null) {
17531 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17532 proto.write(ActivityManagerServiceDumpProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
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);
17550 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17551 proto.write(ActivityManagerServiceDumpProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
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);
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));
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)) {
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);
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)) {
17617 if (needSep) pw.println();
17619 pw.println(" Processes that are waiting to GC:");
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");
17635 void printOomLevel(PrintWriter pw, String name, int adj) {
17639 if (adj < 10) pw.print(' ');
17641 if (adj > -10) pw.print(' ');
17647 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
17651 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17652 int opti, boolean dumpAll) {
17653 boolean needSep = false;
17655 if (mLruProcesses.size() > 0) {
17656 if (needSep) pw.println();
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);
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);
17681 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
17685 dumpProcessesToGc(pw, needSep, null);
17688 pw.println(" mHomeProcess: " + mHomeProcess);
17689 pw.println(" mPreviousProcess: " + mPreviousProcess);
17690 if (mHeavyWeightProcess != null) {
17691 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
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
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);
17711 * Similar to the dumpProvider, but only dumps the first matching provider.
17712 * The provider is responsible for dumping as proto.
17714 protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
17716 return mProviderMap.dumpProviderProto(fd, pw, name, args);
17719 static class ItemMatcher {
17720 ArrayList<ComponentName> components;
17721 ArrayList<String> strings;
17722 ArrayList<Integer> objects;
17729 void build(String name) {
17730 ComponentName componentName = ComponentName.unflattenFromString(name);
17731 if (componentName != null) {
17732 if (components == null) {
17733 components = new ArrayList<ComponentName>();
17735 components.add(componentName);
17739 // Not a '/' separated full component name; maybe an object ID?
17741 objectId = Integer.parseInt(name, 16);
17742 if (objects == null) {
17743 objects = new ArrayList<Integer>();
17745 objects.add(objectId);
17747 } catch (RuntimeException e) {
17748 // Not an integer; just do string match.
17749 if (strings == null) {
17750 strings = new ArrayList<String>();
17758 int build(String[] args, int opti) {
17759 for (; opti<args.length; opti++) {
17760 String name = args[opti];
17761 if ("--".equals(name)) {
17769 boolean match(Object object, ComponentName comp) {
17773 if (components != null) {
17774 for (int i=0; i<components.size(); i++) {
17775 if (components.get(i).equals(comp)) {
17780 if (objects != null) {
17781 for (int i=0; i<objects.size(); i++) {
17782 if (System.identityHashCode(object) == objects.get(i)) {
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))) {
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.
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
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;
17813 synchronized (this) {
17814 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
17815 dumpFocusedStackOnly);
17818 if (activities.size() <= 0) {
17822 String[] newArgs = new String[args.length - opti];
17823 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
17825 TaskRecord lastTask = null;
17826 boolean needSep = false;
17827 for (int i=activities.size()-1; i>=0; i--) {
17828 ActivityRecord r = activities.get(i);
17833 synchronized (this) {
17834 final TaskRecord task = r.getTask();
17835 if (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);
17841 lastTask.dump(pw, " ");
17845 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
17851 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
17852 * there is a thread associated with the activity.
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)));
17861 if (r.app != null) pw.println(r.app.pid);
17862 else pw.println("(not running)");
17864 r.dump(pw, innerPrefix);
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
17872 TransferPipe tp = new TransferPipe();
17874 r.app.thread.dumpActivity(tp.getWriteFd(),
17875 r.appToken, innerPrefix, args);
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");
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);
17896 mReceiverResolver.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
17897 for (BroadcastQueue q : mBroadcastQueues) {
17898 q.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
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);
17911 proto.end(actionToken);
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);
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;
17929 if ("history".equals(dumpPackage)) {
17930 if (opti < args.length && "-s".equals(args[opti])) {
17933 onlyHistory = true;
17934 dumpPackage = null;
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))) {
17949 pw.println(" Registered Receivers:");
17952 printedAnything = true;
17954 pw.print(" * "); pw.println(r);
17959 if (mReceiverResolver.dump(pw, needSep ?
17960 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
17961 " ", dumpPackage, false, false)) {
17963 printedAnything = true;
17967 for (BroadcastQueue q : mBroadcastQueues) {
17968 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17969 printedAnything |= needSep;
17974 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17975 for (int user=0; user<mStickyBroadcasts.size(); user++) {
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());
17989 ArrayList<Intent> intents = ent.getValue();
17990 final int N = intents.size();
17991 for (int i=0; i<N; i++) {
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) {
17999 pw.println(bundle.toString());
18009 if (!onlyHistory && dumpAll) {
18011 for (BroadcastQueue queue : mBroadcastQueues) {
18012 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
18013 + queue.mBroadcastsScheduled);
18015 pw.println(" mHandler:");
18016 mHandler.dump(new PrintWriterPrinter(pw), " ");
18018 printedAnything = true;
18021 if (!printedAnything) {
18022 pw.println(" (nothing)");
18026 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18027 int opti, boolean dumpAll, String dumpPackage) {
18028 if (mCurBroadcastStats == null) {
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);
18038 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
18040 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
18041 - mLastBroadcastStats.mStartUptime, pw);
18042 pw.println(" uptime):");
18043 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
18044 pw.println(" (nothing)");
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)");
18059 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18060 int opti, boolean fullCheckin, String dumpPackage) {
18061 if (mCurBroadcastStats == null) {
18065 if (mLastBroadcastStats != null) {
18066 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
18068 mLastBroadcastStats = null;
18072 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
18074 mCurBroadcastStats = null;
18078 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18079 int opti, boolean dumpAll, String dumpPackage) {
18081 boolean printedAnything = false;
18083 ItemMatcher matcher = new ItemMatcher();
18084 matcher.build(args, opti);
18086 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
18088 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
18089 printedAnything |= needSep;
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())) {
18099 if (needSep) pw.println();
18101 pw.println(" Launching content providers:");
18103 printedAnything = true;
18105 pw.print(" Launching #"); pw.print(i); pw.print(": ");
18110 if (!printedAnything) {
18111 pw.println(" (nothing)");
18116 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18117 int opti, boolean dumpAll, String dumpPackage) {
18118 boolean needSep = false;
18119 boolean printedAnything = false;
18121 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
18123 if (mGrantedUriPermissions.size() > 0) {
18124 boolean printed = false;
18126 if (dumpPackage != null) {
18128 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
18129 MATCH_ANY_USER, 0);
18130 } catch (NameNotFoundException e) {
18134 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
18135 int uid = mGrantedUriPermissions.keyAt(i);
18136 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
18139 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
18141 if (needSep) pw.println();
18143 pw.println(" Granted Uri Permissions:");
18145 printedAnything = true;
18147 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
18148 for (UriPermission perm : perms.values()) {
18149 pw.print(" "); pw.println(perm);
18151 perm.dump(pw, " ");
18157 if (!printedAnything) {
18158 pw.println(" (nothing)");
18162 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18163 int opti, boolean dumpAll, String dumpPackage) {
18164 boolean printed = false;
18166 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
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;
18181 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
18184 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
18185 if (list == null) {
18186 list = new ArrayList<>();
18187 byPackage.put(rec.key.packageName, list);
18191 for (int i = 0; i < byPackage.size(); i++) {
18192 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
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));
18199 intents.get(j).dump(pw, " ");
18203 if (weakRefs.size() > 0) {
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));
18213 pw.println(" (nothing)");
18217 private static final int dumpProcessList(PrintWriter pw,
18218 ActivityManagerService service, List list,
18219 String prefix, String normalLabel, String persistentLabel,
18220 String dumpPackage) {
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)) {
18228 pw.println(String.format("%s%s #%2d: %s",
18229 prefix, (r.persistent ? persistentLabel : normalLabel),
18231 if (r.persistent) {
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)) {
18247 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
18250 Comparator<Pair<ProcessRecord, Integer>> comparator
18251 = new Comparator<Pair<ProcessRecord, Integer>>() {
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;
18258 if (object1.first.setProcState != object2.first.setProcState) {
18259 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
18261 if (object1.second.intValue() != object2.second.intValue()) {
18262 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
18268 Collections.sort(list, comparator);
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;
18278 final long curUptime = SystemClock.uptimeMillis();
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;
18292 case ProcessList.SCHED_GROUP_DEFAULT:
18293 schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
18295 case ProcessList.SCHED_GROUP_TOP_APP:
18296 schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
18298 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
18299 schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
18302 if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
18303 proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
18305 if (r.foregroundActivities) {
18306 proto.write(ProcessOomProto.ACTIVITIES, true);
18307 } else if (r.foregroundServices) {
18308 proto.write(ProcessOomProto.SERVICES, true);
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());
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());
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);
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);
18361 proto.end(detailToken);
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) {
18374 ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
18375 if (list.isEmpty()) return false;
18377 final long curUptime = SystemClock.uptimeMillis();
18378 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
18380 for (int i=list.size()-1; i>=0; i--) {
18381 ProcessRecord r = list.get(i).first;
18382 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
18384 switch (r.setSchedGroup) {
18385 case ProcessList.SCHED_GROUP_BACKGROUND:
18388 case ProcessList.SCHED_GROUP_DEFAULT:
18391 case ProcessList.SCHED_GROUP_TOP_APP:
18394 case ProcessList.SCHED_GROUP_RESTRICTED:
18402 if (r.foregroundActivities) {
18404 } else if (r.foregroundServices) {
18409 String procState = ProcessList.makeProcStateString(r.curProcState);
18411 pw.print(r.persistent ? persistentLabel : normalLabel);
18413 int num = (origList.size()-1)-list.get(i).second;
18414 if (num < 10) pw.print(' ');
18419 pw.print(schedGroup);
18421 pw.print(foreground);
18423 pw.print(procState);
18425 if (r.trimMemoryLevel < 10) pw.print(' ');
18426 pw.print(r.trimMemoryLevel);
18428 pw.print(r.toShortString());
18430 pw.print(r.adjType);
18432 if (r.adjSource != null || r.adjTarget != null) {
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());
18440 pw.print("{null}");
18443 if (r.adjSource instanceof ProcessRecord) {
18445 pw.print(((ProcessRecord)r.adjSource).toShortString());
18447 } else if (r.adjSource != null) {
18448 pw.println(r.adjSource.toString());
18450 pw.println("{null}");
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);
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);
18471 pw.print("cached="); pw.print(r.cached);
18472 pw.print(" empty="); pw.print(r.empty);
18473 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
18475 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18476 if (r.lastCpuTime != 0) {
18477 long timeUsed = r.curCpuTime - r.lastCpuTime;
18480 pw.print("run cpu over ");
18481 TimeUtils.formatDuration(uptimeSince, pw);
18482 pw.print(" used ");
18483 TimeUtils.formatDuration(timeUsed, pw);
18485 pw.print((timeUsed*100)/uptimeSince);
18494 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
18496 ArrayList<ProcessRecord> procs;
18497 synchronized (this) {
18498 if (args != null && args.length > start
18499 && args[start].charAt(0) != '-') {
18500 procs = new ArrayList<ProcessRecord>();
18503 pid = Integer.parseInt(args[start]);
18504 } catch (NumberFormatException e) {
18506 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18507 ProcessRecord proc = mLruProcesses.get(i);
18508 if (proc.pid > 0 && proc.pid == pid) {
18510 } else if (allPkgs && proc.pkgList != null
18511 && proc.pkgList.containsKey(args[start])) {
18513 } else if (proc.processName.equals(args[start])) {
18517 if (procs.size() <= 0) {
18521 procs = new ArrayList<ProcessRecord>(mLruProcesses);
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]);
18535 long uptime = SystemClock.uptimeMillis();
18536 long realtime = SystemClock.elapsedRealtime();
18537 pw.println("Applications Graphics Acceleration Info:");
18538 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
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 + "] **");
18546 TransferPipe tp = new TransferPipe();
18548 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
18553 } catch (IOException e) {
18554 pw.println("Failure while dumping the app: " + r);
18556 } catch (RemoteException e) {
18557 pw.println("Got a RemoteException while dumping the app " + r);
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]);
18571 pw.println("Applications Database Info:");
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 + "] **");
18579 TransferPipe tp = new TransferPipe();
18581 r.thread.dumpDbInfo(tp.getWriteFd(), args);
18586 } catch (IOException e) {
18587 pw.println("Failure while dumping the app: " + r);
18589 } catch (RemoteException e) {
18590 pw.println("Got a RemoteException while dumping the app " + r);
18597 final static class MemItem {
18598 final boolean isProc;
18599 final String label;
18600 final String shortLabel;
18602 final long swapPss;
18604 final boolean hasActivities;
18605 ArrayList<MemItem> subitems;
18607 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
18608 boolean _hasActivities) {
18611 shortLabel = _shortLabel;
18613 swapPss = _swapPss;
18615 hasActivities = _hasActivities;
18618 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
18621 shortLabel = _shortLabel;
18623 swapPss = _swapPss;
18625 hasActivities = false;
18629 private static void sortMemItems(List<MemItem> items) {
18630 Collections.sort(items, new Comparator<MemItem>() {
18632 public int compare(MemItem lhs, MemItem rhs) {
18633 if (lhs.pss < rhs.pss) {
18635 } else if (lhs.pss > rhs.pss) {
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);
18649 for (int i=0; i<items.size(); i++) {
18650 MemItem mi = items.get(i);
18653 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
18654 mi.label, stringifyKBSize(mi.swapPss));
18656 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
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");
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");
18667 if (mi.subitems != null) {
18668 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
18669 true, isCompact, dumpSwapPss);
18674 static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
18675 ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
18677 sortMemItems(items);
18680 for (int i=0; i<items.size(); i++) {
18681 MemItem mi = items.get(i);
18682 final long token = proto.start(fieldId);
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);
18691 proto.write(MemInfoDumpProto.MemItem.SWAP_PSS_KB, mi.swapPss);
18693 if (mi.subitems != null) {
18694 dumpMemItems(proto, MemInfoDumpProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
18695 true, dumpSwapPss);
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
18709 static final void appendMemBucket(StringBuilder out, long memKB, String label,
18710 boolean stackLike) {
18711 int start = label.lastIndexOf('.');
18712 if (start >= 0) start++;
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);
18724 out.append(memKB/1024);
18725 out.append(stackLike ? "MB." : "MB ");
18726 out.append(label, start, end);
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
18738 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
18740 "System", "Persistent", "Persistent Service", "Foreground",
18741 "Visible", "Perceptible",
18742 "Heavy Weight", "Backup",
18743 "A Services", "Home",
18744 "Previous", "B Services", "Cached"
18746 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
18748 "sys", "pers", "persvc", "fore",
18751 "servicea", "home",
18752 "prev", "serviceb", "cached"
18755 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
18756 long realtime, boolean isCheckinRequest, boolean isCompact) {
18758 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
18760 if (isCheckinRequest || isCompact) {
18761 // short checkin version
18762 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
18764 pw.println("Applications Memory Usage (in Kilobytes):");
18765 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
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;
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
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;
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;
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;
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;
18798 private static String stringifySize(long size, int order) {
18799 Locale locale = Locale.US;
18802 return String.format(locale, "%,13d", size);
18804 return String.format(locale, "%,9dK", size / 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);
18810 throw new IllegalArgumentException("Invalid size order");
18814 private static String stringifyKBSize(long size) {
18815 return stringifySize(size * 1024, 1024);
18818 // Update this version number if you change the 'compact' format.
18819 private static final int MEMINFO_COMPACT_VERSION = 1;
18821 private static class MemoryUsageDumpOptions {
18822 boolean dumpDetails;
18823 boolean dumpFullDetails;
18824 boolean dumpDalvik;
18825 boolean dumpSummaryOnly;
18826 boolean dumpUnreachable;
18831 boolean isCheckinRequest;
18832 boolean dumpSwapPss;
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;
18853 while (opti < args.length) {
18854 String opt = args[opti];
18855 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
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;
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.");
18903 pw.println("Unknown argument: " + opt + "; use -h for help");
18907 String[] innerArgs = new String[args.length-opti];
18908 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18910 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18911 if (opts.dumpProto) {
18912 dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18914 dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
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];
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();
18936 findPid = Integer.parseInt(innerArgs[0]);
18937 } catch (NumberFormatException e) {
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);
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 + "] **");
18960 mi = new Debug.MemoryInfo();
18962 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18963 Debug.getMemoryInfo(pid, mi);
18965 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18966 mi.dalvikPrivateDirty = (int)tmpLong[0];
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) {
18979 pw.println("No process found for: " + proc);
18983 if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18984 opts.dumpDetails = true;
18987 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
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] :
18997 long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19000 long otherSwapPss = 0;
19001 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19002 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
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];
19010 long totalSwapPss = 0;
19011 long cachedPss = 0;
19012 long cachedSwapPss = 0;
19013 boolean hasSwapPss = false;
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;
19021 final boolean hasActivities;
19022 synchronized (this) {
19025 oomAdj = r.getSetAdjWithServices();
19026 hasActivities = r.activities.size() > 0;
19028 if (thread != null) {
19029 if (!opts.isCheckinRequest && opts.dumpDetails) {
19030 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
19033 mi = new Debug.MemoryInfo();
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;
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];
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) {
19061 TransferPipe tp = new TransferPipe();
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);
19070 } catch (IOException e) {
19071 if (!opts.isCheckinRequest) {
19072 pw.println("Got IoException! " + e);
19075 } catch (RemoteException e) {
19076 if (!opts.isCheckinRequest) {
19077 pw.println("Got RemoteException! " + e);
19084 final long myTotalPss = mi.getTotalPss();
19085 final long myTotalUss = mi.getTotalUss();
19086 final long myTotalRss = mi.getTotalRss();
19087 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
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);
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);
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);
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);
19121 mem = mi.getOtherSwappedOutPss(j);
19122 miscSwapPss[j] += mem;
19123 otherSwapPss -= mem;
19126 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19127 cachedPss += myTotalPss;
19128 cachedSwapPss += myTotalSwapPss;
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>();
19140 oomProcs[oomIndex].add(pssItem);
19148 long nativeProcTotalPss = 0;
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();
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) {
19161 mi = new Debug.MemoryInfo();
19163 if (!brief && !opts.oomOnly) {
19164 Debug.getMemoryInfo(st.pid, mi);
19166 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19167 mi.nativePrivateDirty = (int)tmpLong[0];
19170 final long myTotalPss = mi.getTotalPss();
19171 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19172 totalPss += myTotalPss;
19173 totalSwapPss += myTotalSwapPss;
19174 nativeProcTotalPss += myTotalPss;
19176 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19177 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19178 procMems.add(pssItem);
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);
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);
19195 mem = mi.getOtherSwappedOutPss(j);
19196 miscSwapPss[j] += mem;
19197 otherSwapPss -= mem;
19199 oomPss[0] += myTotalPss;
19200 oomSwapPss[0] += myTotalSwapPss;
19201 if (oomProcs[0] == null) {
19202 oomProcs[0] = new ArrayList<MemItem>();
19204 oomProcs[0].add(pssItem);
19209 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
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));
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;
19236 continue; // No subitems, continue.
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));
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];
19260 opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19261 if (!brief && !opts.oomOnly && !opts.isCompact) {
19263 pw.println("Total PSS by process:");
19264 dumpMemItems(pw, " ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
19267 if (!opts.isCompact) {
19268 pw.println("Total PSS by OOM adjustment:");
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) {
19275 out.println("Total PSS by category:");
19277 dumpMemItems(out, " ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
19279 if (!opts.isCompact) {
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);
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)");
19304 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
19305 pw.println("moderate)");
19307 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19308 pw.println("low)");
19310 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19311 pw.println("critical)");
19314 pw.print(mLastMemoryLevel);
19318 pw.print(" Free RAM: ");
19319 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19320 + memInfo.getFreeSizeKb()));
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)");
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);
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));
19345 pw.print("lostram,"); pw.println(lostRAM);
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)");
19359 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
19360 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
19361 pw.println(memInfo.getSwapFreeSizeKb());
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");
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)");
19388 if (ActivityManager.isHighEndGfx()) {
19389 pw.print(" (high-end-gfx)");
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());
19399 pw.print(ActivityManager.staticGetLargeMemoryClass());
19401 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
19402 if (ActivityManager.isLowRamDeviceStatic()) {
19403 pw.print(",low-ram");
19405 if (ActivityManager.isHighEndGfx()) {
19406 pw.print(",high-end-gfx");
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];
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();
19432 findPid = Integer.parseInt(innerArgs[0]);
19433 } catch (NumberFormatException e) {
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);
19445 if (nativeProcs.size() > 0) {
19446 ProtoOutputStream proto = new ProtoOutputStream(fd);
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);
19456 proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19457 proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName);
19460 mi = new Debug.MemoryInfo();
19462 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19463 Debug.getMemoryInfo(pid, mi);
19465 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
19466 mi.dalvikPrivateDirty = (int)tmpLong[0];
19468 ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19469 opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19479 Log.d(TAG, "No process found for: " + innerArgs[0]);
19483 if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
19484 opts.dumpDetails = true;
19487 ProtoOutputStream proto = new ProtoOutputStream(fd);
19489 proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19490 proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
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] :
19500 long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19503 long otherSwapPss = 0;
19504 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19505 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
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];
19513 long totalSwapPss = 0;
19514 long cachedPss = 0;
19515 long cachedSwapPss = 0;
19516 boolean hasSwapPss = false;
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;
19524 final boolean hasActivities;
19525 synchronized (this) {
19528 oomAdj = r.getSetAdjWithServices();
19529 hasActivities = r.activities.size() > 0;
19531 if (thread == null) {
19535 mi = new Debug.MemoryInfo();
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;
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];
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);
19565 ByteTransferPipe tp = new ByteTransferPipe();
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());
19574 } catch (IOException e) {
19575 Log.e(TAG, "Got IOException!", e);
19576 } catch (RemoteException e) {
19577 Log.e(TAG, "Got RemoteException!", e);
19582 final long myTotalPss = mi.getTotalPss();
19583 final long myTotalUss = mi.getTotalUss();
19584 final long myTotalRss = mi.getTotalRss();
19585 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
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);
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);
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);
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);
19619 mem = mi.getOtherSwappedOutPss(j);
19620 miscSwapPss[j] += mem;
19621 otherSwapPss -= mem;
19624 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19625 cachedPss += myTotalPss;
19626 cachedSwapPss += myTotalSwapPss;
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>();
19638 oomProcs[oomIndex].add(pssItem);
19645 long nativeProcTotalPss = 0;
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();
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) {
19658 mi = new Debug.MemoryInfo();
19660 if (!brief && !opts.oomOnly) {
19661 Debug.getMemoryInfo(st.pid, mi);
19663 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19664 mi.nativePrivateDirty = (int)tmpLong[0];
19667 final long myTotalPss = mi.getTotalPss();
19668 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19669 totalPss += myTotalPss;
19670 nativeProcTotalPss += myTotalPss;
19672 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19673 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19674 procMems.add(pssItem);
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);
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);
19691 mem = mi.getOtherSwappedOutPss(j);
19692 miscSwapPss[j] += mem;
19693 otherSwapPss -= mem;
19695 oomPss[0] += myTotalPss;
19696 oomSwapPss[0] += myTotalSwapPss;
19697 if (oomProcs[0] == null) {
19698 oomProcs[0] = new ArrayList<MemItem>();
19700 oomProcs[0].add(pssItem);
19705 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
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));
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;
19732 continue; // No subitems, continue.
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));
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];
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);
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);
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);
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());
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);
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());
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]);
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());
19814 proto.write(MemInfoDumpProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
19815 proto.write(MemInfoDumpProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
19822 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
19823 long memtrack, String name) {
19825 sb.append(ProcessList.makeOomAdjString(oomAdj));
19827 sb.append(ProcessList.makeProcStateString(procState));
19829 ProcessList.appendRamKb(sb, pss);
19832 if (memtrack > 0) {
19834 sb.append(stringifyKBSize(memtrack));
19835 sb.append(" memtrack)");
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 ");
19844 sb.append(mi.adjType);
19846 if (mi.adjReason != null) {
19848 sb.append(mi.adjReason);
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);
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;
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);
19873 if (infoMap.indexOfKey(st.pid) < 0) {
19874 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19875 ProcessList.NATIVE_ADJ, -1, "native", null);
19877 mi.memtrack = memtrackTmp[0];
19884 long totalMemtrack = 0;
19885 for (int i=0, N=memInfos.size(); i<N; i++) {
19886 ProcessMemInfo mi = memInfos.get(i);
19888 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19889 mi.memtrack = memtrackTmp[0];
19891 totalPss += mi.pss;
19892 totalMemtrack += mi.memtrack;
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;
19899 if (lhs.pss != rhs.pss) {
19900 return lhs.pss < rhs.pss ? 1 : -1;
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);
19912 StringBuilder fullNativeBuilder = new StringBuilder(1024);
19913 StringBuilder shortNativeBuilder = new StringBuilder(1024);
19914 StringBuilder fullJavaBuilder = new StringBuilder(1024);
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);
19924 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19925 cachedPss += mi.pss;
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) {
19937 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19942 stack.append("\n\t at ");
19950 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19951 appendMemBucket(tag, mi.pss, mi.name, false);
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)) {
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]);
19961 stack.append(DUMP_MEM_OOM_ADJ[k]);
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);
19974 extraNativeRam += mi.pss;
19975 extraNativeMemtrack += mi.memtrack;
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;
19986 appendMemInfo(fullJavaBuilder, mi);
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)");
19999 fullJavaBuilder.append("\n");
20001 MemInfoReader memInfo = new MemInfoReader();
20002 memInfo.readMemInfo();
20003 final long[] infos = memInfo.getRawInfo();
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");
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");
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());
20061 StringBuilder dropBuilder = new StringBuilder(1024);
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);
20070 String oomString = oomSw.toString();
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');
20081 dropBuilder.append(oomString);
20082 dropBuilder.append('\n');
20084 StringWriter catSw = new StringWriter();
20085 synchronized (ActivityManagerService.this) {
20086 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
20087 String[] emptyArgs = new String[] { };
20089 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
20091 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
20092 false, null).dumpLocked();
20094 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
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;
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
20117 private static boolean scanArgs(String[] args, String value) {
20118 if (args != null) {
20119 for (String arg : args) {
20120 if (value.equals(arg)) {
20128 private final boolean removeDyingProviderLocked(ProcessRecord proc,
20129 ContentProviderRecord cpr, boolean always) {
20130 final boolean inLaunching = mLaunchingProviders.contains(cpr);
20132 if (!inLaunching || always) {
20133 synchronized (cpr) {
20134 cpr.launchingApp = null;
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));
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) {
20154 ProcessRecord capp = conn.client;
20156 if (conn.stableCount > 0) {
20157 if (!capp.persistent && capp.thread != null
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);
20165 } else if (capp.thread != null && conn.provider.provider != null) {
20167 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
20168 } catch (RemoteException e) {
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);
20179 if (inLaunching && always) {
20180 mLaunchingProviders.remove(cpr);
20182 return inLaunching;
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.
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.
20194 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
20195 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
20197 removeLruProcessLocked(app);
20198 ProcessList.remove(app.pid);
20201 mProcessesToGc.remove(app);
20202 mPendingPssProcesses.remove(app);
20203 ProcessList.abortNextPssTime(app.procStateMemTracker);
20205 // Dismiss any open dialogs.
20206 if (app.crashDialog != null && !app.forceCrashReport) {
20207 app.crashDialog.dismiss();
20208 app.crashDialog = null;
20210 if (app.anrDialog != null) {
20211 app.anrDialog.dismiss();
20212 app.anrDialog = null;
20214 if (app.waitDialog != null) {
20215 app.waitDialog.dismiss();
20216 app.waitDialog = null;
20219 app.crashing = false;
20220 app.notResponding = false;
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;
20234 mServices.killServicesLocked(app, allowRestart);
20236 boolean restart = false;
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
20249 cpr.provider = null;
20252 app.pubProviders.clear();
20254 // Take care of any launching providers waiting for this process.
20255 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
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);
20267 app.conProviders.clear();
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.
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;
20287 skipCurrentReceiverLocked(app);
20289 // Unregister any receivers.
20290 for (int i = app.receivers.size() - 1; i >= 0; i--) {
20291 removeReceiverLocked(app.receivers.valueAt(i));
20293 app.receivers.clear();
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() {
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
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);
20320 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
20321 null).sendToTarget();
20323 // If the caller is restarting this app, then leave it in its
20324 // current lists and let the caller take care of it.
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);
20335 if (mHeavyWeightProcess == app) {
20336 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
20337 mHeavyWeightProcess.userId, 0));
20338 mHeavyWeightProcess = null;
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);
20349 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
20350 TAG_CLEANUP, "Clean-up removing on hold: " + app);
20351 mProcessesOnHold.remove(app);
20353 if (app == mHomeProcess) {
20354 mHomeProcess = null;
20356 if (app == mPreviousProcess) {
20357 mPreviousProcess = null;
20360 if (restart && !app.isolated) {
20361 // We have components that still need to be running in the
20362 // process, so re-launch it.
20364 ProcessList.remove(app.pid);
20366 addProcessNameLocked(app);
20367 app.pendingStart = false;
20368 startProcessLocked(app, "restart", app.processName);
20370 } else if (app.pid > 0 && app.pid != MY_PID) {
20373 synchronized (mPidsSelfLocked) {
20374 mPidsSelfLocked.remove(app.pid);
20375 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
20377 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
20378 if (app.isolated) {
20379 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
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) {
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
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()) {
20408 removeDyingProviderLocked(app, cpr, true);
20415 // =========================================================
20417 // =========================================================
20420 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
20421 enforceNotIsolatedCaller("getServices");
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(),
20428 synchronized (this) {
20429 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
20430 allowed, canInteractAcrossUsers);
20435 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
20436 enforceNotIsolatedCaller("getRunningServiceControlPanel");
20437 synchronized (this) {
20438 return mServices.getRunningServiceControlPanelLocked(name);
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");
20452 if (callingPackage == null) {
20453 throw new IllegalArgumentException("callingPackage cannot be null");
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();
20464 res = mServices.startServiceLocked(caller, service,
20465 resolvedType, callingPid, callingUid,
20466 requireForeground, callingPackage, userId);
20468 Binder.restoreCallingIdentity(origId);
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();
20483 res = mServices.startServiceLocked(null, service,
20484 resolvedType, -1, uid, fgRequired, callingPackage, userId);
20486 Binder.restoreCallingIdentity(origId);
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");
20501 synchronized(this) {
20502 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
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");
20514 if (callingPackage == null) {
20515 throw new IllegalArgumentException("callingPackage cannot be null");
20518 synchronized(this) {
20519 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
20524 public boolean stopServiceToken(ComponentName className, IBinder token,
20526 synchronized(this) {
20527 return mServices.stopServiceTokenLocked(className, token, startId);
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);
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);
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;
20560 throw new SecurityException(msg);
20562 // Permission passed
20565 } else if ("system".equals(componentProcessName)) {
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;
20572 if (DEBUG_MU) Slog.v(TAG_MU,
20573 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
20574 + Integer.toHexString(flags) + ") = " + result);
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.
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;
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");
20598 // Refuse possible leaked file descriptors
20599 if (service != null && service.hasFileDescriptors() == true) {
20600 throw new IllegalArgumentException("File descriptors passed in Intent");
20603 if (callingPackage == null) {
20604 throw new IllegalArgumentException("callingPackage cannot be null");
20607 synchronized(this) {
20608 return mServices.bindServiceLocked(caller, token, service,
20609 resolvedType, connection, flags, callingPackage, userId);
20613 public boolean unbindService(IServiceConnection connection) {
20614 synchronized (this) {
20615 return mServices.unbindServiceLocked(connection);
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");
20625 synchronized(this) {
20626 if (!(token instanceof ServiceRecord)) {
20627 throw new IllegalArgumentException("Invalid service token");
20629 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
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");
20639 synchronized(this) {
20640 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
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");
20650 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
20654 // =========================================================
20655 // BACKUP AND RESTORE
20656 // =========================================================
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");
20665 IPackageManager pm = AppGlobals.getPackageManager();
20666 ApplicationInfo app = null;
20668 app = pm.getApplicationInfo(packageName, STOCK_PM_FLAGS, userId);
20669 } catch (RemoteException e) {
20670 // can't happen; package manager is process-local
20673 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
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);
20688 // Backup agent is now in use, its package can't be stopped.
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);
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);
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;
20720 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20721 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
20723 mBackupAppName = app.packageName;
20725 // Try not to kill the process during backup
20726 updateOomAdjLocked(proc, true);
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);
20733 proc.thread.scheduleCreateBackupAgent(app,
20734 compatibilityInfoForPackageLocked(app), backupMode);
20735 } catch (RemoteException e) {
20736 // Will time out on the backup manager side
20739 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
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.
20747 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20748 if (oldBackupUid != -1) {
20749 js.removeBackingUpUid(oldBackupUid);
20751 if (newBackupUid != -1) {
20752 js.addBackingUpUid(newBackupUid);
20759 public void clearPendingBackup() {
20760 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
20761 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
20763 synchronized (this) {
20764 mBackupTarget = null;
20765 mBackupAppName = null;
20768 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20769 js.clearAllBackingUpUids();
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
20777 synchronized(this) {
20778 if (!agentPackageName.equals(mBackupAppName)) {
20779 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
20784 long oldIdent = Binder.clearCallingIdentity();
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();
20795 Binder.restoreCallingIdentity(oldIdent);
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");
20809 synchronized(this) {
20811 if (mBackupAppName == null) {
20812 Slog.w(TAG, "Unbinding backup agent with no active backup");
20816 if (!mBackupAppName.equals(appInfo.packageName)) {
20817 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
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;
20826 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20828 // If the app crashed during backup, 'thread' will be null here
20829 if (proc.thread != null) {
20831 proc.thread.scheduleDestroyBackupAgent(appInfo,
20832 compatibilityInfoForPackageLocked(appInfo));
20833 } catch (Exception e) {
20834 Slog.e(TAG, "Exception when unbinding backup agent:");
20835 e.printStackTrace();
20839 mBackupTarget = null;
20840 mBackupAppName = null;
20844 if (oldBackupUid != -1) {
20845 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20846 js.removeBackingUpUid(oldBackupUid);
20850 // =========================================================
20852 // =========================================================
20854 private boolean isInstantApp(ProcessRecord record, @Nullable String callerPackage, int uid) {
20855 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
20858 // Easy case -- we have the app's ProcessRecord.
20859 if (record != null) {
20860 return record.info.isInstantApp();
20862 // Otherwise check with PackageManager.
20863 IPackageManager pm = AppGlobals.getPackageManager();
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");
20870 // Instant Apps can't use shared uids, so its safe to only check the first package.
20871 callerPackage = packageNames[0];
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);
20881 boolean isPendingBroadcastProcessLocked(int pid) {
20882 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20883 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
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);
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);
20899 return didSomething;
20902 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20903 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
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;
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);
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);
20928 callingUid = callerApp.info.uid;
20929 callingPid = callerApp.pid;
20931 callerPackage = null;
20932 callingUid = Binder.getCallingUid();
20933 callingPid = Binder.getCallingPid();
20936 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20937 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20938 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
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();
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>();
20959 stickyIntents.addAll(intents);
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.
20974 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
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>();
20985 allSticky.add(intent);
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) {
20997 synchronized (this) {
20998 if (callerApp != null && (callerApp.thread == null
20999 || callerApp.thread.asBinder() != caller.asBinder())) {
21000 // Original caller already died
21003 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
21005 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
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);
21014 rl.app.receivers.add(rl);
21017 receiver.asBinder().linkToDeath(rl, 0);
21018 } catch (RemoteException e) {
21021 rl.linkedToDeath = true;
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);
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);
21048 if (!bf.debugCheck()) {
21049 Slog.w(TAG, "==> For Dynamic broadcast");
21051 mReceiverResolver.addFilter(bf);
21054 // Enqueue broadcasts for all existing stickies that match
21056 if (allSticky != null) {
21057 ArrayList receivers = new ArrayList();
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();
21076 public void unregisterReceiver(IIntentReceiver receiver) {
21077 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
21079 final long origId = Binder.clearCallingIdentity();
21081 boolean doTrim = false;
21083 synchronized(this) {
21084 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
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);
21093 r.queue.processNextBroadcast(false);
21097 if (rl.app != null) {
21098 rl.app.receivers.remove(rl);
21100 removeReceiverLocked(rl);
21101 if (rl.linkedToDeath) {
21102 rl.linkedToDeath = false;
21103 rl.receiver.asBinder().unlinkToDeath(rl, 0);
21108 // If we actually concluded any broadcasts, we might now be able
21109 // to trim the recipients' apps from our working set
21111 trimApplications();
21116 Binder.restoreCallingIdentity(origId);
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));
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)) {
21132 r.thread.dispatchPackageBroadcast(cmd, packages);
21133 } catch (RemoteException ex) {
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;
21144 List<ResolveInfo> receivers = null;
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)) {
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);
21170 if (newReceivers != null && newReceivers.size() == 0) {
21171 newReceivers = null;
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
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>();
21191 singleUserReceivers.add(cn);
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>();
21205 if (!singleUserReceivers.contains(cn)) {
21206 singleUserReceivers.add(cn);
21215 } catch (RemoteException ex) {
21216 // pm is in same process, this will never happen.
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());
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
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.
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
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;
21279 BroadcastFilter bf = (BroadcastFilter)target;
21280 if (bf.requiredPermission == null) {
21281 allProtected = false;
21286 if (allProtected) {
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,
21300 Log.wtf(TAG, "Sending non-protected broadcast " + action
21301 + " from system uid " + UserHandle.formatUid(callingUid)
21302 + " pkg " + callerPackage,
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);
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);
21321 // By default broadcasts do not go to stopped apps.
21322 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
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);
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!");
21336 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
21337 ALLOW_NON_FULL, "broadcast", callerPackage);
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;
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 + ")"
21367 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21369 throw new SecurityException(msg);
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;
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;
21385 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
21386 } catch (RemoteException e) {
21387 Slog.w(TAG, "Remote exception", e);
21388 return ActivityManager.BROADCAST_SUCCESS;
21391 final boolean isCallerSystem;
21392 switch (UserHandle.getAppId(callingUid)) {
21396 case BLUETOOTH_UID:
21399 isCallerSystem = true;
21402 isCallerSystem = (callerApp != null) && callerApp.persistent;
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;
21414 throw new SecurityException(msg);
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.";
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(
21432 String msg = "Permission Denial: not allowed to send broadcast "
21434 + intent.getComponent().getPackageName() + " from "
21437 throw new SecurityException(msg);
21440 // Limit broadcast to their own package.
21441 intent.setPackage(callerPackage);
21446 if (action != null) {
21447 if (getBackgroundLaunchBroadcasts().contains(action)) {
21448 if (DEBUG_BACKGROUND_CHECK) {
21449 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
21451 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
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 + ")"
21473 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
21475 throw new SecurityException(msg);
21478 case Intent.ACTION_UID_REMOVED:
21479 final int uid = getUidFromIntent(intent);
21481 mBatteryStatsService.removeUid(uid);
21482 mAppOpsService.uidRemoved(uid);
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.
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");
21495 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21496 sendPackageBroadcastLocked(
21497 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
21501 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21502 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21504 case Intent.ACTION_PACKAGE_REMOVED:
21505 case Intent.ACTION_PACKAGE_CHANGED:
21506 Uri data = intent.getData();
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;
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");
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);
21531 // Remove all permissions granted from/to this package
21532 removeUriPermissionsForPackageLocked(ssp, userId, true,
21535 mRecentTasks.removeTasksByPackageName(ssp, userId);
21537 mServices.forceStopPackageLocked(ssp, userId);
21538 mAppWarnings.onPackageUninstalled(ssp);
21539 mCompatModePackages.handlePackageUninstalledLocked(ssp);
21540 mBatteryStatsService.notePackageUninstalled(ssp);
21544 killPackageProcessesLocked(ssp, UserHandle.getAppId(
21545 intent.getIntExtra(Intent.EXTRA_UID, -1)),
21546 userId, ProcessList.INVALID_ADJ,
21547 false, true, true, false, "change " + ssp);
21549 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
21550 intent.getStringArrayExtra(
21551 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
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);
21564 synchronized(ActivityManagerService.this) {
21565 mRecentTasks.onPackagesSuspendedChanged(
21566 packageNames, suspended, userHandle);
21571 case Intent.ACTION_PACKAGE_REPLACED:
21573 final Uri data = intent.getData();
21575 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21576 ApplicationInfo aInfo = null;
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;
21586 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
21587 mServices.updateServiceApplicationInfoLocked(aInfo);
21588 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
21589 new String[] {ssp}, userId);
21593 case Intent.ACTION_PACKAGE_ADDED:
21595 // Special case for adding a package: by default turn on compatibility mode.
21596 Uri data = intent.getData();
21598 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21599 final boolean replacing =
21600 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21601 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
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) {
21613 case Intent.ACTION_PACKAGE_DATA_CLEARED:
21615 Uri data = intent.getData();
21617 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21618 mCompatModePackages.handlePackageDataClearedLocked(ssp);
21619 mAppWarnings.onPackageDataCleared(ssp);
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);
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);
21644 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21645 synchronized (stats) {
21646 stats.noteCurrentTimeChangedLocked();
21649 case Intent.ACTION_CLEAR_DNS_CACHE:
21650 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
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));
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);
21665 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
21666 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
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;
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);
21681 final UidRecord uidRec = mActiveUids.get(uid);
21682 if (uidRec != null) {
21683 uidRec.updateHasInternetPermission();
21689 // Add to the sticky list if requested.
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;
21698 throw new SecurityException(msg);
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;
21705 if (intent.getComponent() != null) {
21706 throw new SecurityException(
21707 "Sticky broadcasts can't target a specific component");
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
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();
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");
21732 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21733 if (stickies == null) {
21734 stickies = new ArrayMap<>();
21735 mStickyBroadcasts.put(userId, stickies);
21737 ArrayList<Intent> list = stickies.get(intent.getAction());
21738 if (list == null) {
21739 list = new ArrayList<>();
21740 stickies.put(intent.getAction(), list);
21742 final int stickiesCount = list.size();
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));
21751 if (i >= stickiesCount) {
21752 list.add(new Intent(intent));
21757 if (userId == UserHandle.USER_ALL) {
21758 // Caller wants broadcast to go to all started users.
21759 users = mUserController.getStartedUserArray();
21761 // Caller wants broadcast to go to one specific user.
21762 users = new int[] {userId};
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)
21771 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
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])) {
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);
21791 registeredReceivers = mReceiverResolver.queryIntent(intent,
21792 resolvedType, false /*defaultOnly*/, userId);
21796 final boolean replacePending =
21797 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
21799 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
21800 + " replacePending=" + replacePending);
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);
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.
21821 queue.enqueueParallelBroadcastLocked(r);
21822 queue.scheduleBroadcastsLocked();
21824 registeredReceivers = null;
21828 // Merge into one list.
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
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 };
21848 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
21849 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
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);
21867 int NT = receivers != null ? receivers.size() : 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);
21875 if (curr == null) {
21876 curr = registeredReceivers.get(ir);
21878 if (curr.getPriority() >= curt.priority) {
21879 // Insert this broadcast record into the final list.
21880 receivers.add(it, curr);
21886 // Skip to the next ResolveInfo in the final list.
21893 if (receivers == null) {
21894 receivers = new ArrayList();
21896 receivers.add(registeredReceivers.get(ir));
21900 if (isCallerSystem) {
21901 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21902 isProtectedBroadcast, receivers);
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);
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());
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);
21925 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
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 "
21937 queue.enqueueOrderedBroadcastLocked(r);
21938 queue.scheduleBroadcastsLocked();
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);
21950 return ActivityManager.BROADCAST_SUCCESS;
21954 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21956 private int getUidFromIntent(Intent intent) {
21957 if (intent == null) {
21960 final Bundle intentExtras = intent.getExtras();
21961 return intent.hasExtra(Intent.EXTRA_UID)
21962 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
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();
21974 mCurBroadcastStats = new BroadcastStats();
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);
21984 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21985 rotateBroadcastStatsIfNeededLocked();
21986 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
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");
21995 int flags = intent.getFlags();
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");
22009 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
22010 throw new IllegalArgumentException(
22011 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
22014 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
22015 switch (Binder.getCallingUid()) {
22020 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
22021 + Binder.getCallingUid());
22022 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
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);
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);
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,
22059 synchronized(this) {
22060 intent = verifyBroadcastLocked(intent);
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);
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");
22080 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22081 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
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;
22091 throw new SecurityException(msg);
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();
22099 for (i=0; i<N; i++) {
22100 if (intent.filterEquals(list.get(i))) {
22105 if (list.size() <= 0) {
22106 stickies.remove(intent.getAction());
22109 if (stickies.size() <= 0) {
22110 mStickyBroadcasts.remove(userId);
22116 void backgroundServicesFinishedLocked(int userId) {
22117 for (BroadcastQueue queue : mBroadcastQueues) {
22118 queue.backgroundServicesFinishedLocked(userId);
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);
22126 // Refuse possible leaked file descriptors
22127 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
22128 throw new IllegalArgumentException("File descriptors passed in Bundle");
22131 final long origId = Binder.clearCallingIdentity();
22133 boolean doNext = false;
22136 synchronized(this) {
22137 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
22138 ? mFgBroadcastQueue : mBgBroadcastQueue;
22139 r = queue.getMatchingOrderedReceiver(who);
22141 doNext = r.queue.finishReceiverLocked(r, resultCode,
22142 resultData, resultExtras, resultAbort, true);
22145 r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
22147 // updateOomAdjLocked() will be done here
22148 trimApplicationsLocked();
22152 Binder.restoreCallingIdentity(origId);
22156 // =========================================================
22158 // =========================================================
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");
22172 synchronized(this) {
22173 InstrumentationInfo ii = null;
22174 ApplicationInfo ai = null;
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) {
22184 reportStartInstrumentationFailureLocked(watcher, className,
22185 "Unable to find instrumentation info for: " + className);
22189 reportStartInstrumentationFailureLocked(watcher, className,
22190 "Unable to find instrumentation target package: " + ii.targetPackage);
22193 if (!ai.hasCode()) {
22194 reportStartInstrumentationFailureLocked(watcher, className,
22195 "Instrumentation target has no code: " + ii.targetPackage);
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);
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];
22221 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
22222 defProcess = activeInstr.mTargetProcesses[0];
22224 activeInstr.mTargetInfo = ai;
22225 activeInstr.mProfileFile = profileFile;
22226 activeInstr.mArguments = arguments;
22227 activeInstr.mWatcher = watcher;
22228 activeInstr.mUiAutomationConnection = uiAutomationConnection;
22229 activeInstr.mResultClass = className;
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");
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,
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);
22248 ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
22250 app.instr = activeInstr;
22251 activeInstr.mFinished = false;
22252 activeInstr.mRunningProcesses.add(app);
22253 if (!mActiveInstrumentation.contains(activeInstr)) {
22254 mActiveInstrumentation.add(activeInstr);
22256 Binder.restoreCallingIdentity(origId);
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.
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.
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);
22282 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
22283 if (app.instr == null) {
22284 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
22288 if (!app.instr.mFinished && results != null) {
22289 if (app.instr.mCurResults == null) {
22290 app.instr.mCurResults = new Bundle(results);
22292 app.instr.mCurResults.putAll(results);
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");
22304 synchronized(this) {
22305 ProcessRecord app = getRecordForAppLocked(target);
22307 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
22310 final long origId = Binder.clearCallingIdentity();
22311 addInstrumentationResultsLocked(app, results);
22312 Binder.restoreCallingIdentity(origId);
22317 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
22318 if (app.instr == null) {
22319 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
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);
22331 finalResults = results;
22333 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
22334 app.instr.mClass, resultCode, finalResults);
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();
22342 app.instr.mFinished = true;
22345 app.instr.removeProcess(app);
22348 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
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");
22360 synchronized(this) {
22361 ProcessRecord app = getRecordForAppLocked(target);
22363 Slog.w(TAG, "finishInstrumentation: no app for " + target);
22366 final long origId = Binder.clearCallingIdentity();
22367 finishInstrumentationLocked(app, resultCode, results);
22368 Binder.restoreCallingIdentity(origId);
22372 // =========================================================
22374 // =========================================================
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;
22387 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
22388 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
22389 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
22391 config.reqGlEsVersion = GL_ES_VERSION;
22396 ActivityStack getFocusedStack() {
22397 return mStackSupervisor.getFocusedStack();
22401 public StackInfo getFocusedStackInfo() throws RemoteException {
22402 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
22403 long ident = Binder.clearCallingIdentity();
22405 synchronized (this) {
22406 ActivityStack focusedStack = getFocusedStack();
22407 if (focusedStack != null) {
22408 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
22413 Binder.restoreCallingIdentity(ident);
22417 public Configuration getConfiguration() {
22419 synchronized(this) {
22420 ci = new Configuration(getGlobalConfiguration());
22421 ci.userSetLocale = false;
22427 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
22428 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
22429 synchronized (this) {
22430 mSuppressResizeConfigChanges = suppress;
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.
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();
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.");
22453 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
22456 Binder.restoreCallingIdentity(origId);
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");
22469 int userId = UserHandle.getCallingUserId();
22471 synchronized(this) {
22472 updatePersistentConfigurationLocked(values, userId);
22476 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
22477 final long origId = Binder.clearCallingIdentity();
22479 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
22481 Binder.restoreCallingIdentity(origId);
22485 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
22486 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
22487 FONT_SCALE, 1.0f, userId);
22489 synchronized (this) {
22490 if (getGlobalConfiguration().fontScale == scaleFactor) {
22494 final Configuration configuration
22495 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22496 configuration.fontScale = scaleFactor;
22497 updatePersistentConfigurationLocked(configuration, userId);
22501 private void enforceWriteSettingsPermission(String func) {
22502 int uid = Binder.getCallingUid();
22503 if (uid == ROOT_UID) {
22507 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
22508 Settings.getPackageNameForUid(mContext, uid), false)) {
22512 String msg = "Permission Denial: " + func + " from pid="
22513 + Binder.getCallingPid()
22515 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
22517 throw new SecurityException(msg);
22521 public boolean updateConfiguration(Configuration values) {
22522 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
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);
22530 if (mWindowManager != null) {
22531 // Update OOM levels based on display size.
22532 mProcessList.applyDisplaySize(mWindowManager);
22535 final long origId = Binder.clearCallingIdentity();
22537 if (values != null) {
22538 Settings.System.clearConfiguration(values);
22540 updateConfigurationLocked(values, null, false, false /* persistent */,
22541 UserHandle.USER_NULL, false /* deferResume */,
22542 mTmpUpdateConfigurationResult);
22543 return mTmpUpdateConfigurationResult.changes != 0;
22545 Binder.restoreCallingIdentity(origId);
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 */);
22559 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22560 boolean initLocale) {
22561 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
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);
22571 // To cache the list of supported system locales
22572 private String[] mSupportedSystemLocales = null;
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 */);
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
22587 * @param userId is only used when persistent parameter is set to true to persist configuration
22588 * for that particular user
22590 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22591 boolean initLocale, boolean persistent, int userId, boolean deferResume,
22592 UpdateConfigurationResult result) {
22594 boolean kept = true;
22596 if (mWindowManager != null) {
22597 mWindowManager.deferSurfaceLayout();
22600 if (values != null) {
22601 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
22605 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22607 if (mWindowManager != null) {
22608 mWindowManager.continueSurfaceLayout();
22612 if (result != null) {
22613 result.changes = changes;
22614 result.activityRelaunched = !kept;
22620 * Returns true if this configuration change is interesting enough to send an
22621 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
22623 private static boolean isSplitConfigurationChange(int configDiff) {
22624 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
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);
22641 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
22642 "Updating global configuration to: " + values);
22644 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
22645 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
22649 values.hardKeyboardHidden,
22651 values.keyboardHidden,
22655 values.navigationHidden,
22656 values.orientation,
22657 values.screenHeightDp,
22658 values.screenLayout,
22659 values.screenWidthDp,
22660 values.smallestScreenWidthDp,
22661 values.touchscreen,
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();
22672 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
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)));
22681 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
22682 mTempConfig.seq = mConfigurationSeq;
22684 // Update stored global config and notify everyone about the change.
22685 mStackSupervisor.onConfigurationChanged(mTempConfig);
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());
22692 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
22693 updateShouldShowDialogsLocked(mTempConfig);
22695 AttributeCache ac = AttributeCache.instance();
22697 ac.updateConfiguration(mTempConfig);
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);
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;
22713 mHandler.sendMessage(msg);
22716 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22717 ProcessRecord app = mLruProcesses.get(i);
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));
22725 } catch (Exception e) {
22726 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
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);
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);
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);
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);
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,
22772 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
22773 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
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="
22786 if (values == null && mWindowManager != null) {
22787 // sentinel: fetch the current configuration from the window manager
22788 values = mWindowManager.computeNewConfiguration(displayId);
22791 if (mWindowManager != null) {
22792 // Update OOM levels based on display size.
22793 mProcessList.applyDisplaySize(mWindowManager);
22796 final long origId = Binder.clearCallingIdentity();
22798 if (values != null) {
22799 Settings.System.clearConfiguration(values);
22801 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
22802 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
22803 return mTmpUpdateConfigurationResult.changes != 0;
22805 Binder.restoreCallingIdentity(origId);
22810 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
22811 boolean deferResume, int displayId) {
22812 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
22813 displayId, null /* result */);
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.
22820 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
22821 ActivityRecord starting, boolean deferResume, int displayId,
22822 UpdateConfigurationResult result) {
22824 boolean kept = true;
22826 if (mWindowManager != null) {
22827 mWindowManager.deferSurfaceLayout();
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);
22838 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
22842 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22844 if (mWindowManager != null) {
22845 mWindowManager.continueSurfaceLayout();
22849 if (result != null) {
22850 result.changes = changes;
22851 result.activityRelaunched = !kept;
22856 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
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);
22865 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
22866 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
22867 mAppWarnings.onDensityChanged();
22869 killAllBackgroundProcessesExcept(N,
22870 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
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);
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();
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);
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);
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();
22929 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
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);
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.
22945 * A thought: SystemUI might also want to get told about this, the Power
22946 * dialog / global actions also might want different behaviors.
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;
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);
22973 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22974 Intent resultData) {
22976 synchronized (this) {
22977 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22979 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22985 public int getLaunchedFromUid(IBinder activityToken) {
22986 ActivityRecord srec;
22987 synchronized (this) {
22988 srec = ActivityRecord.forTokenLocked(activityToken);
22990 if (srec == null) {
22993 return srec.launchedFromUid;
22996 public String getLaunchedFromPackage(IBinder activityToken) {
22997 ActivityRecord srec;
22998 synchronized (this) {
22999 srec = ActivityRecord.forTokenLocked(activityToken);
23001 if (srec == null) {
23004 return srec.launchedFromPackage;
23007 // =========================================================
23008 // LIFETIME MANAGEMENT
23009 // =========================================================
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();
23018 for (int i = 0; i < N; i++) {
23019 receivingQueues.add(app.curReceivers.valueAt(i).queue);
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);
23033 return !receivingQueues.isEmpty();
23036 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
23037 int targetUid, ComponentName targetComponent, String targetProcess) {
23038 if (!mTrackingAssociations) {
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);
23047 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
23048 if (sourceUids == null) {
23049 sourceUids = new SparseArray<>();
23050 components.put(targetComponent, sourceUids);
23052 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
23053 if (sourceProcesses == null) {
23054 sourceProcesses = new ArrayMap<>();
23055 sourceUids.put(sourceUid, sourceProcesses);
23057 Association ass = sourceProcesses.get(sourceProcess);
23059 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
23061 sourceProcesses.put(sourceProcess, ass);
23065 if (ass.mNesting == 1) {
23066 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
23067 ass.mLastState = sourceState;
23072 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
23073 ComponentName targetComponent) {
23074 if (!mTrackingAssociations) {
23077 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
23078 = mAssociations.get(targetUid);
23079 if (components == null) {
23082 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
23083 if (sourceUids == null) {
23086 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
23087 if (sourceProcesses == null) {
23090 Association ass = sourceProcesses.get(sourceProcess);
23091 if (ass == null || ass.mNesting <= 0) {
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;
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;
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.
23140 // The process is being computed, so there is a cycle. We cannot
23141 // rely on this process's state.
23142 app.containsCycle = true;
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;
23157 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
23158 app.adjSource = null;
23159 app.adjTarget = null;
23161 app.cached = false;
23163 final int activitiesSize = app.activities.size();
23164 final int appUid = app.info.uid;
23165 final int logUid = mCurOomAdjUid;
23167 int prevAppAdj = app.curAdj;
23168 int prevProcState = app.curProcState;
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);
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);
23199 app.systemNoUi = false;
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;
23209 // screen off, restrict UI scheduling
23210 app.curProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23211 app.curSchedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
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;
23220 app.systemNoUi = false;
23222 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
23224 // Determine the importance of the process, starting with most
23225 // important to least, and assign an appropriate OOM adjustment.
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);
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);
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);
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);
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);
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);
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.
23300 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23303 app.adjType = "cch-empty";
23304 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23305 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app);
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
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);
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);
23342 if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23343 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23345 app.cached = 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) {
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);
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);
23373 if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23374 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23376 app.cached = 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);
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);
23405 app.cached = false;
23407 foregroundActivities = true;
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);
23419 if (adj == ProcessList.VISIBLE_APP_ADJ) {
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
23550 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
23551 + " reason=" + app.adjType);
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;
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;
23569 app.adjType = "backup";
23570 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23571 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app);
23573 app.cached = false;
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);
23584 boolean mayBeTop = false;
23585 String mayBeTopType = null;
23586 Object mayBeTopSource = null;
23587 Object mayBeTopTarget = null;
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);
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);
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";
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);
23625 app.cached = false;
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";
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);
23642 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
23644 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
23645 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23646 || procState > ActivityManager.PROCESS_STATE_TOP);
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.
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) {
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;
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";
23691 app.cached = false;
23693 clientProcState = procState;
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";
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
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";
23723 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
23724 |Context.BIND_IMPORTANT)) != 0) {
23725 if (clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
23726 newAdj = clientAdj;
23728 // make this service persistent
23729 newAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
23730 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23731 procState = ActivityManager.PROCESS_STATE_PERSISTENT;
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;
23744 if (adj > ProcessList.VISIBLE_APP_ADJ) {
23745 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
23750 if (!client.cached) {
23751 app.cached = false;
23753 if (adj > newAdj) {
23755 adjType = "service";
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;
23768 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
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.
23783 mayBeTopType = "service";
23784 mayBeTopSource = cr.binding.client;
23785 mayBeTopTarget = s.name;
23786 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
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) {
23794 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23795 } else if (mWakefulness
23796 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
23797 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
23800 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23803 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23807 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
23808 if (clientProcState <
23809 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23811 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23814 if (clientProcState <
23815 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
23817 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
23820 if (procState > clientProcState) {
23821 procState = clientProcState;
23822 if (adjType == null) {
23823 adjType = "service";
23826 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
23827 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
23828 app.pendingUiClean = true;
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));
23845 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
23846 app.treatLikeActivity = true;
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;
23857 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23860 app.cached = false;
23861 app.adjType = "service";
23862 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23863 .REASON_SERVICE_IN_USE;
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);
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);
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);
23888 ContentProviderConnection conn = cpr.connections.get(i);
23889 ProcessRecord client = conn.client;
23890 if (client == app) {
23891 // Being our own client is not interesting.
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) {
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;
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";
23920 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
23921 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
23922 adjType = "provider";
23924 app.cached &= client.cached;
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.
23938 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23939 mayBeTopType = adjType = "provider-top";
23940 mayBeTopSource = client;
23941 mayBeTopTarget = cpr.name;
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.
23948 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23949 if (adjType == null) {
23950 adjType = "provider";
23954 if (procState > clientProcState) {
23955 procState = clientProcState;
23957 if (client.curSchedGroup > schedGroup) {
23958 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
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));
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);
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);
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);
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);
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.
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));
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));
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";
24078 if (adj == ProcessList.SERVICE_ADJ) {
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!");
24094 mNewNumAServiceProcs++;
24095 //Slog.i(TAG, "ADJ " + app + " not high ram!");
24098 app.serviceHighRam = false;
24101 if (app.serviceb) {
24102 adj = ProcessList.SERVICE_B_ADJ;
24106 app.curRawAdj = adj;
24108 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
24109 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
24110 if (adj > app.maxAdj) {
24112 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
24113 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
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;
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;
24137 // if curAdj or curProcState improved, then this process was promoted
24138 return app.curAdj < prevAppAdj || app.curProcState < prevProcState;
24142 * Record new PSS sample for a process.
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;
24156 proc.lastPss = pss;
24157 proc.lastSwapPss = swapPss;
24158 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
24159 proc.lastCachedPss = pss;
24160 proc.lastCachedSwapPss = swapPss;
24163 final SparseArray<Pair<Long, String>> watchUids
24164 = mMemWatchProcesses.getMap().get(proc.processName);
24166 if (watchUids != null) {
24167 Pair<Long, String> val = watchUids.get(proc.uid);
24169 val = watchUids.get(0);
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;
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() {
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;
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) {
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) {
24220 } catch (FileNotFoundException e) {
24221 e.printStackTrace();
24226 } catch (IOException e) {
24233 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
24234 + ", but debugging not enabled");
24241 * Schedule PSS collection of a process.
24243 boolean requestPssLocked(ProcessRecord proc, int procState) {
24244 if (mPendingPssProcesses.contains(proc)) {
24247 if (mPendingPssProcesses.size() == 0) {
24248 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
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);
24258 * Schedule PSS collection of all processes.
24260 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
24262 if (now < (mLastFullPssTime +
24263 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
24264 : mConstants.FULL_PSS_MIN_INTERVAL))) {
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);;
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) {
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);
24293 if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) {
24294 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
24298 public void setTestPssMode(boolean enabled) {
24299 synchronized (this) {
24300 mTestPssMode = 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);
24310 * Ask a given process to GC right now.
24312 final void performAppGcLocked(ProcessRecord app) {
24314 app.lastRequestedGc = SystemClock.uptimeMillis();
24315 if (app.thread != null) {
24316 if (app.reportLowMemory) {
24317 app.reportLowMemory = false;
24318 app.thread.scheduleLowMemory();
24320 app.thread.processInBackground();
24323 } catch (Exception e) {
24329 * Returns true if things are idle enough to perform GCs.
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;
24338 return !processingBroadcasts
24339 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
24343 * Perform GCs on all processes that are waiting for it, but only
24344 * if things are idle.
24346 final void performAppGcsLocked() {
24347 final int N = mProcessesToGc.size();
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();
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);
24371 scheduleAppGcsLocked();
24376 * If all looks good, perform GCs on all processes waiting for them.
24378 final void performAppGcsIfAppropriateLocked() {
24379 if (canGcNowLocked()) {
24380 performAppGcsLocked();
24383 // Still not idle, wait some more.
24384 scheduleAppGcsLocked();
24388 * Schedule the execution of all pending app GCs.
24390 final void scheduleAppGcsLocked() {
24391 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
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);
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;
24403 mHandler.sendMessageAtTime(msg, when);
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
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) {
24418 mProcessesToGc.add(i+1, proc);
24423 mProcessesToGc.add(0, proc);
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.
24432 final void scheduleAppGcLocked(ProcessRecord app) {
24433 long now = SystemClock.uptimeMillis();
24434 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
24437 if (!mProcessesToGc.contains(app)) {
24438 addProcessToGcListLocked(app);
24439 scheduleAppGcsLocked();
24443 final void checkExcessivePowerUsageLocked() {
24444 updateCpuStatsNow();
24446 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
24447 boolean doCpuKills = true;
24448 if (mLastPowerCheckUptime == 0) {
24449 doCpuKills = false;
24451 final long curUptime = SystemClock.uptimeMillis();
24452 final long uptimeSince = curUptime - mLastPowerCheckUptime;
24453 mLastPowerCheckUptime = curUptime;
24454 int i = mLruProcesses.size();
24457 ProcessRecord app = mLruProcesses.get(i);
24458 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24459 if (app.lastCpuTime <= 0) {
24462 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
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);
24472 sb.append((cputimeUsed*100)/uptimeSince);
24474 Slog.i(TAG_POWER, sb.toString());
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?
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;
24490 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
24492 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
24493 synchronized (stats) {
24494 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
24495 uptimeSince, cputimeUsed);
24497 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
24498 + " dur=" + checkDur + " limit=" + cpuLimit, true);
24499 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
24502 app.lastCpuTime = app.curCpuTime;
24507 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
24509 boolean success = true;
24511 if (app.curRawAdj != app.setRawAdj) {
24512 app.setRawAdj = app.curRawAdj;
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);
24524 app.setAdj = app.curAdj;
24525 app.verifiedAdj = ProcessList.INVALID_ADJ;
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);
24536 if (app.waitingToKill != null && app.curReceivers.isEmpty()
24537 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
24538 app.kill(app.waitingToKill, true);
24542 switch (app.curSchedGroup) {
24543 case ProcessList.SCHED_GROUP_BACKGROUND:
24544 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
24546 case ProcessList.SCHED_GROUP_TOP_APP:
24547 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
24548 processGroup = THREAD_GROUP_TOP_APP;
24550 case ProcessList.SCHED_GROUP_RESTRICTED:
24551 processGroup = THREAD_GROUP_RESTRICTED;
24554 processGroup = THREAD_GROUP_DEFAULT;
24557 long oldId = Binder.clearCallingIdentity();
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");
24576 if (DEBUG_OOM_ADJ) {
24577 Slog.d("UI_FIFO", "Not setting RenderThread TID");
24581 // Boost priority for top app UI and render threads
24582 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
24583 if (app.renderThreadTid != 0) {
24585 setThreadPriority(app.renderThreadTid,
24586 TOP_APP_PRIORITY_BOOST);
24587 } catch (IllegalArgumentException e) {
24588 // thread died, ignore
24593 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
24594 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
24595 mVrController.onTopProcChangedLocked(app);
24596 if (mUseFifoUiScheduling) {
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,
24604 setThreadPriority(app.renderThreadTid, -4);
24606 } catch (IllegalArgumentException e) {
24608 "Failed to set scheduling policy, thread does not exist:\n"
24610 } catch (SecurityException e) {
24611 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
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);
24621 } catch (Exception e) {
24623 Slog.w(TAG, "Failed setting process group of " + app.pid
24624 + " to " + app.curSchedGroup);
24625 Slog.w(TAG, "at location", e);
24628 Binder.restoreCallingIdentity(oldId);
24632 if (app.repForegroundActivities != app.foregroundActivities) {
24633 app.repForegroundActivities = app.foregroundActivities;
24634 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
24636 if (app.repProcState != app.curProcState) {
24637 app.repProcState = app.curProcState;
24638 if (app.thread != null) {
24641 //RuntimeException h = new RuntimeException("here");
24642 Slog.i(TAG, "Sending new process state " + app.repProcState
24643 + " to " + app /*, h*/);
24645 app.thread.setProcessState(app.repProcState);
24646 } catch (RemoteException e) {
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");
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);
24676 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
24677 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
24679 if (requestPssLocked(app, app.setProcState)) {
24680 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24681 app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24683 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
24684 "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
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);
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;
24703 // Inform UsageStats of important process state change
24704 // Must be called before updating setProcState
24705 maybeUpdateUsageStatsLocked(app, nowElapsed);
24707 maybeUpdateLastTopTime(app, now);
24709 app.setProcState = app.curProcState;
24710 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24711 app.notCachedSinceIdle = false;
24714 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
24716 app.procStateChanged = true;
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);
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;
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);
24740 // No existing item in pending changes; need a new one.
24741 final int NA = mAvailProcessChanges.size();
24743 item = mAvailProcessChanges.remove(NA-1);
24744 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24745 "Retrieving available item: " + item);
24747 item = new ProcessChangeItem();
24748 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24749 "Allocating new item: " + item);
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();
24759 mPendingProcessChanges.add(item);
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);
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
24779 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
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();
24792 final int NA = mAvailUidChanges.size();
24794 pendingChange = mAvailUidChanges.remove(NA-1);
24795 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24796 "Retrieving available item: " + pendingChange);
24798 pendingChange = new UidRecord.ChangeItem();
24799 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24800 "Allocating new item: " + pendingChange);
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,
24807 change |= UidRecord.CHANGE_IDLE;
24809 } else if (uid < 0) {
24810 throw new IllegalArgumentException("No UidRecord or uid");
24812 pendingChange.uidRecord = uidRec;
24813 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
24814 mPendingUidChanges.add(pendingChange);
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));
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));
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,
24835 change |= UidRecord.CHANGE_IDLE;
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);
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);
24857 if ((change & UidRecord.CHANGE_IDLE) != 0) {
24858 mLocalPowerManager.uidIdle(pendingChange.uid);
24860 if ((change & UidRecord.CHANGE_GONE) != 0) {
24861 mLocalPowerManager.uidGone(pendingChange.uid);
24863 mLocalPowerManager.updateUidProcState(pendingChange.uid,
24864 pendingChange.processState);
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);
24883 userState.mProviderLastReportedFg.put(authority, now);
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);
24894 if (mUsageStatsService == null) {
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;
24909 isInteraction = nowElapsed > app.fgInteractionTime
24910 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
24913 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
24914 app.fgInteractionTime = 0;
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);
24927 app.reportedInteraction = isInteraction;
24928 if (!isInteraction) {
24929 app.interactionEventTime = 0;
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;
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);
24948 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
24949 ProcessRecord TOP_APP, boolean doingAll, long now) {
24950 if (app.thread == null) {
24954 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
24956 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
24960 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
24962 if (isForeground != proc.foregroundServices) {
24963 proc.foregroundServices = isForeground;
24964 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
24966 if (isForeground) {
24967 if (curProcs == null) {
24968 curProcs = new ArrayList<ProcessRecord>();
24969 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
24971 if (!curProcs.contains(proc)) {
24972 curProcs.add(proc);
24973 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
24974 proc.info.packageName, proc.info.uid);
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);
24989 updateOomAdjLocked();
24994 private final ActivityRecord resumedAppLocked() {
24995 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
24999 pkg = act.packageName;
25000 uid = act.info.applicationInfo.uid;
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);
25012 mCurResumedPackage = pkg;
25013 mCurResumedUid = uid;
25014 if (mCurResumedPackage != null) {
25015 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
25016 mCurResumedPackage, mCurResumedUid);
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.
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;
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());
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();
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();
25064 RuntimeException e = new RuntimeException();
25065 e.fillInStackTrace();
25066 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
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);
25077 mStackSupervisor.rankTaskLayersIfNeeded();
25080 mNewNumServiceProcs = 0;
25081 mNewNumAServiceProcs = 0;
25083 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
25084 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
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
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;
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;
25110 int numTrimming = 0;
25112 mNumNonCachedProcs = 0;
25113 mNumCachedHiddenProcs = 0;
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;
25122 boolean retryCycles = false;
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;
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);
25135 // if any app encountered a cycle, we need to perform an additional loop later
25136 retryCycles |= app.containsCycle;
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
25153 if (curCachedAdj != nextCachedAdj) {
25155 if (stepCached >= cachedFactor) {
25157 curCachedAdj = nextCachedAdj;
25158 nextCachedAdj += 2;
25159 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
25160 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
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
25176 if (curEmptyAdj != nextEmptyAdj) {
25178 if (stepEmpty >= emptyFactor) {
25180 curEmptyAdj = nextEmptyAdj;
25182 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
25183 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
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) {
25202 retryCycles = false;
25204 for (int i=0; i<N; i++) {
25205 ProcessRecord app = mLruProcesses.get(i);
25206 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
25208 app.completedAdjSeq--;
25212 for (int i=0; i<N; i++) {
25213 ProcessRecord app = mLruProcesses.get(i);
25214 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
25216 if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now)) {
25217 retryCycles = true;
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);
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++;
25234 if (numCached > cachedProcessLimit) {
25235 app.kill("cached #" + numCached, true);
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);
25246 if (numEmpty > emptyProcessLimit) {
25247 app.kill("empty #" + numEmpty, true);
25252 mNumNonCachedProcs++;
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);
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;
25273 if (app.foregroundServices) {
25274 uidRec.foregroundServices = true;
25279 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
25280 && !app.killedByAm) {
25286 incrementProcStateSeqAndNotifyAppsLocked();
25288 mNumServiceProcs = mNewNumServiceProcs;
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;
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;
25305 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
25308 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
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!");
25322 if (memFactor != mLastMemoryLevel) {
25323 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
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;
25335 switch (memFactor) {
25336 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
25337 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
25339 case ProcessStats.ADJ_MEM_FACTOR_LOW:
25340 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
25343 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
25346 int factor = numTrimming/3;
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;
25358 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
25359 && !app.killedByAm) {
25360 if (app.trimMemoryLevel < curLevel && app.thread != null) {
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) {
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");
25381 app.trimMemoryLevel = curLevel;
25383 if (step >= factor) {
25385 switch (curLevel) {
25386 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
25387 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
25389 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
25390 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
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) {
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) {
25407 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
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) {
25417 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25418 "Trimming memory of bg-ui " + app.processName
25420 app.thread.scheduleTrimMemory(level);
25421 } catch (RemoteException e) {
25424 app.pendingUiClean = false;
25426 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
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) {
25435 app.trimMemoryLevel = fgTrimLevel;
25439 if (mLowRamStartTime != 0) {
25440 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
25441 mLowRamStartTime = 0;
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;
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) {
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) {
25462 app.pendingUiClean = false;
25464 app.trimMemoryLevel = 0;
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");
25475 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
25478 ArrayList<UidRecord> becameIdle = null;
25480 // Update from any uid changes.
25481 if (mLocalPowerManager != null) {
25482 mLocalPowerManager.startUidChanges();
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);
25510 if (uidRec.idle && !uidRec.setIdle) {
25511 uidChange = UidRecord.CHANGE_IDLE;
25512 if (becameIdle == null) {
25513 becameIdle = new ArrayList<>();
25515 becameIdle.add(uidRec);
25519 uidChange = UidRecord.CHANGE_ACTIVE;
25520 EventLogTags.writeAmUidActive(uidRec.uid);
25521 uidRec.idle = false;
25523 uidRec.lastBackgroundTime = 0;
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;
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);
25543 if (mLocalPowerManager != null) {
25544 mLocalPowerManager.finishUidChanges();
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);
25555 if (mProcessStats.shouldWriteNowLocked(now)) {
25556 mHandler.post(new Runnable() {
25557 @Override public void run() {
25558 synchronized (ActivityManagerService.this) {
25559 mProcessStats.writeStateAsyncLocked();
25565 if (DEBUG_OOM_ADJ) {
25566 final long duration = SystemClock.uptimeMillis() - now;
25568 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
25569 new RuntimeException("here").fillInStackTrace());
25571 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
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;
25585 throw new SecurityException(msg);
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) {
25593 IPackageManager pm = AppGlobals.getPackageManager();
25596 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
25597 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
25598 } catch (RemoteException e) {
25600 if (pkgUid == -1) {
25601 throw new IllegalArgumentException("Unknown package name " + packageName);
25604 if (mLocalPowerManager != null) {
25605 mLocalPowerManager.startUidChanges();
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);
25627 if (mLocalPowerManager != null) {
25628 mLocalPowerManager.finishUidChanges();
25630 Binder.restoreCallingIdentity(callingId);
25635 final void idleUids() {
25636 synchronized (this) {
25637 final int N = mActiveUids.size();
25641 final long nowElapsed = SystemClock.elapsedRealtime();
25642 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
25644 if (mLocalPowerManager != null) {
25645 mLocalPowerManager.startUidChanges();
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);
25657 if (nextTime == 0 || nextTime > bgTime) {
25663 if (mLocalPowerManager != null) {
25664 mLocalPowerManager.finishUidChanges();
25666 if (nextTime > 0) {
25667 mHandler.removeMessages(IDLE_UIDS_MSG);
25668 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
25669 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
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.
25681 void incrementProcStateSeqAndNotifyAppsLocked() {
25682 if (mWaitForNetworkTimeoutMs <= 0) {
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)) {
25693 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
25696 // If process state is not changed, then there's nothing to do.
25697 if (uidRec.setProcState == uidRec.curProcState) {
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) {
25706 synchronized (uidRec.networkStateLock) {
25707 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
25708 if (blockState == NETWORK_STATE_BLOCK) {
25709 if (blockingUids == null) {
25710 blockingUids = new ArrayList<>();
25712 blockingUids.add(uidRec.uid);
25714 if (DEBUG_NETWORK) {
25715 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
25716 + " threads for uid: " + uidRec);
25718 if (uidRec.waitingForNetwork) {
25719 uidRec.networkStateLock.notifyAll();
25725 // There are no uids that need to block, so nothing more to do.
25726 if (blockingUids == null) {
25730 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
25731 final ProcessRecord app = mLruProcesses.get(i);
25732 if (!blockingUids.contains(app.uid)) {
25735 if (!app.killedByAm && app.thread != null) {
25736 final UidRecord uidRec = mActiveUids.get(app.uid);
25738 if (DEBUG_NETWORK) {
25739 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
25742 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
25743 } catch (RemoteException ignored) {
25750 * Checks if the uid is coming from background to foreground or vice versa and returns
25751 * appropriate block state based on this.
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}.
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);
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;
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;
25777 return NETWORK_STATE_NO_CHANGE;
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?
25786 doStopUidLocked(uidRec.uid, uidRec);
25789 // This uid isn't actually running... still send a report about it being "stopped".
25790 doStopUidLocked(uid, null);
25796 * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
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)) {
25805 final UidRecord uidRec = mActiveUids.valueAt(i);
25806 if (!uidRec.idle) {
25809 doStopUidLocked(uidRec.uid, uidRec);
25813 final void doStopUidLocked(int uid, final UidRecord uidRec) {
25814 mServices.stopInBackgroundLocked(uid);
25815 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
25819 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
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 + ")");
25829 synchronized (mPidsSelfLocked) {
25830 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
25832 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
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");
25848 tempWhitelistUidLocked(targetUid, duration, tag);
25852 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
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();
25861 void pushTempWhitelist() {
25863 final PendingTempWhitelist[] list;
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);
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);
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);
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;
25905 updateOomAdjLocked();
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();
25919 final void trimApplications() {
25920 synchronized (this) {
25921 trimApplicationsLocked();
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) {
25933 TAG, "Exiting empty application process "
25934 + app.toShortString() + " ("
25935 + (app.thread != null ? app.thread.asBinder() : null)
25937 if (app.pid > 0 && app.pid != MY_PID) {
25938 app.kill("empty", false);
25939 } else if (app.thread != null) {
25941 app.thread.scheduleExit();
25942 } catch (Exception e) {
25943 // Ignore exceptions.
25946 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
25947 mRemovedProcesses.remove(i);
25949 if (app.persistent) {
25950 addAppLocked(app.info, null, false, null /* ABI override */);
25955 // Now update the oom adj for all processes. Don't skip this, since other callers
25956 // might be depending on it.
25957 updateOomAdjLocked();
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");
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);
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);
25982 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
25983 if (proc == null || proc == mProfileProc) {
25984 proc = mProfileProc;
25985 profileType = mProfileType;
25986 clearProfilerLocked();
25988 if (proc == null) {
25992 proc.thread.profilerControl(false, null, profileType);
25993 } catch (RemoteException e) {
25994 throw new IllegalStateException("Process disappeared");
25998 private void clearProfilerLocked() {
25999 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
26001 mProfilerInfo.profileFd.close();
26002 } catch (IOException e) {
26005 mProfileApp = null;
26006 mProfileProc = null;
26007 mProfilerInfo = null;
26010 public boolean profileControl(String process, int userId, boolean start,
26011 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
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);
26023 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
26024 throw new IllegalArgumentException("null profile info or fd");
26027 ProcessRecord proc = null;
26028 if (process != null) {
26029 proc = findProcessLocked(process, userId, "profileControl");
26032 if (start && (proc == null || proc.thread == null)) {
26033 throw new IllegalArgumentException("Unknown process: " + process);
26037 stopProfilerLocked(null, 0);
26038 setProfileApp(proc.info, proc.processName, profilerInfo);
26039 mProfileProc = proc;
26040 mProfileType = profileType;
26041 ParcelFileDescriptor fd = profilerInfo.profileFd;
26044 } catch (IOException e) {
26047 profilerInfo.profileFd = fd;
26048 proc.thread.profilerControl(start, profilerInfo, profileType);
26051 mProfilerInfo.profileFd.close();
26052 } catch (IOException e) {
26054 mProfilerInfo.profileFd = null;
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;
26064 stopProfilerLocked(proc, profileType);
26065 if (profilerInfo != null && profilerInfo.profileFd != null) {
26067 profilerInfo.profileFd.close();
26068 } catch (IOException e) {
26075 } catch (RemoteException e) {
26076 throw new IllegalStateException("Process disappeared");
26078 if (profilerInfo != null && profilerInfo.profileFd != null) {
26080 profilerInfo.profileFd.close();
26081 } catch (IOException e) {
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;
26092 int pid = Integer.parseInt(process);
26093 synchronized (mPidsSelfLocked) {
26094 proc = mPidsSelfLocked.get(pid);
26096 } catch (NumberFormatException e) {
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) {
26120 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
26121 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
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);
26134 throw new IllegalArgumentException("null fd");
26137 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
26138 if (proc == null || proc.thread == null) {
26139 throw new IllegalArgumentException("Unknown process: " + process);
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);
26149 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
26153 } catch (RemoteException e) {
26154 throw new IllegalStateException("Process disappeared");
26159 } catch (IOException e) {
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()");
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());
26178 if (!Build.IS_DEBUGGABLE
26179 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26180 throw new SecurityException("Not running a debuggable build");
26182 processName = proc.processName;
26184 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
26185 throw new SecurityException("Package " + reportPackage + " is not running in "
26190 synchronized (this) {
26191 if (maxMemSize > 0) {
26192 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
26195 mMemWatchProcesses.remove(processName, uid);
26197 mMemWatchProcesses.getMap().remove(processName);
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);
26211 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
26212 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
26213 + " does not match last path " + mMemWatchDumpFile);
26216 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
26217 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
26219 // Forced gc to clean up the remnant hprof fd.
26220 Runtime.getRuntime().gc();
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) { }
26229 void onCoreSettingsChange(Bundle settings) {
26230 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
26231 ProcessRecord processRecord = mLruProcesses.get(i);
26233 if (processRecord.thread != null) {
26234 processRecord.thread.setCoreSettings(settings);
26236 } catch (RemoteException re) {
26242 // Multi-user methods
26245 * Start user, if its not already running, but don't bring it to foreground.
26248 public boolean startUserInBackground(final int userId) {
26249 return startUserInBackgroundWithListener(userId, null);
26253 public boolean startUserInBackgroundWithListener(final int userId,
26254 @Nullable IProgressListener unlockListener) {
26255 return mUserController.startUser(userId, /* foreground */ false, unlockListener);
26259 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
26260 return mUserController.unlockUser(userId, token, secret, listener);
26264 public boolean switchUser(final int targetUserId) {
26265 return mUserController.switchUser(targetUserId);
26269 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
26270 return mUserController.stopUser(userId, force, callback);
26274 public UserInfo getCurrentUser() {
26275 return mUserController.getCurrentUser();
26278 String getStartedUserState(int userId) {
26279 final UserState userState = mUserController.getStartedUserState(userId);
26280 return UserState.stateToString(userState.state);
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;
26293 throw new SecurityException(msg);
26295 return mUserController.isUserRunning(userId, flags);
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;
26307 throw new SecurityException(msg);
26309 return mUserController.getStartedUserArray();
26313 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
26314 mUserController.registerUserSwitchObserver(observer, name);
26318 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
26319 mUserController.unregisterUserSwitchObserver(observer);
26322 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
26323 if (info == null) return null;
26324 ApplicationInfo newInfo = new ApplicationInfo(info);
26325 newInfo.initForUser(userId);
26329 public boolean isUserStopped(int userId) {
26330 return mUserController.getStartedUserState(userId) == null;
26333 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
26335 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
26339 ActivityInfo info = new ActivityInfo(aInfo);
26340 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
26344 private boolean processSanityChecksLocked(ProcessRecord process) {
26345 if (process == null || process.thread == null) {
26349 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26350 if (!isDebuggable) {
26351 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
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);
26370 for (int i = 0; i < mLruProcesses.size(); i++) {
26371 ProcessRecord process = mLruProcesses.get(i);
26372 if (!processSanityChecksLocked(process)) {
26376 process.thread.startBinderTracking();
26377 } catch (RemoteException e) {
26378 Log.v(TAG, "Process disappared");
26385 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
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);
26398 throw new IllegalArgumentException("null fd");
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)) {
26408 pw.println("Traces for process: " + process.processName);
26411 TransferPipe tp = new TransferPipe();
26413 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
26414 tp.go(fd.getFileDescriptor());
26418 } catch (IOException e) {
26419 pw.println("Failure while dumping IPC traces from " + process +
26420 ". Exception: " + e);
26422 } catch (RemoteException e) {
26423 pw.println("Got a RemoteException while dumping IPC traces from " +
26424 process + ". Exception: " + e);
26435 } catch (IOException e) {
26442 final class LocalService extends ActivityManagerInternal {
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);
26453 public String checkContentProviderAccess(String authority, int userId) {
26454 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
26458 public void onWakefulnessChanged(int wakefulness) {
26459 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
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);
26470 public SleepToken acquireSleepToken(String tag, int displayId) {
26471 Preconditions.checkNotNull(tag);
26472 return ActivityManagerService.this.acquireSleepToken(tag, displayId);
26476 public ComponentName getHomeActivityForUser(int userId) {
26477 synchronized (ActivityManagerService.this) {
26478 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
26479 return homeActivity == null ? null : homeActivity.realActivity;
26484 public void onUserRemoved(int userId) {
26485 synchronized (ActivityManagerService.this) {
26486 ActivityManagerService.this.onUserStoppedLocked(userId);
26488 mBatteryStatsService.onUserRemoved(userId);
26489 mUserController.onUserRemoved(userId);
26493 public void onLocalVoiceInteractionStarted(IBinder activity,
26494 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
26495 synchronized (ActivityManagerService.this) {
26496 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
26497 voiceSession, voiceInteractor);
26502 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
26503 synchronized (ActivityManagerService.this) {
26504 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
26505 reasons, timestamp);
26510 public void notifyAppTransitionFinished() {
26511 synchronized (ActivityManagerService.this) {
26512 mStackSupervisor.notifyAppTransitionDone();
26517 public void notifyAppTransitionCancelled() {
26518 synchronized (ActivityManagerService.this) {
26519 mStackSupervisor.notifyAppTransitionDone();
26524 public List<IBinder> getTopVisibleActivities() {
26525 synchronized (ActivityManagerService.this) {
26526 return mStackSupervisor.getTopVisibleActivities();
26531 public void notifyDockedStackMinimizedChanged(boolean minimized) {
26532 synchronized (ActivityManagerService.this) {
26533 mStackSupervisor.setDockedStackMinimized(minimized);
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.
26553 } else if (app.userId == userHandle && app.foregroundActivities) {
26554 app.removed = true;
26560 final int N = procs.size();
26561 for (int i = 0; i < N; i++) {
26562 removeProcessLocked(procs.get(i), false, true, "kill all fg");
26568 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
26570 if (!(target instanceof PendingIntentRecord)) {
26571 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
26574 synchronized (ActivityManagerService.this) {
26575 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
26580 public void setDeviceIdleWhitelist(int[] allAppids, int[] exceptIdleAppids) {
26581 synchronized (ActivityManagerService.this) {
26582 mDeviceIdleWhitelist = allAppids;
26583 mDeviceIdleExceptIdleWhitelist = exceptIdleAppids;
26588 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
26589 synchronized (ActivityManagerService.this) {
26590 mDeviceIdleTempWhitelist = appids;
26591 setAppIdTempWhitelistStateLocked(changingAppId, adding);
26596 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
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 */);
26607 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
26609 Preconditions.checkNotNull(intents, "intents");
26610 final String[] resolvedTypes = new String[intents.length];
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();
26619 for (int i = 0; i < intents.length; i++) {
26621 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
26624 packageUid = AppGlobals.getPackageManager().getPackageUid(
26625 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
26626 } catch (RemoteException e) {
26627 // Shouldn't happen.
26629 Binder.restoreCallingIdentity(ident);
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 */);
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*/);
26652 public int getUidProcessState(int uid) {
26653 return getUidState(uid);
26657 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
26658 synchronized (ActivityManagerService.this) {
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 */);
26668 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
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();
26676 if (callback != null) {
26682 public boolean isSystemReady() {
26683 // no need to synchronize(this) just to read & return the value
26684 return mSystemReady;
26688 public void notifyKeyguardTrustedChanged() {
26689 synchronized (ActivityManagerService.this) {
26690 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
26691 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26697 * Sets if the given pid has an overlay UI or not.
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
26704 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
26705 synchronized (ActivityManagerService.this) {
26706 final ProcessRecord pr;
26707 synchronized (mPidsSelfLocked) {
26708 pr = mPidsSelfLocked.get(pid);
26710 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
26714 if (pr.hasOverlayUi == hasOverlayUi) {
26717 pr.hasOverlayUi = hasOverlayUi;
26718 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
26719 updateOomAdjLocked(pr, true);
26724 public void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
26725 ActivityManagerService.this.setRunningRemoteAnimation(pid, runningRemoteAnimation);
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}.
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);
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);
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);
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);
26767 if (record.waitingForNetwork) {
26768 if (DEBUG_NETWORK) {
26769 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
26770 + ", procStateSeq: " + procStateSeq);
26772 record.networkStateLock.notifyAll();
26778 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
26779 synchronized (ActivityManagerService.this) {
26780 mActiveVoiceInteractionServiceComponent = component;
26785 * Called after virtual display Id is updated by
26786 * {@link com.android.server.vr.Vr2dDisplay} with a specific
26787 * {@param vrVr2dDisplayId}.
26790 public void setVr2dDisplayId(int vr2dDisplayId) {
26792 Slog.d(TAG, "setVr2dDisplayId called for: " +
26795 synchronized (ActivityManagerService.this) {
26796 mVr2dDisplayId = vr2dDisplayId;
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);
26810 mActivityStartController.dump(pw, " ", null);
26812 pw.println("-------------------------------------------------------------------------------");
26813 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
26814 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
26819 mLastANRState = sw.toString();
26824 public void clearSavedANRState() {
26825 synchronized (ActivityManagerService.this) {
26826 mLastANRState = null;
26831 public void setFocusedActivity(IBinder token) {
26832 synchronized (ActivityManagerService.this) {
26833 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
26835 throw new IllegalArgumentException(
26836 "setFocusedActivity: No activity record matching token=" + token);
26838 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
26839 r, "setFocusedActivity")) {
26840 mStackSupervisor.resumeFocusedStackTopActivityLocked();
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) {
26854 types = new ArrayMap<>();
26855 mAllowAppSwitchUids.put(userId, types);
26858 types.remove(type);
26860 types.put(type, uid);
26867 public boolean isRuntimeRestarted() {
26868 return mSystemServiceManager.isRuntimeRestarted();
26872 public boolean hasRunningActivity(int uid, @Nullable String packageName) {
26873 if (packageName == null) return false;
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)) {
26892 public void registerScreenObserver(ScreenObserver observer) {
26893 mScreenObservers.add(observer);
26897 public boolean canStartMoreUsers() {
26898 return mUserController.canStartMoreUsers();
26902 public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
26903 mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
26907 public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
26908 mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
26912 public int getMaxRunningUsers() {
26913 return mUserController.mMaxRunningUsers;
26917 public boolean isCallerRecents(int callingUid) {
26918 return getRecentTasks().isCallerRecents(callingUid);
26922 public boolean isRecentsComponentHomeActivity(int userId) {
26923 return getRecentTasks().isRecentsComponentHomeActivity(userId);
26927 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
26928 ActivityManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
26932 public boolean isUidActive(int uid) {
26933 synchronized (ActivityManagerService.this) {
26934 return isUidActiveLocked(uid);
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) {
26950 ProcessMemoryState processMemoryState =
26951 new ProcessMemoryState(uid,
26954 memoryStat.pgfault,
26955 memoryStat.pgmajfault,
26956 memoryStat.rssInBytes,
26957 memoryStat.cacheInBytes,
26958 memoryStat.swapInBytes);
26959 processMemoryStates.add(processMemoryState);
26962 return processMemoryStates;
26966 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
26967 ActivityManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
26971 public Intent getHomeIntent() {
26972 synchronized (ActivityManagerService.this) {
26973 return ActivityManagerService.this.getHomeIntent();
26978 public void notifyDefaultDisplaySizeChanged() {
26979 synchronized (ActivityManagerService.this) {
26980 if (mSystemServiceManager.isBootCompleted() && mHomeProcess != null) {
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");
26991 * Called by app main thread to wait for the network policy rules to get updated.
26993 * @param procStateSeq The sequence number indicating the process state change that the main
26994 * thread is interested in.
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);
27003 synchronized (this) {
27004 record = mActiveUids.get(callingUid);
27005 if (record == null) {
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);
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);
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);
27037 if (DEBUG_NETWORK) {
27038 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
27039 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
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));
27052 } catch (InterruptedException e) {
27053 Thread.currentThread().interrupt();
27058 public void waitForBroadcastIdle(PrintWriter pw) {
27059 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
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...";
27075 final String msg = "All broadcast queues are idle!";
27081 SystemClock.sleep(1000);
27087 * Return the user id of the last resumed activity.
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();
27097 return mLastResumedActivity.userId;
27102 * Kill processes for the user with id userId and that depend on the package named packageName
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.");
27112 long callingId = Binder.clearCallingIdentity();
27113 IPackageManager pm = AppGlobals.getPackageManager();
27116 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
27117 } catch (RemoteException e) {
27119 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
27120 throw new IllegalArgumentException(
27121 "Cannot kill dependents of non-existing package " + packageName);
27124 synchronized(this) {
27125 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
27126 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
27127 "dep: " + packageName);
27130 Binder.restoreCallingIdentity(callingId);
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()");
27141 final long callingId = Binder.clearCallingIdentity();
27143 mKeyguardController.dismissKeyguard(token, callback, message);
27145 Binder.restoreCallingIdentity(callingId);
27150 public int restartUserInBackground(final int userId) {
27151 return mUserController.restartUser(userId, /* foreground */ false);
27155 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
27156 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
27157 "scheduleApplicationInfoChanged()");
27159 synchronized (this) {
27160 final long origId = Binder.clearCallingIdentity();
27162 updateApplicationInfoLocked(packageNames, userId);
27164 Binder.restoreCallingIdentity(origId);
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) {
27177 if (userId != UserHandle.USER_ALL && app.userId != userId) {
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)) {
27186 final ApplicationInfo ai = AppGlobals.getPackageManager()
27187 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
27189 app.thread.scheduleApplicationInfoChanged(ai);
27191 } catch (RemoteException e) {
27192 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
27193 packageName, app));
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);
27207 if (mWindowManager != null) {
27208 executor.execute(mWindowManager::onOverlayChanged);
27214 * Attach an agent to the specified process (proces name or PID)
27216 public void attachAgent(String process, String path) {
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);
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);
27231 proc.thread.attachAgent(path);
27233 } catch (RemoteException e) {
27234 throw new IllegalStateException("Process disappeared");
27239 public static class Injector {
27240 private NetworkManagementInternal mNmi;
27242 public Context getContext() {
27246 public AppOpsService getAppOpsService(File file, Handler handler) {
27247 return new AppOpsService(file, handler);
27250 public Handler getUiHandler(ActivityManagerService service) {
27251 return service.new UiHandler();
27254 public boolean isNetworkRestrictedForUid(int uid) {
27255 if (ensureHasNetworkManagementInternal()) {
27256 return mNmi.isNetworkRestrictedForUid(uid);
27261 private boolean ensureHasNetworkManagementInternal() {
27262 if (mNmi == null) {
27263 mNmi = LocalServices.getService(NetworkManagementInternal.class);
27265 return mNmi != null;
27270 public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
27271 throws RemoteException {
27272 synchronized (this) {
27273 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27277 final long origId = Binder.clearCallingIdentity();
27279 r.setShowWhenLocked(showWhenLocked);
27281 Binder.restoreCallingIdentity(origId);
27287 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
27288 synchronized (this) {
27289 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27293 final long origId = Binder.clearCallingIdentity();
27295 r.setTurnScreenOn(turnScreenOn);
27297 Binder.restoreCallingIdentity(origId);
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);
27313 final long origId = Binder.clearCallingIdentity();
27315 r.registerRemoteAnimations(definition);
27317 Binder.restoreCallingIdentity(origId);
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();
27331 mActivityStartController.registerRemoteAnimationForNextActivityStart(packageName,
27334 Binder.restoreCallingIdentity(origId);
27339 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
27341 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
27342 synchronized (this) {
27343 final long origId = Binder.clearCallingIdentity();
27345 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
27347 Binder.restoreCallingIdentity(origId);