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 || UserHandle.isIsolated(procUid)) {
4000 // Don't use an app process or different user process for system component.
4003 return procs.valueAt(i);
4006 ProcessRecord proc = mProcessNames.get(processName, uid);
4007 if (false && proc != null && !keepIfLarge
4008 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
4009 && proc.lastCachedPss >= 4000) {
4010 // Turn this condition on to cause killing to happen regularly, for testing.
4011 if (proc.baseProcessTracker != null) {
4012 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
4014 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
4015 } else if (proc != null && !keepIfLarge
4016 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
4017 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
4018 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
4019 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
4020 if (proc.baseProcessTracker != null) {
4021 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
4023 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
4029 void notifyPackageUse(String packageName, int reason) {
4030 synchronized(this) {
4031 getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
4035 boolean isNextTransitionForward() {
4036 int transit = mWindowManager.getPendingAppTransition();
4037 return transit == TRANSIT_ACTIVITY_OPEN
4038 || transit == TRANSIT_TASK_OPEN
4039 || transit == TRANSIT_TASK_TO_FRONT;
4042 boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
4043 String processName, String abiOverride, int uid, Runnable crashHandler) {
4044 synchronized(this) {
4045 ApplicationInfo info = new ApplicationInfo();
4046 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
4047 // For isolated processes, the former contains the parent's uid and the latter the
4048 // actual uid of the isolated process.
4049 // In the special case introduced by this method (which is, starting an isolated
4050 // process directly from the SystemServer without an actual parent app process) the
4051 // closest thing to a parent's uid is SYSTEM_UID.
4052 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
4053 // the |isolated| logic in the ProcessRecord constructor.
4054 info.uid = SYSTEM_UID;
4055 info.processName = processName;
4056 info.className = entryPoint;
4057 info.packageName = "android";
4058 info.seInfoUser = SELinuxUtil.COMPLETE_STR;
4059 info.targetSdkVersion = Build.VERSION.SDK_INT;
4060 ProcessRecord proc = startProcessLocked(processName, info /* info */,
4061 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
4062 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
4063 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
4065 return proc != null;
4070 final ProcessRecord startProcessLocked(String processName,
4071 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
4072 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
4073 boolean isolated, boolean keepIfLarge) {
4074 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
4075 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
4076 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
4077 null /* crashHandler */);
4081 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
4082 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
4083 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
4084 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
4085 long startTime = SystemClock.elapsedRealtime();
4088 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
4089 checkTime(startTime, "startProcess: after getProcessRecord");
4091 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
4092 // If we are in the background, then check to see if this process
4093 // is bad. If so, we will just silently fail.
4094 if (mAppErrors.isBadProcessLocked(info)) {
4095 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
4096 + "/" + info.processName);
4100 // When the user is explicitly starting a process, then clear its
4101 // crash count so that we won't make it bad until they see at
4102 // least one crash dialog again, and make the process good again
4103 // if it had been bad.
4104 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
4105 + "/" + info.processName);
4106 mAppErrors.resetProcessCrashTimeLocked(info);
4107 if (mAppErrors.isBadProcessLocked(info)) {
4108 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
4109 UserHandle.getUserId(info.uid), info.uid,
4111 mAppErrors.clearBadProcessLocked(info);
4118 // If this is an isolated process, it can't re-use an existing process.
4122 // We don't have to do anything more if:
4123 // (1) There is an existing application record; and
4124 // (2) The caller doesn't think it is dead, OR there is no thread
4125 // object attached to it so we know it couldn't have crashed; and
4126 // (3) There is a pid assigned to it, so it is either starting or
4128 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
4129 + " app=" + app + " knownToBeDead=" + knownToBeDead
4130 + " thread=" + (app != null ? app.thread : null)
4131 + " pid=" + (app != null ? app.pid : -1));
4132 if (app != null && app.pid > 0) {
4133 if ((!knownToBeDead && !app.killed) || app.thread == null) {
4134 // We already have the app running, or are waiting for it to
4135 // come up (we have a pid but not yet its thread), so keep it.
4136 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
4137 // If this is a new package in the process, add the package to the list
4138 app.addPackage(info.packageName, info.versionCode, mProcessStats);
4139 checkTime(startTime, "startProcess: done, added package to proc");
4143 // An application record is attached to a previous process,
4145 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
4146 checkTime(startTime, "startProcess: bad proc running, killing");
4147 killProcessGroup(app.uid, app.pid);
4148 handleAppDiedLocked(app, true, true);
4149 checkTime(startTime, "startProcess: done killing old proc");
4152 String hostingNameStr = hostingName != null
4153 ? hostingName.flattenToShortString() : null;
4156 checkTime(startTime, "startProcess: creating new process record");
4157 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
4159 Slog.w(TAG, "Failed making new process record for "
4160 + processName + "/" + info.uid + " isolated=" + isolated);
4163 app.crashHandler = crashHandler;
4164 app.isolatedEntryPoint = entryPoint;
4165 app.isolatedEntryPointArgs = entryPointArgs;
4166 checkTime(startTime, "startProcess: done creating new process record");
4168 // If this is a new package in the process, add the package to the list
4169 app.addPackage(info.packageName, info.versionCode, mProcessStats);
4170 checkTime(startTime, "startProcess: added package to existing proc");
4173 // If the system is not ready yet, then hold off on starting this
4174 // process until it is.
4175 if (!mProcessesReady
4176 && !isAllowedWhileBooting(info)
4177 && !allowWhileBooting) {
4178 if (!mProcessesOnHold.contains(app)) {
4179 mProcessesOnHold.add(app);
4181 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
4182 "System not ready, putting on hold: " + app);
4183 checkTime(startTime, "startProcess: returning with proc on hold");
4187 checkTime(startTime, "startProcess: stepping in to startProcess");
4188 final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
4189 checkTime(startTime, "startProcess: done starting proc!");
4190 return success ? app : null;
4193 boolean isAllowedWhileBooting(ApplicationInfo ai) {
4194 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
4198 private final void startProcessLocked(ProcessRecord app,
4199 String hostingType, String hostingNameStr) {
4200 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
4204 private final boolean startProcessLocked(ProcessRecord app,
4205 String hostingType, String hostingNameStr, String abiOverride) {
4206 return startProcessLocked(app, hostingType, hostingNameStr,
4207 false /* disableHiddenApiChecks */, abiOverride);
4211 * @return {@code true} if process start is successful, false otherwise.
4214 private final boolean startProcessLocked(ProcessRecord app, String hostingType,
4215 String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
4216 if (app.pendingStart) {
4219 long startTime = SystemClock.elapsedRealtime();
4220 if (app.pid > 0 && app.pid != MY_PID) {
4221 checkTime(startTime, "startProcess: removing from pids map");
4222 synchronized (mPidsSelfLocked) {
4223 mPidsSelfLocked.remove(app.pid);
4224 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4226 checkTime(startTime, "startProcess: done removing from pids map");
4231 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
4232 "startProcessLocked removing on hold: " + app);
4233 mProcessesOnHold.remove(app);
4235 checkTime(startTime, "startProcess: starting to update cpu stats");
4237 checkTime(startTime, "startProcess: done updating cpu stats");
4241 final int userId = UserHandle.getUserId(app.uid);
4242 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
4243 } catch (RemoteException e) {
4244 throw e.rethrowAsRuntimeException();
4249 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
4250 if (!app.isolated) {
4251 int[] permGids = null;
4253 checkTime(startTime, "startProcess: getting gids from package manager");
4254 final IPackageManager pm = AppGlobals.getPackageManager();
4255 permGids = pm.getPackageGids(app.info.packageName,
4256 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
4257 StorageManagerInternal storageManagerInternal = LocalServices.getService(
4258 StorageManagerInternal.class);
4259 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
4260 app.info.packageName);
4261 } catch (RemoteException e) {
4262 throw e.rethrowAsRuntimeException();
4266 * Add shared application and profile GIDs so applications can share some
4267 * resources like shared libraries and access user-wide resources
4269 if (ArrayUtils.isEmpty(permGids)) {
4272 gids = new int[permGids.length + 3];
4273 System.arraycopy(permGids, 0, gids, 3, permGids.length);
4275 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
4276 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
4277 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
4279 // Replace any invalid GIDs
4280 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
4281 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
4283 checkTime(startTime, "startProcess: building args");
4284 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
4285 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4286 && mTopComponent != null
4287 && app.processName.equals(mTopComponent.getPackageName())) {
4290 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
4291 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
4295 int runtimeFlags = 0;
4296 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4297 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
4298 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
4299 // Also turn on CheckJNI for debuggable apps. It's quite
4300 // awkward to turn on otherwise.
4301 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4303 // Run the app in safe mode if its manifest requests so or the
4304 // system is booted in safe mode.
4305 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
4306 mSafeMode == true) {
4307 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
4309 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4310 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4312 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4313 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
4314 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4316 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
4317 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
4318 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
4320 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4321 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4323 if ("1".equals(SystemProperties.get("debug.assert"))) {
4324 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
4326 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
4327 // Enable all debug flags required by the native debugger.
4328 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
4329 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
4330 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
4331 mNativeDebuggingApp = null;
4334 if (app.info.isPrivilegedApp() &&
4335 DexManager.isPackageSelectedToRunOob(app.pkgList.keySet())) {
4336 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
4339 if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) {
4340 app.info.maybeUpdateHiddenApiEnforcementPolicy(
4341 mHiddenApiBlacklist.getPolicyForPrePApps(),
4342 mHiddenApiBlacklist.getPolicyForPApps());
4343 @HiddenApiEnforcementPolicy int policy =
4344 app.info.getHiddenApiEnforcementPolicy();
4345 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
4346 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
4347 throw new IllegalStateException("Invalid API policy: " + policy);
4349 runtimeFlags |= policyBits;
4352 String invokeWith = null;
4353 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4354 // Debuggable apps may include a wrapper script with their library directory.
4355 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
4356 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4358 if (new File(wrapperFileName).exists()) {
4359 invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4362 StrictMode.setThreadPolicy(oldPolicy);
4366 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4367 if (requiredAbi == null) {
4368 requiredAbi = Build.SUPPORTED_ABIS[0];
4371 String instructionSet = null;
4372 if (app.info.primaryCpuAbi != null) {
4373 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4377 app.requiredAbi = requiredAbi;
4378 app.instructionSet = instructionSet;
4380 // the per-user SELinux context must be set
4381 if (TextUtils.isEmpty(app.info.seInfoUser)) {
4382 Slog.wtf(TAG, "SELinux tag not defined",
4383 new IllegalStateException("SELinux tag not defined for "
4384 + app.info.packageName + " (uid " + app.uid + ")"));
4386 final String seInfo = app.info.seInfo
4387 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
4388 // Start the process. It will either succeed and return a result containing
4389 // the PID of the new process, or else throw a RuntimeException.
4390 final String entryPoint = "android.app.ActivityThread";
4392 return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4393 runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4395 } catch (RuntimeException e) {
4396 Slog.e(TAG, "Failure starting process " + app.processName, e);
4398 // Something went very wrong while trying to start this process; one
4399 // common case is when the package is frozen due to an active
4400 // upgrade. To recover, clean up any active bookkeeping related to
4401 // starting this process. (We already invoked this method once when
4402 // the package was initially frozen through KILL_APPLICATION_MSG, so
4403 // it doesn't hurt to use it again.)
4404 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4405 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4411 private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4412 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4413 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4415 app.pendingStart = true;
4416 app.killedByAm = false;
4417 app.removed = false;
4419 if (app.startSeq != 0) {
4420 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
4421 + " with non-zero startSeq:" + app.startSeq);
4424 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
4425 + " with non-zero pid:" + app.pid);
4427 final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4428 app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4429 if (mConstants.FLAG_PROCESS_START_ASYNC) {
4430 if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4431 "Posting procStart msg for " + app.toShortString());
4432 mProcStartHandler.post(() -> {
4434 synchronized (ActivityManagerService.this) {
4435 final String reason = isProcStartValidLocked(app, startSeq);
4436 if (reason != null) {
4437 Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4438 + " don't start process, " + reason);
4439 app.pendingStart = false;
4442 app.usingWrapper = invokeWith != null
4443 || SystemProperties.get("wrap." + app.processName) != null;
4444 mPendingStarts.put(startSeq, app);
4446 final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4447 app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4448 requiredAbi, instructionSet, invokeWith, app.startTime);
4449 synchronized (ActivityManagerService.this) {
4450 handleProcessStartedLocked(app, startResult, startSeq);
4452 } catch (RuntimeException e) {
4453 synchronized (ActivityManagerService.this) {
4454 Slog.e(TAG, "Failure starting process " + app.processName, e);
4455 mPendingStarts.remove(startSeq);
4456 app.pendingStart = false;
4457 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4458 false, false, true, false, false,
4459 UserHandle.getUserId(app.userId), "start failure");
4466 final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4467 uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4468 invokeWith, startTime);
4469 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4471 } catch (RuntimeException e) {
4472 Slog.e(TAG, "Failure starting process " + app.processName, e);
4473 app.pendingStart = false;
4474 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4475 false, false, true, false, false,
4476 UserHandle.getUserId(app.userId), "start failure");
4482 private ProcessStartResult startProcess(String hostingType, String entryPoint,
4483 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4484 String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4487 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4489 checkTime(startTime, "startProcess: asking zygote to start proc");
4490 final ProcessStartResult startResult;
4491 if (hostingType.equals("webview_service")) {
4492 startResult = startWebView(entryPoint,
4493 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4494 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4495 app.info.dataDir, null,
4496 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4498 startResult = Process.start(entryPoint,
4499 app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4500 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4501 app.info.dataDir, invokeWith,
4502 new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4504 checkTime(startTime, "startProcess: returned from zygote!");
4507 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4512 private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4513 StringBuilder sb = null;
4514 if (app.killedByAm) {
4515 if (sb == null) sb = new StringBuilder();
4516 sb.append("killedByAm=true;");
4518 if (mProcessNames.get(app.processName, app.uid) != app) {
4519 if (sb == null) sb = new StringBuilder();
4520 sb.append("No entry in mProcessNames;");
4522 if (!app.pendingStart) {
4523 if (sb == null) sb = new StringBuilder();
4524 sb.append("pendingStart=false;");
4526 if (app.startSeq > expectedStartSeq) {
4527 if (sb == null) sb = new StringBuilder();
4528 sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4530 return sb == null ? null : sb.toString();
4534 private boolean handleProcessStartedLocked(ProcessRecord pending,
4535 ProcessStartResult startResult, long expectedStartSeq) {
4536 // Indicates that this process start has been taken care of.
4537 if (mPendingStarts.get(expectedStartSeq) == null) {
4538 if (pending.pid == startResult.pid) {
4539 pending.usingWrapper = startResult.usingWrapper;
4540 // TODO: Update already existing clients of usingWrapper
4544 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4545 expectedStartSeq, false);
4549 private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4550 long expectedStartSeq, boolean procAttached) {
4551 mPendingStarts.remove(expectedStartSeq);
4552 final String reason = isProcStartValidLocked(app, expectedStartSeq);
4553 if (reason != null) {
4554 Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4556 app.pendingStart = false;
4557 Process.killProcessQuiet(pid);
4558 Process.killProcessGroup(app.uid, app.pid);
4561 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4562 checkTime(app.startTime, "startProcess: done updating battery stats");
4564 EventLog.writeEvent(EventLogTags.AM_PROC_START,
4565 UserHandle.getUserId(app.startUid), pid, app.startUid,
4566 app.processName, app.hostingType,
4567 app.hostingNameStr != null ? app.hostingNameStr : "");
4570 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4571 app.seInfo, app.info.sourceDir, pid);
4572 } catch (RemoteException ex) {
4576 if (app.persistent) {
4577 Watchdog.getInstance().processStarted(app.processName, pid);
4580 checkTime(app.startTime, "startProcess: building log message");
4581 StringBuilder buf = mStringBuilder;
4583 buf.append("Start proc ");
4586 buf.append(app.processName);
4588 UserHandle.formatUid(buf, app.startUid);
4589 if (app.isolatedEntryPoint != null) {
4591 buf.append(app.isolatedEntryPoint);
4594 buf.append(" for ");
4595 buf.append(app.hostingType);
4596 if (app.hostingNameStr != null) {
4598 buf.append(app.hostingNameStr);
4600 reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
4602 app.usingWrapper = usingWrapper;
4603 app.pendingStart = false;
4604 checkTime(app.startTime, "startProcess: starting to update pids map");
4605 ProcessRecord oldApp;
4606 synchronized (mPidsSelfLocked) {
4607 oldApp = mPidsSelfLocked.get(pid);
4609 // If there is already an app occupying that pid that hasn't been cleaned up
4610 if (oldApp != null && !app.isolated) {
4611 // Clean up anything relating to this pid first
4612 Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName
4613 + " startSeq:" + app.startSeq
4615 + " belongs to another existing app:" + oldApp.processName
4616 + " startSeq:" + oldApp.startSeq);
4617 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4618 true /*replacingPid*/);
4620 synchronized (mPidsSelfLocked) {
4621 this.mPidsSelfLocked.put(pid, app);
4622 if (!procAttached) {
4623 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4625 mHandler.sendMessageDelayed(msg, usingWrapper
4626 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4629 checkTime(app.startTime, "startProcess: done updating pids map");
4633 void updateUsageStats(ActivityRecord component, boolean resumed) {
4634 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4635 "updateUsageStats: comp=" + component + "res=" + resumed);
4636 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4637 StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4638 component.app.uid, component.realActivity.getPackageName(),
4639 component.realActivity.getShortClassName(), resumed ?
4640 StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND :
4641 StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND);
4643 if (mUsageStatsService != null) {
4644 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4645 UsageEvents.Event.MOVE_TO_FOREGROUND);
4648 synchronized (stats) {
4649 stats.noteActivityResumedLocked(component.app.uid);
4652 if (mUsageStatsService != null) {
4653 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4654 UsageEvents.Event.MOVE_TO_BACKGROUND);
4656 synchronized (stats) {
4657 stats.noteActivityPausedLocked(component.app.uid);
4662 Intent getHomeIntent() {
4663 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4664 intent.setComponent(mTopComponent);
4665 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4666 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4667 intent.addCategory(Intent.CATEGORY_HOME);
4672 boolean startHomeActivityLocked(int userId, String reason) {
4673 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4674 && mTopAction == null) {
4675 // We are running in factory test mode, but unable to find
4676 // the factory test app, so just sit around displaying the
4677 // error message and don't try to start anything.
4680 Intent intent = getHomeIntent();
4681 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4682 if (aInfo != null) {
4683 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4684 // Don't do this if the home app is currently being
4686 aInfo = new ActivityInfo(aInfo);
4687 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4688 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4689 aInfo.applicationInfo.uid, true);
4690 if (app == null || app.instr == null) {
4691 intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4692 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4693 // For ANR debugging to verify if the user activity is the one that actually
4695 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4696 mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4699 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4705 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4706 ActivityInfo ai = null;
4707 ComponentName comp = intent.getComponent();
4711 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4713 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4715 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4719 ai = info.activityInfo;
4722 } catch (RemoteException e) {
4729 boolean getCheckedForSetup() {
4730 return mCheckedForSetup;
4733 void setCheckedForSetup(boolean checked) {
4734 mCheckedForSetup = checked;
4737 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4738 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4741 void enforceNotIsolatedCaller(String caller) {
4742 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4743 throw new SecurityException("Isolated process not allowed to call " + caller);
4748 public int getFrontActivityScreenCompatMode() {
4749 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4750 synchronized (this) {
4751 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4756 public void setFrontActivityScreenCompatMode(int mode) {
4757 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4758 "setFrontActivityScreenCompatMode");
4759 synchronized (this) {
4760 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4765 public int getPackageScreenCompatMode(String packageName) {
4766 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4767 synchronized (this) {
4768 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4773 public void setPackageScreenCompatMode(String packageName, int mode) {
4774 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4775 "setPackageScreenCompatMode");
4776 synchronized (this) {
4777 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4782 public boolean getPackageAskScreenCompat(String packageName) {
4783 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4784 synchronized (this) {
4785 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4790 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4791 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4792 "setPackageAskScreenCompat");
4793 synchronized (this) {
4794 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4798 private boolean hasUsageStatsPermission(String callingPackage) {
4799 final int mode = mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS,
4800 Binder.getCallingUid(), callingPackage);
4801 if (mode == AppOpsManager.MODE_DEFAULT) {
4802 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4803 == PackageManager.PERMISSION_GRANTED;
4805 return mode == AppOpsManager.MODE_ALLOWED;
4809 public int getPackageProcessState(String packageName, String callingPackage) {
4810 if (!hasUsageStatsPermission(callingPackage)) {
4811 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4812 "getPackageProcessState");
4815 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4816 synchronized (this) {
4817 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4818 final ProcessRecord proc = mLruProcesses.get(i);
4819 if (procState > proc.setProcState) {
4820 if (proc.pkgList.containsKey(packageName) ||
4821 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4822 procState = proc.setProcState;
4831 public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4832 throws RemoteException {
4833 synchronized (this) {
4834 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4836 throw new IllegalArgumentException("Unknown process: " + process);
4838 if (app.thread == null) {
4839 throw new IllegalArgumentException("Process has no app thread");
4841 if (app.trimMemoryLevel >= level) {
4842 throw new IllegalArgumentException(
4843 "Unable to set a higher trim level than current level");
4845 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4846 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4847 throw new IllegalArgumentException("Unable to set a background trim level "
4848 + "on a foreground process");
4850 app.thread.scheduleTrimMemory(level);
4851 app.trimMemoryLevel = level;
4856 private void dispatchProcessesChanged() {
4858 synchronized (this) {
4859 N = mPendingProcessChanges.size();
4860 if (mActiveProcessChanges.length < N) {
4861 mActiveProcessChanges = new ProcessChangeItem[N];
4863 mPendingProcessChanges.toArray(mActiveProcessChanges);
4864 mPendingProcessChanges.clear();
4865 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4866 "*** Delivering " + N + " process changes");
4869 int i = mProcessObservers.beginBroadcast();
4872 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4873 if (observer != null) {
4875 for (int j=0; j<N; j++) {
4876 ProcessChangeItem item = mActiveProcessChanges[j];
4877 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4878 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4879 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4880 + item.uid + ": " + item.foregroundActivities);
4881 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4882 item.foregroundActivities);
4885 } catch (RemoteException e) {
4889 mProcessObservers.finishBroadcast();
4891 synchronized (this) {
4892 for (int j=0; j<N; j++) {
4893 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4898 private void dispatchProcessDied(int pid, int uid) {
4899 int i = mProcessObservers.beginBroadcast();
4902 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4903 if (observer != null) {
4905 observer.onProcessDied(pid, uid);
4906 } catch (RemoteException e) {
4910 mProcessObservers.finishBroadcast();
4914 void dispatchUidsChanged() {
4916 synchronized (this) {
4917 N = mPendingUidChanges.size();
4918 if (mActiveUidChanges.length < N) {
4919 mActiveUidChanges = new UidRecord.ChangeItem[N];
4921 for (int i=0; i<N; i++) {
4922 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4923 mActiveUidChanges[i] = change;
4924 if (change.uidRecord != null) {
4925 change.uidRecord.pendingChange = null;
4926 change.uidRecord = null;
4929 mPendingUidChanges.clear();
4930 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4931 "*** Delivering " + N + " uid changes");
4934 mUidChangeDispatchCount += N;
4935 int i = mUidObservers.beginBroadcast();
4938 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4939 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4941 mUidObservers.finishBroadcast();
4943 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4944 for (int j = 0; j < N; ++j) {
4945 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4946 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4947 mValidateUids.remove(item.uid);
4949 UidRecord validateUid = mValidateUids.get(item.uid);
4950 if (validateUid == null) {
4951 validateUid = new UidRecord(item.uid);
4952 mValidateUids.put(item.uid, validateUid);
4954 if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4955 validateUid.idle = true;
4956 } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4957 validateUid.idle = false;
4959 validateUid.curProcState = validateUid.setProcState = item.processState;
4960 validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4965 synchronized (this) {
4966 for (int j = 0; j < N; j++) {
4967 mAvailUidChanges.add(mActiveUidChanges[j]);
4972 private void dispatchUidsChangedForObserver(IUidObserver observer,
4973 UidObserverRegistration reg, int changesSize) {
4974 if (observer == null) {
4978 for (int j = 0; j < changesSize; j++) {
4979 UidRecord.ChangeItem item = mActiveUidChanges[j];
4980 final int change = item.change;
4981 if (change == UidRecord.CHANGE_PROCSTATE &&
4982 (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4983 // No-op common case: no significant change, the observer is not
4984 // interested in all proc state changes.
4987 final long start = SystemClock.uptimeMillis();
4988 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4989 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4990 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4991 "UID idle uid=" + item.uid);
4992 observer.onUidIdle(item.uid, item.ephemeral);
4994 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4995 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4996 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4997 "UID active uid=" + item.uid);
4998 observer.onUidActive(item.uid);
5001 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
5002 if ((change & UidRecord.CHANGE_CACHED) != 0) {
5003 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5004 "UID cached uid=" + item.uid);
5005 observer.onUidCachedChanged(item.uid, true);
5006 } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
5007 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5008 "UID active uid=" + item.uid);
5009 observer.onUidCachedChanged(item.uid, false);
5012 if ((change & UidRecord.CHANGE_GONE) != 0) {
5013 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
5014 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5015 "UID gone uid=" + item.uid);
5016 observer.onUidGone(item.uid, item.ephemeral);
5018 if (reg.lastProcStates != null) {
5019 reg.lastProcStates.delete(item.uid);
5022 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
5023 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5024 "UID CHANGED uid=" + item.uid
5025 + ": " + item.processState);
5026 boolean doReport = true;
5027 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
5028 final int lastState = reg.lastProcStates.get(item.uid,
5029 ActivityManager.PROCESS_STATE_UNKNOWN);
5030 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
5031 final boolean lastAboveCut = lastState <= reg.cutpoint;
5032 final boolean newAboveCut = item.processState <= reg.cutpoint;
5033 doReport = lastAboveCut != newAboveCut;
5035 doReport = item.processState
5036 != ActivityManager.PROCESS_STATE_NONEXISTENT;
5040 if (reg.lastProcStates != null) {
5041 reg.lastProcStates.put(item.uid, item.processState);
5043 observer.onUidStateChanged(item.uid, item.processState,
5048 final int duration = (int) (SystemClock.uptimeMillis() - start);
5049 if (reg.mMaxDispatchTime < duration) {
5050 reg.mMaxDispatchTime = duration;
5052 if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
5053 reg.mSlowDispatchCount++;
5056 } catch (RemoteException e) {
5060 void dispatchOomAdjObserver(String msg) {
5061 OomAdjObserver observer;
5062 synchronized (this) {
5063 observer = mCurOomAdjObserver;
5066 if (observer != null) {
5067 observer.onOomAdjMessage(msg);
5071 void setOomAdjObserver(int uid, OomAdjObserver observer) {
5072 synchronized (this) {
5073 mCurOomAdjUid = uid;
5074 mCurOomAdjObserver = observer;
5078 void clearOomAdjObserver() {
5079 synchronized (this) {
5081 mCurOomAdjObserver = null;
5085 void reportOomAdjMessageLocked(String tag, String msg) {
5087 if (mCurOomAdjObserver != null) {
5088 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
5092 void reportUidInfoMessageLocked(String tag, String msg, int uid) {
5094 if (mCurOomAdjObserver != null && uid == mCurOomAdjUid) {
5095 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
5101 public final int startActivity(IApplicationThread caller, String callingPackage,
5102 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5103 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
5104 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
5105 resultWho, requestCode, startFlags, profilerInfo, bOptions,
5106 UserHandle.getCallingUserId());
5110 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
5111 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5112 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5113 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
5114 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
5115 true /*validateIncomingUser*/);
5118 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
5119 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5120 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
5121 boolean validateIncomingUser) {
5122 enforceNotIsolatedCaller("startActivity");
5124 userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
5125 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
5127 // TODO: Switch to user app stacks here.
5128 return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
5130 .setCallingPackage(callingPackage)
5131 .setResolvedType(resolvedType)
5132 .setResultTo(resultTo)
5133 .setResultWho(resultWho)
5134 .setRequestCode(requestCode)
5135 .setStartFlags(startFlags)
5136 .setProfilerInfo(profilerInfo)
5137 .setActivityOptions(bOptions)
5144 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
5145 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5146 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
5149 // This is very dangerous -- it allows you to perform a start activity (including
5150 // permission grants) as any app that may launch one of your own activities. So
5151 // we will only allow this to be done from activities that are part of the core framework,
5152 // and then only when they are running as the system.
5153 final ActivityRecord sourceRecord;
5154 final int targetUid;
5155 final String targetPackage;
5156 final boolean isResolver;
5157 synchronized (this) {
5158 if (resultTo == null) {
5159 throw new SecurityException("Must be called from an activity");
5161 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
5162 if (sourceRecord == null) {
5163 throw new SecurityException("Called with bad activity token: " + resultTo);
5165 if (!sourceRecord.info.packageName.equals("android")) {
5166 throw new SecurityException(
5167 "Must be called from an activity that is declared in the android package");
5169 if (sourceRecord.app == null) {
5170 throw new SecurityException("Called without a process attached to activity");
5172 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
5173 // This is still okay, as long as this activity is running under the
5174 // uid of the original calling activity.
5175 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
5176 throw new SecurityException(
5177 "Calling activity in uid " + sourceRecord.app.uid
5178 + " must be system uid or original calling uid "
5179 + sourceRecord.launchedFromUid);
5182 if (ignoreTargetSecurity) {
5183 if (intent.getComponent() == null) {
5184 throw new SecurityException(
5185 "Component must be specified with ignoreTargetSecurity");
5187 if (intent.getSelector() != null) {
5188 throw new SecurityException(
5189 "Selector not allowed with ignoreTargetSecurity");
5192 targetUid = sourceRecord.launchedFromUid;
5193 targetPackage = sourceRecord.launchedFromPackage;
5194 isResolver = sourceRecord.isResolverOrChildActivity();
5197 if (userId == UserHandle.USER_NULL) {
5198 userId = UserHandle.getUserId(sourceRecord.app.uid);
5201 // TODO: Switch to user app stacks here.
5203 return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
5204 .setCallingUid(targetUid)
5205 .setCallingPackage(targetPackage)
5206 .setResolvedType(resolvedType)
5207 .setResultTo(resultTo)
5208 .setResultWho(resultWho)
5209 .setRequestCode(requestCode)
5210 .setStartFlags(startFlags)
5211 .setActivityOptions(bOptions)
5213 .setIgnoreTargetSecurity(ignoreTargetSecurity)
5214 .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
5216 } catch (SecurityException e) {
5217 // XXX need to figure out how to propagate to original app.
5218 // A SecurityException here is generally actually a fault of the original
5219 // calling activity (such as a fairly granting permissions), so propagate it
5222 StringBuilder msg = new StringBuilder();
5223 msg.append("While launching");
5224 msg.append(intent.toString());
5226 msg.append(e.getMessage());
5233 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
5234 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5235 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5236 enforceNotIsolatedCaller("startActivityAndWait");
5237 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5238 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
5239 WaitResult res = new WaitResult();
5240 // TODO: Switch to user app stacks here.
5241 mActivityStartController.obtainStarter(intent, "startActivityAndWait")
5243 .setCallingPackage(callingPackage)
5244 .setResolvedType(resolvedType)
5245 .setResultTo(resultTo)
5246 .setResultWho(resultWho)
5247 .setRequestCode(requestCode)
5248 .setStartFlags(startFlags)
5249 .setActivityOptions(bOptions)
5251 .setProfilerInfo(profilerInfo)
5258 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
5259 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5260 int startFlags, Configuration config, Bundle bOptions, int userId) {
5261 enforceNotIsolatedCaller("startActivityWithConfig");
5262 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5263 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
5264 // TODO: Switch to user app stacks here.
5265 return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
5267 .setCallingPackage(callingPackage)
5268 .setResolvedType(resolvedType)
5269 .setResultTo(resultTo)
5270 .setResultWho(resultWho)
5271 .setRequestCode(requestCode)
5272 .setStartFlags(startFlags)
5273 .setGlobalConfiguration(config)
5274 .setActivityOptions(bOptions)
5280 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
5281 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
5282 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
5283 throws TransactionTooLargeException {
5284 enforceNotIsolatedCaller("startActivityIntentSender");
5285 // Refuse possible leaked file descriptors
5286 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
5287 throw new IllegalArgumentException("File descriptors passed in Intent");
5290 if (!(target instanceof PendingIntentRecord)) {
5291 throw new IllegalArgumentException("Bad PendingIntent object");
5294 PendingIntentRecord pir = (PendingIntentRecord)target;
5296 synchronized (this) {
5297 // If this is coming from the currently resumed activity, it is
5298 // effectively saying that app switches are allowed at this point.
5299 final ActivityStack stack = getFocusedStack();
5300 if (stack.mResumedActivity != null &&
5301 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
5302 mAppSwitchesAllowedTime = 0;
5305 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
5306 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
5311 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
5312 Intent intent, String resolvedType, IVoiceInteractionSession session,
5313 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
5314 Bundle bOptions, int userId) {
5315 enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
5316 if (session == null || interactor == null) {
5317 throw new NullPointerException("null session or interactor");
5319 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5320 ALLOW_FULL_ONLY, "startVoiceActivity", null);
5321 // TODO: Switch to user app stacks here.
5322 return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
5323 .setCallingUid(callingUid)
5324 .setCallingPackage(callingPackage)
5325 .setResolvedType(resolvedType)
5326 .setVoiceSession(session)
5327 .setVoiceInteractor(interactor)
5328 .setStartFlags(startFlags)
5329 .setProfilerInfo(profilerInfo)
5330 .setActivityOptions(bOptions)
5336 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
5337 Intent intent, String resolvedType, Bundle bOptions, int userId) {
5338 enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
5339 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5340 ALLOW_FULL_ONLY, "startAssistantActivity", null);
5342 return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
5343 .setCallingUid(callingUid)
5344 .setCallingPackage(callingPackage)
5345 .setResolvedType(resolvedType)
5346 .setActivityOptions(bOptions)
5352 public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
5353 IRecentsAnimationRunner recentsAnimationRunner) {
5354 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
5355 final int callingPid = Binder.getCallingPid();
5356 final long origId = Binder.clearCallingIdentity();
5358 synchronized (this) {
5359 final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
5360 final int recentsUid = mRecentTasks.getRecentsComponentUid();
5362 // Start a new recents animation
5363 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
5364 mActivityStartController, mWindowManager, mUserController, callingPid);
5365 anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
5366 recentsUid, assistDataReceiver);
5369 Binder.restoreCallingIdentity(origId);
5374 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5375 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
5376 final long callingUid = Binder.getCallingUid();
5377 final long origId = Binder.clearCallingIdentity();
5379 synchronized (this) {
5380 // Cancel the recents animation synchronously (do not hold the WM lock)
5381 mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
5382 ? REORDER_MOVE_TO_ORIGINAL_POSITION
5383 : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
5386 Binder.restoreCallingIdentity(origId);
5391 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
5392 throws RemoteException {
5393 Slog.i(TAG, "Activity tried to startVoiceInteraction");
5394 synchronized (this) {
5395 ActivityRecord activity = getFocusedStack().getTopActivity();
5396 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
5397 throw new SecurityException("Only focused activity can call startVoiceInteraction");
5399 if (mRunningVoice != null || activity.getTask().voiceSession != null
5400 || activity.voiceSession != null) {
5401 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
5404 if (activity.pendingVoiceInteractionStart) {
5405 Slog.w(TAG, "Pending start of voice interaction already.");
5408 activity.pendingVoiceInteractionStart = true;
5410 LocalServices.getService(VoiceInteractionManagerInternal.class)
5411 .startLocalVoiceInteraction(callingActivity, options);
5415 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5416 LocalServices.getService(VoiceInteractionManagerInternal.class)
5417 .stopLocalVoiceInteraction(callingActivity);
5421 public boolean supportsLocalVoiceInteraction() throws RemoteException {
5422 return LocalServices.getService(VoiceInteractionManagerInternal.class)
5423 .supportsLocalVoiceInteraction();
5427 void onLocalVoiceInteractionStartedLocked(IBinder activity,
5428 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5429 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
5430 if (activityToCallback == null) return;
5431 activityToCallback.setVoiceSessionLocked(voiceSession);
5433 // Inform the activity
5435 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5437 long token = Binder.clearCallingIdentity();
5439 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5441 Binder.restoreCallingIdentity(token);
5443 // TODO: VI Should we cache the activity so that it's easier to find later
5444 // rather than scan through all the stacks and activities?
5445 } catch (RemoteException re) {
5446 activityToCallback.clearVoiceSessionLocked();
5447 // TODO: VI Should this terminate the voice session?
5452 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5453 synchronized (this) {
5454 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5456 mVoiceWakeLock.acquire();
5458 mVoiceWakeLock.release();
5465 public boolean startNextMatchingActivity(IBinder callingActivity,
5466 Intent intent, Bundle bOptions) {
5467 // Refuse possible leaked file descriptors
5468 if (intent != null && intent.hasFileDescriptors() == true) {
5469 throw new IllegalArgumentException("File descriptors passed in Intent");
5471 SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5473 synchronized (this) {
5474 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5476 SafeActivityOptions.abort(options);
5479 if (r.app == null || r.app.thread == null) {
5480 // The caller is not running... d'oh!
5481 SafeActivityOptions.abort(options);
5484 intent = new Intent(intent);
5485 // The caller is not allowed to change the data.
5486 intent.setDataAndType(r.intent.getData(), r.intent.getType());
5487 // And we are resetting to find the next component...
5488 intent.setComponent(null);
5490 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5492 ActivityInfo aInfo = null;
5494 List<ResolveInfo> resolves =
5495 AppGlobals.getPackageManager().queryIntentActivities(
5496 intent, r.resolvedType,
5497 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5498 UserHandle.getCallingUserId()).getList();
5500 // Look for the original activity in the list...
5501 final int N = resolves != null ? resolves.size() : 0;
5502 for (int i=0; i<N; i++) {
5503 ResolveInfo rInfo = resolves.get(i);
5504 if (rInfo.activityInfo.packageName.equals(r.packageName)
5505 && rInfo.activityInfo.name.equals(r.info.name)) {
5506 // We found the current one... the next matching is
5510 aInfo = resolves.get(i).activityInfo;
5513 Slog.v(TAG, "Next matching activity: found current " + r.packageName
5514 + "/" + r.info.name);
5515 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5516 ? "null" : aInfo.packageName + "/" + aInfo.name));
5521 } catch (RemoteException e) {
5524 if (aInfo == null) {
5525 // Nobody who is next!
5526 SafeActivityOptions.abort(options);
5527 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5531 intent.setComponent(new ComponentName(
5532 aInfo.applicationInfo.packageName, aInfo.name));
5533 intent.setFlags(intent.getFlags()&~(
5534 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5535 Intent.FLAG_ACTIVITY_CLEAR_TOP|
5536 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5537 FLAG_ACTIVITY_NEW_TASK));
5539 // Okay now we need to start the new activity, replacing the
5540 // currently running activity. This is a little tricky because
5541 // we want to start the new one as if the current one is finished,
5542 // but not finish the current one first so that there is no flicker.
5544 final boolean wasFinishing = r.finishing;
5547 // Propagate reply information over to the new activity.
5548 final ActivityRecord resultTo = r.resultTo;
5549 final String resultWho = r.resultWho;
5550 final int requestCode = r.requestCode;
5552 if (resultTo != null) {
5553 resultTo.removeResultsLocked(r, resultWho, requestCode);
5556 final long origId = Binder.clearCallingIdentity();
5557 // TODO(b/64750076): Check if calling pid should really be -1.
5558 final int res = mActivityStartController
5559 .obtainStarter(intent, "startNextMatchingActivity")
5560 .setCaller(r.app.thread)
5561 .setResolvedType(r.resolvedType)
5562 .setActivityInfo(aInfo)
5563 .setResultTo(resultTo != null ? resultTo.appToken : null)
5564 .setResultWho(resultWho)
5565 .setRequestCode(requestCode)
5567 .setCallingUid(r.launchedFromUid)
5568 .setCallingPackage(r.launchedFromPackage)
5569 .setRealCallingPid(-1)
5570 .setRealCallingUid(r.launchedFromUid)
5571 .setActivityOptions(options)
5573 Binder.restoreCallingIdentity(origId);
5575 r.finishing = wasFinishing;
5576 if (res != ActivityManager.START_SUCCESS) {
5584 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5585 enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5586 "startActivityFromRecents()");
5588 final int callingPid = Binder.getCallingPid();
5589 final int callingUid = Binder.getCallingUid();
5590 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
5591 final long origId = Binder.clearCallingIdentity();
5593 synchronized (this) {
5594 return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5598 Binder.restoreCallingIdentity(origId);
5603 public final int startActivities(IApplicationThread caller, String callingPackage,
5604 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5606 final String reason = "startActivities";
5607 enforceNotIsolatedCaller(reason);
5608 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5609 userId, false, ALLOW_FULL_ONLY, reason, null);
5610 // TODO: Switch to user app stacks here.
5611 int ret = mActivityStartController.startActivities(caller, -1, 0,
5612 UserHandle.USER_NULL, callingPackage, intents, resolvedTypes, resultTo,
5613 SafeActivityOptions.fromBundle(bOptions), userId, reason,
5614 null /* originatingPendingIntent */);
5619 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5620 synchronized (this) {
5621 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5625 r.reportFullyDrawnLocked(restoredFromBundle);
5630 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5631 synchronized (this) {
5632 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5636 final long origId = Binder.clearCallingIdentity();
5638 r.setRequestedOrientation(requestedOrientation);
5640 Binder.restoreCallingIdentity(origId);
5646 public int getRequestedOrientation(IBinder token) {
5647 synchronized (this) {
5648 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5650 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5652 return r.getRequestedOrientation();
5657 * This is the internal entry point for handling Activity.finish().
5659 * @param token The Binder token referencing the Activity we want to finish.
5660 * @param resultCode Result code, if any, from this Activity.
5661 * @param resultData Result data (Intent), if any, from this Activity.
5662 * @param finishTask Whether to finish the task associated with this Activity.
5664 * @return Returns true if the activity successfully finished, or false if it is still running.
5667 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5669 // Refuse possible leaked file descriptors
5670 if (resultData != null && resultData.hasFileDescriptors() == true) {
5671 throw new IllegalArgumentException("File descriptors passed in Intent");
5674 synchronized(this) {
5675 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5679 // Keep track of the root activity of the task before we finish it
5680 TaskRecord tr = r.getTask();
5681 ActivityRecord rootR = tr.getRootActivity();
5682 if (rootR == null) {
5683 Slog.w(TAG, "Finishing task with all activities already finished");
5685 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5687 if (mLockTaskController.activityBlockedFromFinish(r)) {
5691 if (mController != null) {
5692 // Find the first activity that is not finishing.
5693 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5695 // ask watcher if this is allowed
5696 boolean resumeOK = true;
5698 resumeOK = mController.activityResuming(next.packageName);
5699 } catch (RemoteException e) {
5701 Watchdog.getInstance().setActivityController(null);
5705 Slog.i(TAG, "Not finishing activity because controller resumed");
5710 final long origId = Binder.clearCallingIdentity();
5713 final boolean finishWithRootActivity =
5714 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5715 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5716 || (finishWithRootActivity && r == rootR)) {
5717 // If requested, remove the task that is associated to this activity only if it
5718 // was the root activity in the task. The result code and data is ignored
5719 // because we don't support returning them across task boundaries. Also, to
5720 // keep backwards compatibility we remove the task from recents when finishing
5721 // task with root activity.
5722 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5723 finishWithRootActivity, "finish-activity");
5725 Slog.i(TAG, "Removing task failed to finish activity");
5728 res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5729 resultData, "app-request", true);
5731 Slog.i(TAG, "Failed to finish by app-request");
5736 Binder.restoreCallingIdentity(origId);
5742 public final void finishHeavyWeightApp() {
5743 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5744 != PackageManager.PERMISSION_GRANTED) {
5745 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5746 + Binder.getCallingPid()
5747 + ", uid=" + Binder.getCallingUid()
5748 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5750 throw new SecurityException(msg);
5753 synchronized(this) {
5754 final ProcessRecord proc = mHeavyWeightProcess;
5759 ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5760 for (int i = 0; i < activities.size(); i++) {
5761 ActivityRecord r = activities.get(i);
5762 if (!r.finishing && r.isInStackLocked()) {
5763 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5764 null, "finish-heavy", true);
5768 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5770 mHeavyWeightProcess = null;
5775 public void crashApplication(int uid, int initialPid, String packageName, int userId,
5777 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5778 != PackageManager.PERMISSION_GRANTED) {
5779 String msg = "Permission Denial: crashApplication() from pid="
5780 + Binder.getCallingPid()
5781 + ", uid=" + Binder.getCallingUid()
5782 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5784 throw new SecurityException(msg);
5787 synchronized(this) {
5788 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5793 public final void finishSubActivity(IBinder token, String resultWho,
5795 synchronized(this) {
5796 final long origId = Binder.clearCallingIdentity();
5797 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5799 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5801 Binder.restoreCallingIdentity(origId);
5806 public boolean finishActivityAffinity(IBinder token) {
5807 synchronized(this) {
5808 final long origId = Binder.clearCallingIdentity();
5810 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5815 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5817 final TaskRecord task = r.getTask();
5818 if (mLockTaskController.activityBlockedFromFinish(r)) {
5821 return task.getStack().finishActivityAffinityLocked(r);
5823 Binder.restoreCallingIdentity(origId);
5829 public void finishVoiceTask(IVoiceInteractionSession session) {
5830 synchronized (this) {
5831 final long origId = Binder.clearCallingIdentity();
5833 // TODO: VI Consider treating local voice interactions and voice tasks
5835 mStackSupervisor.finishVoiceTask(session);
5837 Binder.restoreCallingIdentity(origId);
5844 public boolean releaseActivityInstance(IBinder token) {
5845 synchronized(this) {
5846 final long origId = Binder.clearCallingIdentity();
5848 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5852 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5854 Binder.restoreCallingIdentity(origId);
5860 public void releaseSomeActivities(IApplicationThread appInt) {
5861 synchronized(this) {
5862 final long origId = Binder.clearCallingIdentity();
5864 ProcessRecord app = getRecordForAppLocked(appInt);
5865 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5867 Binder.restoreCallingIdentity(origId);
5873 public boolean willActivityBeVisible(IBinder token) {
5874 synchronized(this) {
5875 ActivityStack stack = ActivityRecord.getStackLocked(token);
5876 if (stack != null) {
5877 return stack.willActivityBeVisibleLocked(token);
5884 public void overridePendingTransition(IBinder token, String packageName,
5885 int enterAnim, int exitAnim) {
5886 synchronized(this) {
5887 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5892 final long origId = Binder.clearCallingIdentity();
5894 if (self.isState(ActivityState.RESUMED, ActivityState.PAUSING)) {
5895 mWindowManager.overridePendingAppTransition(packageName,
5896 enterAnim, exitAnim, null);
5899 Binder.restoreCallingIdentity(origId);
5904 * Main function for removing an existing process from the activity manager
5905 * as a result of that process going away. Clears out all connections
5909 private final void handleAppDiedLocked(ProcessRecord app,
5910 boolean restarting, boolean allowRestart) {
5912 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5913 false /*replacingPid*/);
5914 if (!kept && !restarting) {
5915 removeLruProcessLocked(app);
5917 ProcessList.remove(pid);
5921 if (mProfileProc == app) {
5922 clearProfilerLocked();
5925 // Remove this application's activities from active lists.
5926 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5928 app.clearRecentTasks();
5930 app.activities.clear();
5932 if (app.instr != null) {
5933 Slog.w(TAG, "Crash of app " + app.processName
5934 + " running instrumentation " + app.instr.mClass);
5935 Bundle info = new Bundle();
5936 info.putString("shortMsg", "Process crashed.");
5937 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5940 mWindowManager.deferSurfaceLayout();
5942 if (!restarting && hasVisibleActivities
5943 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5944 // If there was nothing to resume, and we are not already restarting this process, but
5945 // there is a visible activity that is hosted by the process... then make sure all
5946 // visible activities are running, taking care of restarting this process.
5947 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5950 mWindowManager.continueSurfaceLayout();
5955 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5956 final IBinder threadBinder = thread.asBinder();
5957 // Find the application record.
5958 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5959 final ProcessRecord rec = mLruProcesses.get(i);
5960 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5967 ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5968 if (thread == null) {
5972 int appIndex = getLRURecordIndexForAppLocked(thread);
5973 if (appIndex >= 0) {
5974 return mLruProcesses.get(appIndex);
5977 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5978 // double-check that.
5979 final IBinder threadBinder = thread.asBinder();
5980 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5981 for (int i = pmap.size()-1; i >= 0; i--) {
5982 final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5983 for (int j = procs.size()-1; j >= 0; j--) {
5984 final ProcessRecord proc = procs.valueAt(j);
5985 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5986 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5996 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5997 // If there are no longer any background processes running,
5998 // and the app that died was not running instrumentation,
5999 // then tell everyone we are now low on memory.
6000 boolean haveBg = false;
6001 for (int i=mLruProcesses.size()-1; i>=0; i--) {
6002 ProcessRecord rec = mLruProcesses.get(i);
6003 if (rec.thread != null
6004 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
6011 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6013 long now = SystemClock.uptimeMillis();
6014 if (now < (mLastMemUsageReportTime+5*60*1000)) {
6017 mLastMemUsageReportTime = now;
6020 final ArrayList<ProcessMemInfo> memInfos
6021 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
6022 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
6023 long now = SystemClock.uptimeMillis();
6024 for (int i=mLruProcesses.size()-1; i>=0; i--) {
6025 ProcessRecord rec = mLruProcesses.get(i);
6026 if (rec == dyingProc || rec.thread == null) {
6030 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
6031 rec.setProcState, rec.adjType, rec.makeAdjReason()));
6033 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
6034 // The low memory report is overriding any current
6035 // state for a GC request. Make sure to do
6036 // heavy/important/visible/foreground processes first.
6037 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
6038 rec.lastRequestedGc = 0;
6040 rec.lastRequestedGc = rec.lastLowMemory;
6042 rec.reportLowMemory = true;
6043 rec.lastLowMemory = now;
6044 mProcessesToGc.remove(rec);
6045 addProcessToGcListLocked(rec);
6049 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
6050 mHandler.sendMessage(msg);
6052 scheduleAppGcsLocked();
6057 final void appDiedLocked(ProcessRecord app) {
6058 appDiedLocked(app, app.pid, app.thread, false);
6062 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
6063 boolean fromBinderDied) {
6064 // First check if this ProcessRecord is actually active for the pid.
6065 synchronized (mPidsSelfLocked) {
6066 ProcessRecord curProc = mPidsSelfLocked.get(pid);
6067 if (curProc != app) {
6068 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
6073 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6074 synchronized (stats) {
6075 stats.noteProcessDiedLocked(app.info.uid, pid);
6079 if (!fromBinderDied) {
6080 killProcessQuiet(pid);
6082 killProcessGroup(app.uid, pid);
6086 // Clean up already done if the process has been re-started.
6087 if (app.pid == pid && app.thread != null &&
6088 app.thread.asBinder() == thread.asBinder()) {
6089 boolean doLowMem = app.instr == null;
6090 boolean doOomAdj = doLowMem;
6091 if (!app.killedByAm) {
6092 reportUidInfoMessageLocked(TAG,
6093 "Process " + app.processName + " (pid " + pid + ") has died: "
6094 + ProcessList.makeOomAdjString(app.setAdj)
6095 + ProcessList.makeProcStateString(app.setProcState), app.info.uid);
6096 mAllowLowerMemLevel = true;
6098 // Note that we always want to do oom adj to update our state with the
6099 // new number of procs.
6100 mAllowLowerMemLevel = false;
6103 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
6104 app.setAdj, app.setProcState);
6105 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
6106 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
6107 handleAppDiedLocked(app, false, true);
6110 updateOomAdjLocked();
6113 doLowMemReportIfNeededLocked(app);
6115 } else if (app.pid != pid) {
6116 // A new process has already been started.
6117 reportUidInfoMessageLocked(TAG,
6118 "Process " + app.processName + " (pid " + pid
6119 + ") has died and restarted (pid " + app.pid + ").", app.info.uid);
6120 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
6121 } else if (DEBUG_PROCESSES) {
6122 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
6123 + thread.asBinder());
6126 // On the device which doesn't have Cgroup, log LmkStateChanged which is used as a signal
6127 // for pulling memory stats of other running processes when this process died.
6129 StatsLog.write(StatsLog.APP_DIED, SystemClock.elapsedRealtime());
6134 * If a stack trace dump file is configured, dump process stack traces.
6135 * @param clearTraces causes the dump file to be erased prior to the new
6136 * traces being written, if true; when false, the new traces will be
6137 * appended to any existing file content.
6138 * @param firstPids of dalvik VM processes to dump stack traces for first
6139 * @param lastPids of dalvik VM processes to dump stack traces for last
6140 * @param nativePids optional list of native pids to dump stack crawls
6142 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
6143 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
6144 ArrayList<Integer> nativePids) {
6145 ArrayList<Integer> extraPids = null;
6147 // Measure CPU usage as soon as we're called in order to get a realistic sampling
6148 // of the top users at the time of the request.
6149 if (processCpuTracker != null) {
6150 processCpuTracker.init();
6153 } catch (InterruptedException ignored) {
6156 processCpuTracker.update();
6158 // We'll take the stack crawls of just the top apps using CPU.
6159 final int N = processCpuTracker.countWorkingStats();
6160 extraPids = new ArrayList<>();
6161 for (int i = 0; i < N && extraPids.size() < 5; i++) {
6162 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
6163 if (lastPids.indexOfKey(stats.pid) >= 0) {
6164 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
6166 extraPids.add(stats.pid);
6167 } else if (DEBUG_ANR) {
6168 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
6174 boolean useTombstonedForJavaTraces = false;
6177 final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
6178 if (tracesDirProp.isEmpty()) {
6179 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
6180 // dumping scheme. All traces are written to a global trace file (usually
6181 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
6182 // the file if requested.
6184 // This mode of operation will be removed in the near future.
6187 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6188 if (globalTracesPath.isEmpty()) {
6189 Slog.w(TAG, "dumpStackTraces: no trace path configured");
6193 tracesFile = new File(globalTracesPath);
6195 if (clearTraces && tracesFile.exists()) {
6196 tracesFile.delete();
6199 tracesFile.createNewFile();
6200 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
6201 } catch (IOException e) {
6202 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
6206 File tracesDir = new File(tracesDirProp);
6207 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
6208 // Each set of ANR traces is written to a separate file and dumpstate will process
6209 // all such files and add them to a captured bug report if they're recent enough.
6210 maybePruneOldTraces(tracesDir);
6212 // NOTE: We should consider creating the file in native code atomically once we've
6213 // gotten rid of the old scheme of dumping and lot of the code that deals with paths
6215 tracesFile = createAnrDumpFile(tracesDir);
6216 if (tracesFile == null) {
6220 useTombstonedForJavaTraces = true;
6223 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
6224 useTombstonedForJavaTraces);
6228 @GuardedBy("ActivityManagerService.class")
6229 private static SimpleDateFormat sAnrFileDateFormat;
6231 private static synchronized File createAnrDumpFile(File tracesDir) {
6232 if (sAnrFileDateFormat == null) {
6233 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
6236 final String formattedDate = sAnrFileDateFormat.format(new Date());
6237 final File anrFile = new File(tracesDir, "anr_" + formattedDate);
6240 if (anrFile.createNewFile()) {
6241 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
6244 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
6246 } catch (IOException ioe) {
6247 Slog.w(TAG, "Exception creating ANR dump file:", ioe);
6254 * Prune all trace files that are more than a day old.
6256 * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
6257 * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
6258 * since it's the system_server that creates trace files for most ANRs.
6260 private static void maybePruneOldTraces(File tracesDir) {
6261 final long now = System.currentTimeMillis();
6262 final File[] traceFiles = tracesDir.listFiles();
6264 if (traceFiles != null) {
6265 for (File file : traceFiles) {
6266 if ((now - file.lastModified()) > DAY_IN_MILLIS) {
6267 if (!file.delete()) {
6268 Slog.w(TAG, "Unable to prune stale trace file: " + file);
6276 * Legacy code, do not use. Existing users will be deleted.
6281 public static class DumpStackFileObserver extends FileObserver {
6282 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
6283 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
6285 private final String mTracesPath;
6286 private boolean mClosed;
6288 public DumpStackFileObserver(String tracesPath) {
6289 super(tracesPath, FileObserver.CLOSE_WRITE);
6290 mTracesPath = tracesPath;
6294 public synchronized void onEvent(int event, String path) {
6299 public long dumpWithTimeout(int pid, long timeout) {
6300 sendSignal(pid, SIGNAL_QUIT);
6301 final long start = SystemClock.elapsedRealtime();
6303 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
6304 synchronized (this) {
6306 wait(waitTime); // Wait for traces file to be closed.
6307 } catch (InterruptedException e) {
6312 // This avoids a corner case of passing a negative time to the native
6313 // trace in case we've already hit the overall timeout.
6314 final long timeWaited = SystemClock.elapsedRealtime() - start;
6315 if (timeWaited >= timeout) {
6320 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
6321 ". Attempting native stack collection.");
6323 final long nativeDumpTimeoutMs = Math.min(
6324 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
6326 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
6327 (int) (nativeDumpTimeoutMs / 1000));
6330 final long end = SystemClock.elapsedRealtime();
6333 return (end - start);
6338 * Dump java traces for process {@code pid} to the specified file. If java trace dumping
6339 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
6340 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
6341 * attempting to obtain native traces in the case of a failure. Returns the total time spent
6344 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
6345 final long timeStart = SystemClock.elapsedRealtime();
6346 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
6347 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
6348 (NATIVE_DUMP_TIMEOUT_MS / 1000));
6351 return SystemClock.elapsedRealtime() - timeStart;
6354 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6355 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6356 boolean useTombstonedForJavaTraces) {
6358 // We don't need any sort of inotify based monitoring when we're dumping traces via
6359 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
6360 // control of all writes to the file in question.
6361 final DumpStackFileObserver observer;
6362 if (useTombstonedForJavaTraces) {
6365 // Use a FileObserver to detect when traces finish writing.
6366 // The order of traces is considered important to maintain for legibility.
6367 observer = new DumpStackFileObserver(tracesFile);
6370 // We must complete all stack dumps within 20 seconds.
6371 long remainingTime = 20 * 1000;
6373 if (observer != null) {
6374 observer.startWatching();
6377 // First collect all of the stacks of the most important pids.
6378 if (firstPids != null) {
6379 int num = firstPids.size();
6380 for (int i = 0; i < num; i++) {
6381 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
6382 + firstPids.get(i));
6383 final long timeTaken;
6384 if (useTombstonedForJavaTraces) {
6385 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
6387 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6390 remainingTime -= timeTaken;
6391 if (remainingTime <= 0) {
6392 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6393 "); deadline exceeded.");
6398 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
6403 // Next collect the stacks of the native pids
6404 if (nativePids != null) {
6405 for (int pid : nativePids) {
6406 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
6407 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
6409 final long start = SystemClock.elapsedRealtime();
6410 Debug.dumpNativeBacktraceToFileTimeout(
6411 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6412 final long timeTaken = SystemClock.elapsedRealtime() - start;
6414 remainingTime -= timeTaken;
6415 if (remainingTime <= 0) {
6416 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6417 "); deadline exceeded.");
6422 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
6427 // Lastly, dump stacks for all extra PIDs from the CPU tracker.
6428 if (extraPids != null) {
6429 for (int pid : extraPids) {
6430 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6432 final long timeTaken;
6433 if (useTombstonedForJavaTraces) {
6434 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6436 timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6439 remainingTime -= timeTaken;
6440 if (remainingTime <= 0) {
6441 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6442 "); deadline exceeded.");
6447 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6452 if (observer != null) {
6453 observer.stopWatching();
6458 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6459 if (true || Build.IS_USER) {
6462 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6463 if (tracesPath == null || tracesPath.length() == 0) {
6467 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6468 StrictMode.allowThreadDiskWrites();
6470 final File tracesFile = new File(tracesPath);
6471 final File tracesDir = tracesFile.getParentFile();
6472 final File tracesTmp = new File(tracesDir, "__tmp__");
6474 if (tracesFile.exists()) {
6476 tracesFile.renameTo(tracesTmp);
6478 StringBuilder sb = new StringBuilder();
6479 Time tobj = new Time();
6480 tobj.set(System.currentTimeMillis());
6481 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6483 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6484 sb.append(" since ");
6486 FileOutputStream fos = new FileOutputStream(tracesFile);
6487 fos.write(sb.toString().getBytes());
6489 fos.write("\n*** No application process!".getBytes());
6492 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6493 } catch (IOException e) {
6494 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6498 if (app != null && app.pid > 0) {
6499 ArrayList<Integer> firstPids = new ArrayList<Integer>();
6500 firstPids.add(app.pid);
6501 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6504 File lastTracesFile = null;
6505 File curTracesFile = null;
6506 for (int i=9; i>=0; i--) {
6507 String name = String.format(Locale.US, "slow%02d.txt", i);
6508 curTracesFile = new File(tracesDir, name);
6509 if (curTracesFile.exists()) {
6510 if (lastTracesFile != null) {
6511 curTracesFile.renameTo(lastTracesFile);
6513 curTracesFile.delete();
6516 lastTracesFile = curTracesFile;
6518 tracesFile.renameTo(curTracesFile);
6519 if (tracesTmp.exists()) {
6520 tracesTmp.renameTo(tracesFile);
6523 StrictMode.setThreadPolicy(oldPolicy);
6528 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6529 if (!mLaunchWarningShown) {
6530 mLaunchWarningShown = true;
6531 mUiHandler.post(new Runnable() {
6534 synchronized (ActivityManagerService.this) {
6535 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6537 mUiHandler.postDelayed(new Runnable() {
6540 synchronized (ActivityManagerService.this) {
6542 mLaunchWarningShown = false;
6553 public boolean clearApplicationUserData(final String packageName, boolean keepState,
6554 final IPackageDataObserver observer, int userId) {
6555 enforceNotIsolatedCaller("clearApplicationUserData");
6556 int uid = Binder.getCallingUid();
6557 int pid = Binder.getCallingPid();
6558 final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6559 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6561 final ApplicationInfo appInfo;
6562 final boolean isInstantApp;
6564 long callingId = Binder.clearCallingIdentity();
6566 IPackageManager pm = AppGlobals.getPackageManager();
6567 synchronized(this) {
6568 // Instant packages are not protected
6569 if (getPackageManagerInternalLocked().isPackageDataProtected(
6570 resolvedUserId, packageName)) {
6571 throw new SecurityException(
6572 "Cannot clear data for a protected package: " + packageName);
6575 ApplicationInfo applicationInfo = null;
6577 applicationInfo = pm.getApplicationInfo(packageName,
6578 MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6579 } catch (RemoteException e) {
6582 appInfo = applicationInfo;
6584 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6586 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6587 pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6588 throw new SecurityException("PID " + pid + " does not have permission "
6589 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6590 + " of package " + packageName);
6593 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6594 .hasInstantApplicationMetadata(packageName, resolvedUserId);
6595 final boolean isUninstalledAppWithoutInstantMetadata =
6596 (appInfo == null && !hasInstantMetadata);
6597 isInstantApp = (appInfo != null && appInfo.isInstantApp())
6598 || hasInstantMetadata;
6599 final boolean canAccessInstantApps = checkComponentPermission(
6600 permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6601 == PackageManager.PERMISSION_GRANTED;
6603 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6604 && !canAccessInstantApps)) {
6605 Slog.w(TAG, "Invalid packageName: " + packageName);
6606 if (observer != null) {
6608 observer.onRemoveCompleted(packageName, false);
6609 } catch (RemoteException e) {
6610 Slog.i(TAG, "Observer no longer exists.");
6616 if (appInfo != null) {
6617 forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6618 mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6622 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6624 public void onRemoveCompleted(String packageName, boolean succeeded)
6625 throws RemoteException {
6626 if (appInfo != null) {
6627 synchronized (ActivityManagerService.this) {
6628 finishForceStopPackageLocked(packageName, appInfo.uid);
6631 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6632 Uri.fromParts("package", packageName, null));
6633 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6634 intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6635 intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6637 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6638 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6639 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6642 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6643 null, null, null, null, false, false, resolvedUserId);
6646 if (observer != null) {
6647 observer.onRemoveCompleted(packageName, succeeded);
6653 // Clear application user data
6654 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6656 if (appInfo != null) {
6657 // Restore already established notification state and permission grants,
6658 // so it told us to keep those intact -- it's about to emplace app data
6659 // that is appropriate for those bits of system state.
6661 synchronized (this) {
6662 // Remove all permissions granted from/to this package
6663 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
6667 // Reset notification state
6668 INotificationManager inm = NotificationManager.getService();
6669 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6672 // Clear its scheduled jobs
6673 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6674 js.cancelJobsForUid(appInfo.uid, "clear data");
6676 // Clear its pending alarms
6677 AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6678 ami.removeAlarmsForUid(appInfo.uid);
6680 } catch (RemoteException e) {
6683 Binder.restoreCallingIdentity(callingId);
6689 public void killBackgroundProcesses(final String packageName, int userId) {
6690 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6691 != PackageManager.PERMISSION_GRANTED &&
6692 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6693 != PackageManager.PERMISSION_GRANTED) {
6694 String msg = "Permission Denial: killBackgroundProcesses() from pid="
6695 + Binder.getCallingPid()
6696 + ", uid=" + Binder.getCallingUid()
6697 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6699 throw new SecurityException(msg);
6702 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6703 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6704 final int[] userIds = mUserController.expandUserId(userId);
6706 long callingId = Binder.clearCallingIdentity();
6708 IPackageManager pm = AppGlobals.getPackageManager();
6709 for (int targetUserId : userIds) {
6712 appId = UserHandle.getAppId(
6713 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6715 } catch (RemoteException e) {
6718 Slog.w(TAG, "Invalid packageName: " + packageName);
6721 synchronized (this) {
6722 killPackageProcessesLocked(packageName, appId, targetUserId,
6723 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6727 Binder.restoreCallingIdentity(callingId);
6732 public void killAllBackgroundProcesses() {
6733 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6734 != PackageManager.PERMISSION_GRANTED) {
6735 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6736 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6737 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6739 throw new SecurityException(msg);
6742 final long callingId = Binder.clearCallingIdentity();
6744 synchronized (this) {
6745 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6746 final int NP = mProcessNames.getMap().size();
6747 for (int ip = 0; ip < NP; ip++) {
6748 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6749 final int NA = apps.size();
6750 for (int ia = 0; ia < NA; ia++) {
6751 final ProcessRecord app = apps.valueAt(ia);
6752 if (app.persistent) {
6753 // We don't kill persistent processes.
6758 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6765 final int N = procs.size();
6766 for (int i = 0; i < N; i++) {
6767 removeProcessLocked(procs.get(i), false, true, "kill all background");
6770 mAllowLowerMemLevel = true;
6772 updateOomAdjLocked();
6773 doLowMemReportIfNeededLocked(null);
6776 Binder.restoreCallingIdentity(callingId);
6781 * Kills all background processes, except those matching any of the
6782 * specified properties.
6784 * @param minTargetSdk the target SDK version at or above which to preserve
6785 * processes, or {@code -1} to ignore the target SDK
6786 * @param maxProcState the process state at or below which to preserve
6787 * processes, or {@code -1} to ignore the process state
6789 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6790 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6791 != PackageManager.PERMISSION_GRANTED) {
6792 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6793 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6794 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6796 throw new SecurityException(msg);
6799 final long callingId = Binder.clearCallingIdentity();
6801 synchronized (this) {
6802 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6803 final int NP = mProcessNames.getMap().size();
6804 for (int ip = 0; ip < NP; ip++) {
6805 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6806 final int NA = apps.size();
6807 for (int ia = 0; ia < NA; ia++) {
6808 final ProcessRecord app = apps.valueAt(ia);
6811 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6812 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6819 final int N = procs.size();
6820 for (int i = 0; i < N; i++) {
6821 removeProcessLocked(procs.get(i), false, true, "kill all background except");
6825 Binder.restoreCallingIdentity(callingId);
6830 public void forceStopPackage(final String packageName, int userId) {
6831 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6832 != PackageManager.PERMISSION_GRANTED) {
6833 String msg = "Permission Denial: forceStopPackage() from pid="
6834 + Binder.getCallingPid()
6835 + ", uid=" + Binder.getCallingUid()
6836 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6838 throw new SecurityException(msg);
6840 final int callingPid = Binder.getCallingPid();
6841 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6842 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6843 long callingId = Binder.clearCallingIdentity();
6845 IPackageManager pm = AppGlobals.getPackageManager();
6846 synchronized(this) {
6847 int[] users = userId == UserHandle.USER_ALL
6848 ? mUserController.getUsers() : new int[] { userId };
6849 for (int user : users) {
6850 if (getPackageManagerInternalLocked().isPackageStateProtected(
6851 packageName, user)) {
6852 Slog.w(TAG, "Ignoring request to force stop protected package "
6853 + packageName + " u" + user);
6859 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6861 } catch (RemoteException e) {
6864 Slog.w(TAG, "Invalid packageName: " + packageName);
6868 pm.setPackageStoppedState(packageName, true, user);
6869 } catch (RemoteException e) {
6870 } catch (IllegalArgumentException e) {
6871 Slog.w(TAG, "Failed trying to unstop package "
6872 + packageName + ": " + e);
6874 if (mUserController.isUserRunning(user, 0)) {
6875 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6876 finishForceStopPackageLocked(packageName, pkgUid);
6881 Binder.restoreCallingIdentity(callingId);
6886 public void addPackageDependency(String packageName) {
6887 synchronized (this) {
6888 int callingPid = Binder.getCallingPid();
6889 if (callingPid == myPid()) {
6894 synchronized (mPidsSelfLocked) {
6895 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6898 if (proc.pkgDeps == null) {
6899 proc.pkgDeps = new ArraySet<String>(1);
6901 proc.pkgDeps.add(packageName);
6907 * The pkg name and app id have to be specified.
6910 public void killApplication(String pkg, int appId, int userId, String reason) {
6914 // Make sure the uid is valid.
6916 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6919 int callerUid = Binder.getCallingUid();
6920 // Only the system server can kill an application
6921 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6922 // Post an aysnc message to kill the application
6923 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6926 Bundle bundle = new Bundle();
6927 bundle.putString("pkg", pkg);
6928 bundle.putString("reason", reason);
6930 mHandler.sendMessage(msg);
6932 throw new SecurityException(callerUid + " cannot kill pkg: " +
6938 public void closeSystemDialogs(String reason) {
6939 enforceNotIsolatedCaller("closeSystemDialogs");
6941 final int pid = Binder.getCallingPid();
6942 final int uid = Binder.getCallingUid();
6943 final long origId = Binder.clearCallingIdentity();
6945 synchronized (this) {
6946 // Only allow this from foreground processes, so that background
6947 // applications can't abuse it to prevent system UI from being shown.
6948 if (uid >= FIRST_APPLICATION_UID) {
6950 synchronized (mPidsSelfLocked) {
6951 proc = mPidsSelfLocked.get(pid);
6953 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6954 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6955 + " from background process " + proc);
6959 closeSystemDialogsLocked(reason);
6962 Binder.restoreCallingIdentity(origId);
6967 void closeSystemDialogsLocked(String reason) {
6968 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6969 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6970 | Intent.FLAG_RECEIVER_FOREGROUND);
6971 if (reason != null) {
6972 intent.putExtra("reason", reason);
6974 mWindowManager.closeSystemDialogs(reason);
6976 mStackSupervisor.closeSystemDialogsLocked();
6978 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6979 OP_NONE, null, false, false,
6980 -1, SYSTEM_UID, UserHandle.USER_ALL);
6984 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6985 enforceNotIsolatedCaller("getProcessMemoryInfo");
6986 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6987 for (int i=pids.length-1; i>=0; i--) {
6990 synchronized (this) {
6991 synchronized (mPidsSelfLocked) {
6992 proc = mPidsSelfLocked.get(pids[i]);
6993 oomAdj = proc != null ? proc.setAdj : 0;
6996 infos[i] = new Debug.MemoryInfo();
6997 long startTime = SystemClock.currentThreadTimeMillis();
6998 Debug.getMemoryInfo(pids[i], infos[i]);
6999 long endTime = SystemClock.currentThreadTimeMillis();
7001 synchronized (this) {
7002 if (proc.thread != null && proc.setAdj == oomAdj) {
7003 // Record this for posterity if the process has been stable.
7004 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
7005 infos[i].getTotalUss(), infos[i].getTotalRss(), false,
7006 ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
7016 public long[] getProcessPss(int[] pids) {
7017 enforceNotIsolatedCaller("getProcessPss");
7018 long[] pss = new long[pids.length];
7019 for (int i=pids.length-1; i>=0; i--) {
7022 synchronized (this) {
7023 synchronized (mPidsSelfLocked) {
7024 proc = mPidsSelfLocked.get(pids[i]);
7025 oomAdj = proc != null ? proc.setAdj : 0;
7028 long[] tmpUss = new long[3];
7029 long startTime = SystemClock.currentThreadTimeMillis();
7030 pss[i] = Debug.getPss(pids[i], tmpUss, null);
7031 long endTime = SystemClock.currentThreadTimeMillis();
7033 synchronized (this) {
7034 if (proc.thread != null && proc.setAdj == oomAdj) {
7035 // Record this for posterity if the process has been stable.
7036 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
7037 ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
7046 public void killApplicationProcess(String processName, int uid) {
7047 if (processName == null) {
7051 int callerUid = Binder.getCallingUid();
7052 // Only the system server can kill an application
7053 if (callerUid == SYSTEM_UID) {
7054 synchronized (this) {
7055 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
7056 if (app != null && app.thread != null) {
7058 app.thread.scheduleSuicide();
7059 } catch (RemoteException e) {
7060 // If the other end already died, then our work here is done.
7063 Slog.w(TAG, "Process/uid not found attempting kill of "
7064 + processName + " / " + uid);
7068 throw new SecurityException(callerUid + " cannot kill app process: " +
7074 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
7075 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
7076 false, true, false, false, UserHandle.getUserId(uid), reason);
7080 private void finishForceStopPackageLocked(final String packageName, int uid) {
7081 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
7082 Uri.fromParts("package", packageName, null));
7083 if (!mProcessesReady) {
7084 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7085 | Intent.FLAG_RECEIVER_FOREGROUND);
7087 intent.putExtra(Intent.EXTRA_UID, uid);
7088 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
7089 broadcastIntentLocked(null, null, intent,
7090 null, null, 0, null, null, null, OP_NONE,
7091 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
7096 private final boolean killPackageProcessesLocked(String packageName, int appId,
7097 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
7098 boolean doit, boolean evenPersistent, String reason) {
7099 ArrayList<ProcessRecord> procs = new ArrayList<>();
7101 // Remove all processes this package may have touched: all with the
7102 // same UID (except for the system or root user), and all whose name
7103 // matches the package name.
7104 final int NP = mProcessNames.getMap().size();
7105 for (int ip=0; ip<NP; ip++) {
7106 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
7107 final int NA = apps.size();
7108 for (int ia=0; ia<NA; ia++) {
7109 ProcessRecord app = apps.valueAt(ia);
7110 if (app.persistent && !evenPersistent) {
7111 // we don't kill persistent processes
7121 // Skip process if it doesn't meet our oom adj requirement.
7122 if (app.setAdj < minOomAdj) {
7126 // If no package is specified, we call all processes under the
7128 if (packageName == null) {
7129 if (userId != UserHandle.USER_ALL && app.userId != userId) {
7132 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
7135 // Package has been specified, we want to hit all processes
7136 // that match it. We need to qualify this by the processes
7137 // that are running under the specified app and user ID.
7139 final boolean isDep = app.pkgDeps != null
7140 && app.pkgDeps.contains(packageName);
7141 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
7144 if (userId != UserHandle.USER_ALL && app.userId != userId) {
7147 if (!app.pkgList.containsKey(packageName) && !isDep) {
7152 // Process has passed all conditions, kill it!
7161 int N = procs.size();
7162 for (int i=0; i<N; i++) {
7163 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
7165 updateOomAdjLocked();
7169 private void cleanupDisabledPackageComponentsLocked(
7170 String packageName, int userId, boolean killProcess, String[] changedClasses) {
7172 Set<String> disabledClasses = null;
7173 boolean packageDisabled = false;
7174 IPackageManager pm = AppGlobals.getPackageManager();
7176 if (changedClasses == null) {
7177 // Nothing changed...
7181 // Determine enable/disable state of the package and its components.
7182 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
7183 for (int i = changedClasses.length - 1; i >= 0; i--) {
7184 final String changedClass = changedClasses[i];
7186 if (changedClass.equals(packageName)) {
7188 // Entire package setting changed
7189 enabled = pm.getApplicationEnabledSetting(packageName,
7190 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7191 } catch (Exception e) {
7192 // No such package/component; probably racing with uninstall. In any
7193 // event it means we have nothing further to do here.
7196 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7197 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
7198 if (packageDisabled) {
7199 // Entire package is disabled.
7200 // No need to continue to check component states.
7201 disabledClasses = null;
7206 enabled = pm.getComponentEnabledSetting(
7207 new ComponentName(packageName, changedClass),
7208 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7209 } catch (Exception e) {
7210 // As above, probably racing with uninstall.
7213 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7214 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
7215 if (disabledClasses == null) {
7216 disabledClasses = new ArraySet<>(changedClasses.length);
7218 disabledClasses.add(changedClass);
7223 if (!packageDisabled && disabledClasses == null) {
7224 // Nothing to do here...
7228 // Clean-up disabled activities.
7229 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7230 packageName, disabledClasses, true, false, userId) && mBooted) {
7231 mStackSupervisor.resumeFocusedStackTopActivityLocked();
7232 mStackSupervisor.scheduleIdleLocked();
7235 // Clean-up disabled tasks
7236 mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
7238 // Clean-up disabled services.
7239 mServices.bringDownDisabledPackageServicesLocked(
7240 packageName, disabledClasses, userId, false, killProcess, true);
7242 // Clean-up disabled providers.
7243 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7244 mProviderMap.collectPackageProvidersLocked(
7245 packageName, disabledClasses, true, false, userId, providers);
7246 for (int i = providers.size() - 1; i >= 0; i--) {
7247 removeDyingProviderLocked(null, providers.get(i), true);
7250 // Clean-up disabled broadcast receivers.
7251 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7252 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7253 packageName, disabledClasses, userId, true);
7258 final boolean clearBroadcastQueueForUserLocked(int userId) {
7259 boolean didSomething = false;
7260 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7261 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7262 null, null, userId, true);
7264 return didSomething;
7268 final boolean forceStopPackageLocked(String packageName, int appId,
7269 boolean callerWillRestart, boolean purgeCache, boolean doit,
7270 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
7273 if (userId == UserHandle.USER_ALL && packageName == null) {
7274 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
7277 if (appId < 0 && packageName != null) {
7279 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
7280 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
7281 } catch (RemoteException e) {
7286 if (packageName != null) {
7287 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
7288 + " user=" + userId + ": " + reason);
7290 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
7293 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
7296 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
7297 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
7298 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
7300 didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
7302 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7303 packageName, null, doit, evenPersistent, userId)) {
7307 didSomething = true;
7310 if (mServices.bringDownDisabledPackageServicesLocked(
7311 packageName, null, userId, evenPersistent, true, doit)) {
7315 didSomething = true;
7318 if (packageName == null) {
7319 // Remove all sticky broadcasts from this user.
7320 mStickyBroadcasts.remove(userId);
7323 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7324 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
7325 userId, providers)) {
7329 didSomething = true;
7331 for (i = providers.size() - 1; i >= 0; i--) {
7332 removeDyingProviderLocked(null, providers.get(i), true);
7335 // Remove transient permissions granted from/to this package/user
7336 removeUriPermissionsForPackageLocked(packageName, userId, false, false);
7339 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
7340 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7341 packageName, null, userId, doit);
7345 if (packageName == null || uninstalling) {
7346 // Remove pending intents. For now we only do this when force
7347 // stopping users, because we have some problems when doing this
7348 // for packages -- app widgets are not currently cleaned up for
7349 // such packages, so they can be left with bad pending intents.
7350 if (mIntentSenderRecords.size() > 0) {
7351 Iterator<WeakReference<PendingIntentRecord>> it
7352 = mIntentSenderRecords.values().iterator();
7353 while (it.hasNext()) {
7354 WeakReference<PendingIntentRecord> wpir = it.next();
7359 PendingIntentRecord pir = wpir.get();
7364 if (packageName == null) {
7365 // Stopping user, remove all objects for the user.
7366 if (pir.key.userId != userId) {
7367 // Not the same user, skip it.
7371 if (UserHandle.getAppId(pir.uid) != appId) {
7372 // Different app id, skip it.
7375 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7376 // Different user, skip it.
7379 if (!pir.key.packageName.equals(packageName)) {
7380 // Different package, skip it.
7387 didSomething = true;
7389 makeIntentSenderCanceledLocked(pir);
7390 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7391 pir.key.activity.pendingResults.remove(pir.ref);
7398 if (purgeCache && packageName != null) {
7399 AttributeCache ac = AttributeCache.instance();
7401 ac.removePackage(packageName);
7405 mStackSupervisor.resumeFocusedStackTopActivityLocked();
7406 mStackSupervisor.scheduleIdleLocked();
7410 return didSomething;
7413 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7414 return removeProcessNameLocked(name, uid, null);
7417 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
7418 final ProcessRecord expecting) {
7419 ProcessRecord old = mProcessNames.get(name, uid);
7420 // Only actually remove when the currently recorded value matches the
7421 // record that we expected; if it doesn't match then we raced with a
7422 // newly created process and we don't want to destroy the new one.
7423 if ((expecting == null) || (old == expecting)) {
7424 mProcessNames.remove(name, uid);
7426 if (old != null && old.uidRecord != null) {
7427 old.uidRecord.numProcs--;
7428 if (old.uidRecord.numProcs == 0) {
7429 // No more processes using this uid, tell clients it is gone.
7430 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7431 "No more processes in " + old.uidRecord);
7432 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
7433 EventLogTags.writeAmUidStopped(uid);
7434 mActiveUids.remove(uid);
7435 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
7437 old.uidRecord = null;
7439 mIsolatedProcesses.remove(uid);
7443 private final void addProcessNameLocked(ProcessRecord proc) {
7444 // We shouldn't already have a process under this name, but just in case we
7445 // need to clean up whatever may be there now.
7446 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
7447 if (old == proc && proc.persistent) {
7448 // We are re-adding a persistent process. Whatevs! Just leave it there.
7449 Slog.w(TAG, "Re-adding persistent process " + proc);
7450 } else if (old != null) {
7451 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7453 UidRecord uidRec = mActiveUids.get(proc.uid);
7454 if (uidRec == null) {
7455 uidRec = new UidRecord(proc.uid);
7456 // This is the first appearance of the uid, report it now!
7457 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7458 "Creating new process uid: " + uidRec);
7459 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7460 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7461 uidRec.setWhitelist = uidRec.curWhitelist = true;
7463 uidRec.updateHasInternetPermission();
7464 mActiveUids.put(proc.uid, uidRec);
7465 EventLogTags.writeAmUidRunning(uidRec.uid);
7466 noteUidProcessState(uidRec.uid, uidRec.curProcState);
7468 proc.uidRecord = uidRec;
7470 // Reset render thread tid if it was already set, so new process can set it again.
7471 proc.renderThreadTid = 0;
7473 mProcessNames.put(proc.processName, proc.uid, proc);
7474 if (proc.isolated) {
7475 mIsolatedProcesses.put(proc.uid, proc);
7480 boolean removeProcessLocked(ProcessRecord app,
7481 boolean callerWillRestart, boolean allowRestart, String reason) {
7482 final String name = app.processName;
7483 final int uid = app.uid;
7484 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7485 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7487 ProcessRecord old = mProcessNames.get(name, uid);
7489 // This process is no longer active, so nothing to do.
7490 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7493 removeProcessNameLocked(name, uid);
7494 if (mHeavyWeightProcess == app) {
7495 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7496 mHeavyWeightProcess.userId, 0));
7497 mHeavyWeightProcess = null;
7499 boolean needRestart = false;
7500 if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7503 synchronized (mPidsSelfLocked) {
7504 mPidsSelfLocked.remove(pid);
7505 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7507 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7509 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7510 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7513 boolean willRestart = false;
7514 if (app.persistent && !app.isolated) {
7515 if (!callerWillRestart) {
7521 app.kill(reason, true);
7522 handleAppDiedLocked(app, willRestart, allowRestart);
7524 removeLruProcessLocked(app);
7525 addAppLocked(app.info, null, false, null /* ABI override */);
7528 mRemovedProcesses.add(app);
7535 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7536 cleanupAppInLaunchingProvidersLocked(app, true);
7537 removeProcessLocked(app, false, true, "timeout publishing content providers");
7540 private final void processStartTimedOutLocked(ProcessRecord app) {
7541 final int pid = app.pid;
7542 boolean gone = false;
7543 synchronized (mPidsSelfLocked) {
7544 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7545 if (knownApp != null && knownApp.thread == null) {
7546 mPidsSelfLocked.remove(pid);
7552 Slog.w(TAG, "Process " + app + " failed to attach");
7553 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7554 pid, app.uid, app.processName);
7555 removeProcessNameLocked(app.processName, app.uid);
7556 if (mHeavyWeightProcess == app) {
7557 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7558 mHeavyWeightProcess.userId, 0));
7559 mHeavyWeightProcess = null;
7561 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7562 // Take care of any launching providers waiting for this process.
7563 cleanupAppInLaunchingProvidersLocked(app, true);
7564 // Take care of any services that are waiting for the process.
7565 mServices.processStartTimedOutLocked(app);
7566 app.kill("start timeout", true);
7568 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7570 removeLruProcessLocked(app);
7571 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7572 Slog.w(TAG, "Unattached app died before backup, skipping");
7573 mHandler.post(new Runnable() {
7577 IBackupManager bm = IBackupManager.Stub.asInterface(
7578 ServiceManager.getService(Context.BACKUP_SERVICE));
7579 bm.agentDisconnected(app.info.packageName);
7580 } catch (RemoteException e) {
7581 // Can't happen; the backup manager is local
7586 if (isPendingBroadcastProcessLocked(pid)) {
7587 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7588 skipPendingBroadcastLocked(pid);
7591 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7596 private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
7597 int pid, int callingUid, long startSeq) {
7599 // Find the application record that is being attached... either via
7600 // the pid if we are running in multiple processes, or just pull the
7601 // next app record if we are emulating process with anonymous threads.
7603 long startTime = SystemClock.uptimeMillis();
7604 if (pid != MY_PID && pid >= 0) {
7605 synchronized (mPidsSelfLocked) {
7606 app = mPidsSelfLocked.get(pid);
7608 if (app != null && (app.startUid != callingUid || app.startSeq != startSeq)) {
7609 String processName = null;
7610 final ProcessRecord pending = mPendingStarts.get(startSeq);
7611 if (pending != null) {
7612 processName = pending.processName;
7614 final String msg = "attachApplicationLocked process:" + processName
7615 + " startSeq:" + startSeq
7617 + " belongs to another existing app:" + app.processName
7618 + " startSeq:" + app.startSeq;
7620 // SafetyNet logging for b/131105245.
7621 EventLog.writeEvent(0x534e4554, "131105245", app.startUid, msg);
7622 // If there is already an app occupying that pid that hasn't been cleaned up
7623 cleanUpApplicationRecordLocked(app, false, false, -1,
7624 true /*replacingPid*/);
7625 mPidsSelfLocked.remove(pid);
7632 // It's possible that process called attachApplication before we got a chance to
7633 // update the internal state.
7634 if (app == null && startSeq > 0) {
7635 final ProcessRecord pending = mPendingStarts.get(startSeq);
7636 if (pending != null && pending.startUid == callingUid && pending.startSeq == startSeq
7637 && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7644 Slog.w(TAG, "No pending application record for pid " + pid
7645 + " (IApplicationThread " + thread + "); dropping process");
7646 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7647 if (pid > 0 && pid != MY_PID) {
7648 killProcessQuiet(pid);
7649 //TODO: killProcessGroup(app.info.uid, pid);
7652 thread.scheduleExit();
7653 } catch (Exception e) {
7654 // Ignore exceptions.
7660 // If this application record is still attached to a previous
7661 // process, clean it up now.
7662 if (app.thread != null) {
7663 handleAppDiedLocked(app, true, true);
7666 // Tell the process all about itself.
7668 if (DEBUG_ALL) Slog.v(
7669 TAG, "Binding process pid " + pid + " to record " + app);
7671 final String processName = app.processName;
7673 AppDeathRecipient adr = new AppDeathRecipient(
7675 thread.asBinder().linkToDeath(adr, 0);
7676 app.deathRecipient = adr;
7677 } catch (RemoteException e) {
7678 app.resetPackageList(mProcessStats);
7679 startProcessLocked(app, "link fail", processName);
7683 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7685 app.makeActive(thread, mProcessStats);
7686 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7687 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7688 app.forcingToImportant = null;
7689 updateProcessForegroundLocked(app, false, false);
7690 app.hasShownUi = false;
7691 app.debugging = false;
7693 app.killedByAm = false;
7697 // We carefully use the same state that PackageManager uses for
7698 // filtering, since we use this flag to decide if we need to install
7699 // providers when user is unlocked later
7700 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7702 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7704 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7705 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7707 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7708 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7710 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7713 checkTime(startTime, "attachApplicationLocked: before bindApplication");
7716 Slog.i(TAG, "Launching preboot mode app: " + app);
7719 if (DEBUG_ALL) Slog.v(
7720 TAG, "New app record " + app
7721 + " thread=" + thread.asBinder() + " pid=" + pid);
7723 int testMode = ApplicationThreadConstants.DEBUG_OFF;
7724 if (mDebugApp != null && mDebugApp.equals(processName)) {
7725 testMode = mWaitForDebugger
7726 ? ApplicationThreadConstants.DEBUG_WAIT
7727 : ApplicationThreadConstants.DEBUG_ON;
7728 app.debugging = true;
7729 if (mDebugTransient) {
7730 mDebugApp = mOrigDebugApp;
7731 mWaitForDebugger = mOrigWaitForDebugger;
7735 boolean enableTrackAllocation = false;
7736 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7737 enableTrackAllocation = true;
7738 mTrackAllocationApp = null;
7741 // If the app is being launched for restore or full backup, set it up specially
7742 boolean isRestrictedBackupMode = false;
7743 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7744 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7745 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7746 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7747 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7750 if (app.instr != null) {
7751 notifyPackageUse(app.instr.mClass.getPackageName(),
7752 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7754 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7755 + processName + " with config " + getGlobalConfiguration());
7756 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7757 app.compat = compatibilityInfoForPackageLocked(appInfo);
7759 ProfilerInfo profilerInfo = null;
7760 String preBindAgent = null;
7761 if (mProfileApp != null && mProfileApp.equals(processName)) {
7763 if (mProfilerInfo != null) {
7764 // Send a profiler info object to the app if either a file is given, or
7765 // an agent should be loaded at bind-time.
7766 boolean needsInfo = mProfilerInfo.profileFile != null
7767 || mProfilerInfo.attachAgentDuringBind;
7768 profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7769 if (mProfilerInfo.agent != null) {
7770 preBindAgent = mProfilerInfo.agent;
7773 } else if (app.instr != null && app.instr.mProfileFile != null) {
7774 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7777 if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7778 // We need to do a debuggable check here. See setAgentApp for why the check is
7779 // postponed to here.
7780 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7781 String agent = mAppAgentMap.get(processName);
7782 // Do not overwrite already requested agent.
7783 if (profilerInfo == null) {
7784 profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7785 mAppAgentMap.get(processName), true);
7786 } else if (profilerInfo.agent == null) {
7787 profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7792 if (profilerInfo != null && profilerInfo.profileFd != null) {
7793 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7794 if (TextUtils.equals(mProfileApp, processName) && mProfilerInfo != null) {
7795 clearProfilerLocked();
7799 // We deprecated Build.SERIAL and it is not accessible to
7800 // apps that target the v2 security sandbox and to apps that
7801 // target APIs higher than O MR1. Since access to the serial
7802 // is now behind a permission we push down the value.
7803 final String buildSerial = (appInfo.targetSandboxVersion < 2
7804 && appInfo.targetSdkVersion < Build.VERSION_CODES.P)
7805 ? sTheRealBuildSerial : Build.UNKNOWN;
7807 // Check if this is a secondary process that should be incorporated into some
7808 // currently active instrumentation. (Note we do this AFTER all of the profiling
7809 // stuff above because profiling can currently happen only in the primary
7810 // instrumentation process.)
7811 if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7812 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7813 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7814 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7815 if (aInstr.mTargetProcesses.length == 0) {
7816 // This is the wildcard mode, where every process brought up for
7817 // the target instrumentation should be included.
7818 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7820 aInstr.mRunningProcesses.add(app);
7823 for (String proc : aInstr.mTargetProcesses) {
7824 if (proc.equals(app.processName)) {
7826 aInstr.mRunningProcesses.add(app);
7835 // If we were asked to attach an agent on startup, do so now, before we're binding
7836 // application code.
7837 if (preBindAgent != null) {
7838 thread.attachAgent(preBindAgent);
7842 // Figure out whether the app needs to run in autofill compat mode.
7843 boolean isAutofillCompatEnabled = false;
7844 if (UserHandle.getAppId(app.info.uid) >= Process.FIRST_APPLICATION_UID) {
7845 final AutofillManagerInternal afm = LocalServices.getService(
7846 AutofillManagerInternal.class);
7848 isAutofillCompatEnabled = afm.isCompatibilityModeRequested(
7849 app.info.packageName, app.info.versionCode, app.userId);
7853 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7854 mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7855 if (app.isolatedEntryPoint != null) {
7856 // This is an isolated process which should just call an entry point instead of
7857 // being bound to an application.
7858 thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7859 } else if (app.instr != null) {
7860 thread.bindApplication(processName, appInfo, providers,
7862 profilerInfo, app.instr.mArguments,
7864 app.instr.mUiAutomationConnection, testMode,
7865 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7866 isRestrictedBackupMode || !normalMode, app.persistent,
7867 new Configuration(getGlobalConfiguration()), app.compat,
7868 getCommonServicesLocked(app.isolated),
7869 mCoreSettingsObserver.getCoreSettingsLocked(),
7870 buildSerial, isAutofillCompatEnabled);
7872 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7873 null, null, null, testMode,
7874 mBinderTransactionTrackingEnabled, enableTrackAllocation,
7875 isRestrictedBackupMode || !normalMode, app.persistent,
7876 new Configuration(getGlobalConfiguration()), app.compat,
7877 getCommonServicesLocked(app.isolated),
7878 mCoreSettingsObserver.getCoreSettingsLocked(),
7879 buildSerial, isAutofillCompatEnabled);
7881 if (profilerInfo != null) {
7882 profilerInfo.closeFd();
7883 profilerInfo = null;
7885 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7886 updateLruProcessLocked(app, false, null);
7887 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7888 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7889 } catch (Exception e) {
7890 // todo: Yikes! What should we do? For now we will try to
7891 // start another process, but that could easily get us in
7892 // an infinite loop of restarting processes...
7893 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7895 app.resetPackageList(mProcessStats);
7896 app.unlinkDeathRecipient();
7897 startProcessLocked(app, "bind fail", processName);
7901 // Remove this record from the list of starting applications.
7902 mPersistentStartingProcesses.remove(app);
7903 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7904 "Attach application locked removing on hold: " + app);
7905 mProcessesOnHold.remove(app);
7907 boolean badApp = false;
7908 boolean didSomething = false;
7910 // See if the top visible activity is waiting to run in this process...
7913 if (mStackSupervisor.attachApplicationLocked(app)) {
7914 didSomething = true;
7916 } catch (Exception e) {
7917 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7922 // Find any services that should be running in this process...
7925 didSomething |= mServices.attachApplicationLocked(app, processName);
7926 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7927 } catch (Exception e) {
7928 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7933 // Check if a next-broadcast receiver is in this process...
7934 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7936 didSomething |= sendPendingBroadcastsLocked(app);
7937 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7938 } catch (Exception e) {
7939 // If the app died trying to launch the receiver we declare it 'bad'
7940 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7945 // Check whether the next backup agent is in this process...
7946 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7947 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7948 "New app is backup target, launching agent for " + app);
7949 notifyPackageUse(mBackupTarget.appInfo.packageName,
7950 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7952 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7953 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7954 mBackupTarget.backupMode);
7955 } catch (Exception e) {
7956 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7962 app.kill("error during init", true);
7963 handleAppDiedLocked(app, false, true);
7967 if (!didSomething) {
7968 updateOomAdjLocked();
7969 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7976 public final void attachApplication(IApplicationThread thread, long startSeq) {
7977 if (thread == null) {
7978 throw new SecurityException("Invalid application interface");
7980 synchronized (this) {
7981 int callingPid = Binder.getCallingPid();
7982 final int callingUid = Binder.getCallingUid();
7983 final long origId = Binder.clearCallingIdentity();
7984 attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7985 Binder.restoreCallingIdentity(origId);
7990 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7991 final long origId = Binder.clearCallingIdentity();
7992 synchronized (this) {
7993 ActivityStack stack = ActivityRecord.getStackLocked(token);
7994 if (stack != null) {
7996 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7997 false /* processPausingActivities */, config);
7998 if (stopProfiling) {
7999 if ((mProfileProc == r.app) && mProfilerInfo != null) {
8000 clearProfilerLocked();
8005 Binder.restoreCallingIdentity(origId);
8008 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
8009 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
8010 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
8013 void enableScreenAfterBoot() {
8014 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
8015 SystemClock.uptimeMillis());
8016 mWindowManager.enableScreenAfterBoot();
8018 synchronized (this) {
8019 updateEventDispatchingLocked();
8024 public void showBootMessage(final CharSequence msg, final boolean always) {
8025 if (Binder.getCallingUid() != myUid()) {
8026 throw new SecurityException();
8028 mWindowManager.showBootMessage(msg, always);
8032 public void keyguardGoingAway(int flags) {
8033 enforceNotIsolatedCaller("keyguardGoingAway");
8034 final long token = Binder.clearCallingIdentity();
8036 synchronized (this) {
8037 mKeyguardController.keyguardGoingAway(flags);
8040 Binder.restoreCallingIdentity(token);
8045 * @return whther the keyguard is currently locked.
8047 boolean isKeyguardLocked() {
8048 return mKeyguardController.isKeyguardLocked();
8051 final void finishBooting() {
8052 synchronized (this) {
8053 if (!mBootAnimationComplete) {
8054 mCallFinishBooting = true;
8057 mCallFinishBooting = false;
8060 ArraySet<String> completedIsas = new ArraySet<String>();
8061 for (String abi : Build.SUPPORTED_ABIS) {
8062 zygoteProcess.establishZygoteConnectionForAbi(abi);
8063 final String instructionSet = VMRuntime.getInstructionSet(abi);
8064 if (!completedIsas.contains(instructionSet)) {
8066 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
8067 } catch (InstallerException e) {
8068 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
8069 e.getMessage() +")");
8071 completedIsas.add(instructionSet);
8075 IntentFilter pkgFilter = new IntentFilter();
8076 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
8077 pkgFilter.addDataScheme("package");
8078 mContext.registerReceiver(new BroadcastReceiver() {
8080 public void onReceive(Context context, Intent intent) {
8081 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
8083 for (String pkg : pkgs) {
8084 synchronized (ActivityManagerService.this) {
8085 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
8086 0, "query restart")) {
8087 setResultCode(Activity.RESULT_OK);
8096 IntentFilter dumpheapFilter = new IntentFilter();
8097 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
8098 mContext.registerReceiver(new BroadcastReceiver() {
8100 public void onReceive(Context context, Intent intent) {
8101 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
8102 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
8104 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
8109 // Let system services know.
8110 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
8112 synchronized (this) {
8113 // Ensure that any processes we had put on hold are now started
8115 final int NP = mProcessesOnHold.size();
8117 ArrayList<ProcessRecord> procs =
8118 new ArrayList<ProcessRecord>(mProcessesOnHold);
8119 for (int ip=0; ip<NP; ip++) {
8120 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
8122 startProcessLocked(procs.get(ip), "on-hold", null);
8125 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
8128 // Start looking for apps that are abusing wake locks.
8129 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
8130 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
8131 // Tell anyone interested that we are done booting!
8132 SystemProperties.set("sys.boot_completed", "1");
8134 // And trigger dev.bootcomplete if we are not showing encryption progress
8135 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
8136 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
8137 SystemProperties.set("dev.bootcomplete", "1");
8139 mUserController.sendBootCompleted(
8140 new IIntentReceiver.Stub() {
8142 public void performReceive(Intent intent, int resultCode,
8143 String data, Bundle extras, boolean ordered,
8144 boolean sticky, int sendingUser) {
8145 synchronized (ActivityManagerService.this) {
8146 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
8150 mUserController.scheduleStartProfiles();
8155 public void bootAnimationComplete() {
8156 final boolean callFinishBooting;
8157 synchronized (this) {
8158 callFinishBooting = mCallFinishBooting;
8159 mBootAnimationComplete = true;
8161 if (callFinishBooting) {
8162 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8164 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8168 final void ensureBootCompleted() {
8170 boolean enableScreen;
8171 synchronized (this) {
8174 enableScreen = !mBooted;
8179 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8181 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8185 enableScreenAfterBoot();
8190 public final void activityResumed(IBinder token) {
8191 final long origId = Binder.clearCallingIdentity();
8192 synchronized(this) {
8193 ActivityRecord.activityResumedLocked(token);
8194 mWindowManager.notifyAppResumedFinished(token);
8196 Binder.restoreCallingIdentity(origId);
8200 public final void activityPaused(IBinder token) {
8201 final long origId = Binder.clearCallingIdentity();
8202 synchronized(this) {
8203 ActivityStack stack = ActivityRecord.getStackLocked(token);
8204 if (stack != null) {
8205 stack.activityPausedLocked(token, false);
8208 Binder.restoreCallingIdentity(origId);
8212 public final void activityStopped(IBinder token, Bundle icicle,
8213 PersistableBundle persistentState, CharSequence description) {
8214 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
8216 // Refuse possible leaked file descriptors
8217 if (icicle != null && icicle.hasFileDescriptors()) {
8218 throw new IllegalArgumentException("File descriptors passed in Bundle");
8221 final long origId = Binder.clearCallingIdentity();
8223 synchronized (this) {
8224 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8226 r.activityStoppedLocked(icicle, persistentState, description);
8232 Binder.restoreCallingIdentity(origId);
8236 public final void activityDestroyed(IBinder token) {
8237 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
8238 synchronized (this) {
8239 ActivityStack stack = ActivityRecord.getStackLocked(token);
8240 if (stack != null) {
8241 stack.activityDestroyedLocked(token, "activityDestroyed");
8247 public final void activityRelaunched(IBinder token) {
8248 final long origId = Binder.clearCallingIdentity();
8249 synchronized (this) {
8250 mStackSupervisor.activityRelaunchedLocked(token);
8252 Binder.restoreCallingIdentity(origId);
8256 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
8257 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
8258 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
8259 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
8260 synchronized (this) {
8261 ActivityRecord record = ActivityRecord.isInStackLocked(token);
8262 if (record == null) {
8263 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
8264 + "found for: " + token);
8266 record.setSizeConfigurations(horizontalSizeConfiguration,
8267 verticalSizeConfigurations, smallestSizeConfigurations);
8272 public final void notifyLaunchTaskBehindComplete(IBinder token) {
8273 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
8277 public final void notifyEnterAnimationComplete(IBinder token) {
8278 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
8282 public String getCallingPackage(IBinder token) {
8283 synchronized (this) {
8284 ActivityRecord r = getCallingRecordLocked(token);
8285 return r != null ? r.info.packageName : null;
8290 public ComponentName getCallingActivity(IBinder token) {
8291 synchronized (this) {
8292 ActivityRecord r = getCallingRecordLocked(token);
8293 return r != null ? r.intent.getComponent() : null;
8297 private ActivityRecord getCallingRecordLocked(IBinder token) {
8298 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8306 public ComponentName getActivityClassForToken(IBinder token) {
8307 synchronized(this) {
8308 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8312 return r.intent.getComponent();
8317 public String getPackageForToken(IBinder token) {
8318 synchronized(this) {
8319 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8323 return r.packageName;
8328 public boolean isRootVoiceInteraction(IBinder token) {
8329 synchronized(this) {
8330 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8334 return r.rootVoiceInteraction;
8339 public IIntentSender getIntentSender(int type,
8340 String packageName, IBinder token, String resultWho,
8341 int requestCode, Intent[] intents, String[] resolvedTypes,
8342 int flags, Bundle bOptions, int userId) {
8343 enforceNotIsolatedCaller("getIntentSender");
8344 // Refuse possible leaked file descriptors
8345 if (intents != null) {
8346 if (intents.length < 1) {
8347 throw new IllegalArgumentException("Intents array length must be >= 1");
8349 for (int i=0; i<intents.length; i++) {
8350 Intent intent = intents[i];
8351 if (intent != null) {
8352 if (intent.hasFileDescriptors()) {
8353 throw new IllegalArgumentException("File descriptors passed in Intent");
8355 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
8356 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
8357 throw new IllegalArgumentException(
8358 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
8360 intents[i] = new Intent(intent);
8363 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
8364 throw new IllegalArgumentException(
8365 "Intent array length does not match resolvedTypes length");
8368 if (bOptions != null) {
8369 if (bOptions.hasFileDescriptors()) {
8370 throw new IllegalArgumentException("File descriptors passed in options");
8374 synchronized(this) {
8375 int callingUid = Binder.getCallingUid();
8376 int origUserId = userId;
8377 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8378 type == ActivityManager.INTENT_SENDER_BROADCAST,
8379 ALLOW_NON_FULL, "getIntentSender", null);
8380 if (origUserId == UserHandle.USER_CURRENT) {
8381 // We don't want to evaluate this until the pending intent is
8382 // actually executed. However, we do want to always do the
8383 // security checking for it above.
8384 userId = UserHandle.USER_CURRENT;
8387 if (callingUid != 0 && callingUid != SYSTEM_UID) {
8388 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
8389 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
8390 if (!UserHandle.isSameApp(callingUid, uid)) {
8391 String msg = "Permission Denial: getIntentSender() from pid="
8392 + Binder.getCallingPid()
8393 + ", uid=" + Binder.getCallingUid()
8394 + ", (need uid=" + uid + ")"
8395 + " is not allowed to send as package " + packageName;
8397 throw new SecurityException(msg);
8401 return getIntentSenderLocked(type, packageName, callingUid, userId,
8402 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
8404 } catch (RemoteException e) {
8405 throw new SecurityException(e);
8410 IIntentSender getIntentSenderLocked(int type, String packageName,
8411 int callingUid, int userId, IBinder token, String resultWho,
8412 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
8414 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
8415 ActivityRecord activity = null;
8416 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8417 activity = ActivityRecord.isInStackLocked(token);
8418 if (activity == null) {
8419 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
8422 if (activity.finishing) {
8423 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
8428 // We're going to be splicing together extras before sending, so we're
8429 // okay poking into any contained extras.
8430 if (intents != null) {
8431 for (int i = 0; i < intents.length; i++) {
8432 intents[i].setDefusable(true);
8435 Bundle.setDefusable(bOptions, true);
8437 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
8438 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
8439 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
8440 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
8441 |PendingIntent.FLAG_UPDATE_CURRENT);
8443 PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
8444 resultWho, requestCode, intents, resolvedTypes, flags,
8445 SafeActivityOptions.fromBundle(bOptions), userId);
8446 WeakReference<PendingIntentRecord> ref;
8447 ref = mIntentSenderRecords.get(key);
8448 PendingIntentRecord rec = ref != null ? ref.get() : null;
8450 if (!cancelCurrent) {
8451 if (updateCurrent) {
8452 if (rec.key.requestIntent != null) {
8453 rec.key.requestIntent.replaceExtras(intents != null ?
8454 intents[intents.length - 1] : null);
8456 if (intents != null) {
8457 intents[intents.length-1] = rec.key.requestIntent;
8458 rec.key.allIntents = intents;
8459 rec.key.allResolvedTypes = resolvedTypes;
8461 rec.key.allIntents = null;
8462 rec.key.allResolvedTypes = null;
8467 makeIntentSenderCanceledLocked(rec);
8468 mIntentSenderRecords.remove(key);
8473 rec = new PendingIntentRecord(this, key, callingUid);
8474 mIntentSenderRecords.put(key, rec.ref);
8475 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8476 if (activity.pendingResults == null) {
8477 activity.pendingResults
8478 = new HashSet<WeakReference<PendingIntentRecord>>();
8480 activity.pendingResults.add(rec.ref);
8486 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
8487 Intent intent, String resolvedType,
8488 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
8489 if (target instanceof PendingIntentRecord) {
8490 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
8491 whitelistToken, finishedReceiver, requiredPermission, options);
8493 if (intent == null) {
8494 // Weird case: someone has given us their own custom IIntentSender, and now
8495 // they have someone else trying to send to it but of course this isn't
8496 // really a PendingIntent, so there is no base Intent, and the caller isn't
8497 // supplying an Intent... but we never want to dispatch a null Intent to
8498 // a receiver, so um... let's make something up.
8499 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
8500 intent = new Intent(Intent.ACTION_MAIN);
8503 target.send(code, intent, resolvedType, whitelistToken, null,
8504 requiredPermission, options);
8505 } catch (RemoteException e) {
8507 // Platform code can rely on getting a result back when the send is done, but if
8508 // this intent sender is from outside of the system we can't rely on it doing that.
8509 // So instead we don't give it the result receiver, and instead just directly
8510 // report the finish immediately.
8511 if (finishedReceiver != null) {
8513 finishedReceiver.performReceive(intent, 0,
8514 null, null, false, false, UserHandle.getCallingUserId());
8515 } catch (RemoteException e) {
8523 public void cancelIntentSender(IIntentSender sender) {
8524 if (!(sender instanceof PendingIntentRecord)) {
8527 synchronized(this) {
8528 PendingIntentRecord rec = (PendingIntentRecord)sender;
8530 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8531 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8532 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8533 String msg = "Permission Denial: cancelIntentSender() from pid="
8534 + Binder.getCallingPid()
8535 + ", uid=" + Binder.getCallingUid()
8536 + " is not allowed to cancel package "
8537 + rec.key.packageName;
8539 throw new SecurityException(msg);
8541 } catch (RemoteException e) {
8542 throw new SecurityException(e);
8544 cancelIntentSenderLocked(rec, true);
8548 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8549 makeIntentSenderCanceledLocked(rec);
8550 mIntentSenderRecords.remove(rec.key);
8551 if (cleanActivity && rec.key.activity != null) {
8552 rec.key.activity.pendingResults.remove(rec.ref);
8556 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8557 rec.canceled = true;
8558 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8559 if (callbacks != null) {
8560 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8565 public String getPackageForIntentSender(IIntentSender pendingResult) {
8566 if (!(pendingResult instanceof PendingIntentRecord)) {
8570 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8571 return res.key.packageName;
8572 } catch (ClassCastException e) {
8578 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8579 if (!(sender instanceof PendingIntentRecord)) {
8582 boolean isCancelled;
8583 synchronized(this) {
8584 PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
8585 isCancelled = pendingIntent.canceled;
8587 pendingIntent.registerCancelListenerLocked(receiver);
8592 receiver.send(Activity.RESULT_CANCELED, null);
8593 } catch (RemoteException e) {
8599 public void unregisterIntentSenderCancelListener(IIntentSender sender,
8600 IResultReceiver receiver) {
8601 if (!(sender instanceof PendingIntentRecord)) {
8604 synchronized(this) {
8605 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8610 public int getUidForIntentSender(IIntentSender sender) {
8611 if (sender instanceof PendingIntentRecord) {
8613 PendingIntentRecord res = (PendingIntentRecord)sender;
8615 } catch (ClassCastException e) {
8622 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8623 if (!(pendingResult instanceof PendingIntentRecord)) {
8627 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8628 if (res.key.allIntents == null) {
8631 for (int i=0; i<res.key.allIntents.length; i++) {
8632 Intent intent = res.key.allIntents[i];
8633 if (intent.getPackage() != null && intent.getComponent() != null) {
8638 } catch (ClassCastException e) {
8644 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8645 if (!(pendingResult instanceof PendingIntentRecord)) {
8649 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8650 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8654 } catch (ClassCastException e) {
8660 public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8661 if (pendingResult instanceof PendingIntentRecord) {
8662 final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8663 return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8669 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8670 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8671 "getIntentForIntentSender()");
8672 if (!(pendingResult instanceof PendingIntentRecord)) {
8676 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8677 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8678 } catch (ClassCastException e) {
8684 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8685 if (!(pendingResult instanceof PendingIntentRecord)) {
8689 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8690 synchronized (this) {
8691 return getTagForIntentSenderLocked(res, prefix);
8693 } catch (ClassCastException e) {
8698 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8699 final Intent intent = res.key.requestIntent;
8700 if (intent != null) {
8701 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8702 || res.lastTagPrefix.equals(prefix))) {
8705 res.lastTagPrefix = prefix;
8706 final StringBuilder sb = new StringBuilder(128);
8707 if (prefix != null) {
8710 if (intent.getAction() != null) {
8711 sb.append(intent.getAction());
8712 } else if (intent.getComponent() != null) {
8713 intent.getComponent().appendShortString(sb);
8717 return res.lastTag = sb.toString();
8723 public void setProcessLimit(int max) {
8724 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8725 "setProcessLimit()");
8726 synchronized (this) {
8727 mConstants.setOverrideMaxCachedProcesses(max);
8733 public int getProcessLimit() {
8734 synchronized (this) {
8735 return mConstants.getOverrideMaxCachedProcesses();
8739 void importanceTokenDied(ImportanceToken token) {
8740 synchronized (ActivityManagerService.this) {
8741 synchronized (mPidsSelfLocked) {
8743 = mImportantProcesses.get(token.pid);
8747 mImportantProcesses.remove(token.pid);
8748 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8752 pr.forcingToImportant = null;
8753 updateProcessForegroundLocked(pr, false, false);
8755 updateOomAdjLocked();
8760 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8761 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8762 "setProcessImportant()");
8763 synchronized(this) {
8764 boolean changed = false;
8766 synchronized (mPidsSelfLocked) {
8767 ProcessRecord pr = mPidsSelfLocked.get(pid);
8768 if (pr == null && isForeground) {
8769 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8772 ImportanceToken oldToken = mImportantProcesses.get(pid);
8773 if (oldToken != null) {
8774 oldToken.token.unlinkToDeath(oldToken, 0);
8775 mImportantProcesses.remove(pid);
8777 pr.forcingToImportant = null;
8781 if (isForeground && token != null) {
8782 ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8784 public void binderDied() {
8785 importanceTokenDied(this);
8789 token.linkToDeath(newToken, 0);
8790 mImportantProcesses.put(pid, newToken);
8791 pr.forcingToImportant = newToken;
8793 } catch (RemoteException e) {
8794 // If the process died while doing this, we will later
8795 // do the cleanup with the process death link.
8801 updateOomAdjLocked();
8807 public boolean isAppForeground(int uid) {
8808 int callerUid = Binder.getCallingUid();
8809 if (UserHandle.isCore(callerUid) || callerUid == uid) {
8810 return isAppForegroundInternal(uid);
8815 private boolean isAppForegroundInternal(int uid) {
8816 synchronized (this) {
8817 UidRecord uidRec = mActiveUids.get(uid);
8818 if (uidRec == null || uidRec.idle) {
8821 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8825 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8826 // be guarded by permission checking.
8827 int getUidState(int uid) {
8828 synchronized (this) {
8829 return getUidStateLocked(uid);
8833 int getUidStateLocked(int uid) {
8834 UidRecord uidRec = mActiveUids.get(uid);
8835 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8839 public boolean isInMultiWindowMode(IBinder token) {
8840 final long origId = Binder.clearCallingIdentity();
8842 synchronized(this) {
8843 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8847 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8848 return r.inMultiWindowMode();
8851 Binder.restoreCallingIdentity(origId);
8856 public boolean isInPictureInPictureMode(IBinder token) {
8857 final long origId = Binder.clearCallingIdentity();
8859 synchronized(this) {
8860 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8863 Binder.restoreCallingIdentity(origId);
8867 private boolean isInPictureInPictureMode(ActivityRecord r) {
8868 if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8869 || r.getStack().isInStackLocked(r) == null) {
8873 // If we are animating to fullscreen then we have already dispatched the PIP mode
8874 // changed, so we should reflect that check here as well.
8875 final PinnedActivityStack stack = r.getStack();
8876 final PinnedStackWindowController windowController = stack.getWindowContainerController();
8877 return !windowController.isAnimatingBoundsToFullscreen();
8881 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8882 final long origId = Binder.clearCallingIdentity();
8884 synchronized(this) {
8885 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8886 "enterPictureInPictureMode", token, params);
8888 // If the activity is already in picture in picture mode, then just return early
8889 if (isInPictureInPictureMode(r)) {
8893 // Activity supports picture-in-picture, now check that we can enter PiP at this
8895 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8896 false /* beforeStopping */)) {
8900 final Runnable enterPipRunnable = () -> {
8901 // Only update the saved args from the args that are set
8902 r.pictureInPictureArgs.copyOnlySet(params);
8903 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8904 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8905 // Adjust the source bounds by the insets for the transition down
8906 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8907 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8908 "enterPictureInPictureMode");
8909 final PinnedActivityStack stack = r.getStack();
8910 stack.setPictureInPictureAspectRatio(aspectRatio);
8911 stack.setPictureInPictureActions(actions);
8912 MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
8913 r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
8914 logPictureInPictureArgs(params);
8917 if (isKeyguardLocked()) {
8918 // If the keyguard is showing or occluded, then try and dismiss it before
8919 // entering picture-in-picture (this will prompt the user to authenticate if the
8920 // device is currently locked).
8922 dismissKeyguard(token, new KeyguardDismissCallback() {
8924 public void onDismissSucceeded() throws RemoteException {
8925 mHandler.post(enterPipRunnable);
8927 }, null /* message */);
8928 } catch (RemoteException e) {
8932 // Enter picture in picture immediately otherwise
8933 enterPipRunnable.run();
8938 Binder.restoreCallingIdentity(origId);
8943 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8944 final long origId = Binder.clearCallingIdentity();
8946 synchronized(this) {
8947 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8948 "setPictureInPictureParams", token, params);
8950 // Only update the saved args from the args that are set
8951 r.pictureInPictureArgs.copyOnlySet(params);
8952 if (r.inPinnedWindowingMode()) {
8953 // If the activity is already in picture-in-picture, update the pinned stack now
8954 // if it is not already expanding to fullscreen. Otherwise, the arguments will
8955 // be used the next time the activity enters PiP
8956 final PinnedActivityStack stack = r.getStack();
8957 if (!stack.isAnimatingBoundsToFullscreen()) {
8958 stack.setPictureInPictureAspectRatio(
8959 r.pictureInPictureArgs.getAspectRatio());
8960 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8963 logPictureInPictureArgs(params);
8966 Binder.restoreCallingIdentity(origId);
8971 public int getMaxNumPictureInPictureActions(IBinder token) {
8972 // Currently, this is a static constant, but later, we may change this to be dependent on
8973 // the context of the activity
8977 private void logPictureInPictureArgs(PictureInPictureParams params) {
8978 if (params.hasSetActions()) {
8979 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8980 params.getActions().size());
8982 if (params.hasSetAspectRatio()) {
8983 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8984 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8985 MetricsLogger.action(lm);
8990 * Checks the state of the system and the activity associated with the given {@param token} to
8991 * verify that picture-in-picture is supported for that activity.
8993 * @return the activity record for the given {@param token} if all the checks pass.
8995 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8996 IBinder token, PictureInPictureParams params) {
8997 if (!mSupportsPictureInPicture) {
8998 throw new IllegalStateException(caller
8999 + ": Device doesn't support picture-in-picture mode.");
9002 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9004 throw new IllegalStateException(caller
9005 + ": Can't find activity for token=" + token);
9008 if (!r.supportsPictureInPicture()) {
9009 throw new IllegalStateException(caller
9010 + ": Current activity does not support picture-in-picture.");
9013 if (params.hasSetAspectRatio()
9014 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
9015 params.getAspectRatio())) {
9016 final float minAspectRatio = mContext.getResources().getFloat(
9017 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
9018 final float maxAspectRatio = mContext.getResources().getFloat(
9019 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
9020 throw new IllegalArgumentException(String.format(caller
9021 + ": Aspect ratio is too extreme (must be between %f and %f).",
9022 minAspectRatio, maxAspectRatio));
9025 // Truncate the number of actions if necessary
9026 params.truncateActions(getMaxNumPictureInPictureActions(token));
9031 // =========================================================
9033 // =========================================================
9035 static class ProcessInfoService extends IProcessInfoService.Stub {
9036 final ActivityManagerService mActivityManagerService;
9037 ProcessInfoService(ActivityManagerService activityManagerService) {
9038 mActivityManagerService = activityManagerService;
9042 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
9043 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
9044 /*in*/ pids, /*out*/ states, null);
9048 public void getProcessStatesAndOomScoresFromPids(
9049 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
9050 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
9051 /*in*/ pids, /*out*/ states, /*out*/ scores);
9056 * For each PID in the given input array, write the current process state
9057 * for that process into the states array, or -1 to indicate that no
9058 * process with the given PID exists. If scores array is provided, write
9059 * the oom score for the process into the scores array, with INVALID_ADJ
9060 * indicating the PID doesn't exist.
9062 public void getProcessStatesAndOomScoresForPIDs(
9063 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
9064 if (scores != null) {
9065 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
9066 "getProcessStatesAndOomScoresForPIDs()");
9070 throw new NullPointerException("pids");
9071 } else if (states == null) {
9072 throw new NullPointerException("states");
9073 } else if (pids.length != states.length) {
9074 throw new IllegalArgumentException("pids and states arrays have different lengths!");
9075 } else if (scores != null && pids.length != scores.length) {
9076 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
9079 synchronized (mPidsSelfLocked) {
9080 for (int i = 0; i < pids.length; i++) {
9081 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
9082 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
9084 if (scores != null) {
9085 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
9091 // =========================================================
9093 // =========================================================
9095 static class PermissionController extends IPermissionController.Stub {
9096 ActivityManagerService mActivityManagerService;
9097 PermissionController(ActivityManagerService activityManagerService) {
9098 mActivityManagerService = activityManagerService;
9102 public boolean checkPermission(String permission, int pid, int uid) {
9103 return mActivityManagerService.checkPermission(permission, pid,
9104 uid) == PackageManager.PERMISSION_GRANTED;
9108 public int noteOp(String op, int uid, String packageName) {
9109 return mActivityManagerService.mAppOpsService
9110 .noteOperation(AppOpsManager.strOpToOp(op), uid, packageName);
9114 public String[] getPackagesForUid(int uid) {
9115 return mActivityManagerService.mContext.getPackageManager()
9116 .getPackagesForUid(uid);
9120 public boolean isRuntimePermission(String permission) {
9122 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
9123 .getPermissionInfo(permission, 0);
9124 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
9125 == PermissionInfo.PROTECTION_DANGEROUS;
9126 } catch (NameNotFoundException nnfe) {
9127 Slog.e(TAG, "No such permission: "+ permission, nnfe);
9133 public int getPackageUid(String packageName, int flags) {
9135 return mActivityManagerService.mContext.getPackageManager()
9136 .getPackageUid(packageName, flags);
9137 } catch (NameNotFoundException nnfe) {
9143 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
9145 public int checkComponentPermission(String permission, int pid, int uid,
9146 int owningUid, boolean exported) {
9147 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
9148 owningUid, exported);
9152 public Object getAMSLock() {
9153 return ActivityManagerService.this;
9157 int checkComponentPermission(String permission, int pid, int uid,
9158 int owningUid, boolean exported) {
9159 if (pid == MY_PID) {
9160 return PackageManager.PERMISSION_GRANTED;
9162 return ActivityManager.checkComponentPermission(permission, uid,
9163 owningUid, exported);
9167 * As the only public entry point for permissions checking, this method
9168 * can enforce the semantic that requesting a check on a null global
9169 * permission is automatically denied. (Internally a null permission
9170 * string is used when calling {@link #checkComponentPermission} in cases
9171 * when only uid-based security is needed.)
9173 * This can be called with or without the global lock held.
9176 public int checkPermission(String permission, int pid, int uid) {
9177 if (permission == null) {
9178 return PackageManager.PERMISSION_DENIED;
9180 return checkComponentPermission(permission, pid, uid, -1, true);
9184 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
9185 if (permission == null) {
9186 return PackageManager.PERMISSION_DENIED;
9189 // We might be performing an operation on behalf of an indirect binder
9190 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
9191 // client identity accordingly before proceeding.
9192 Identity tlsIdentity = sCallerIdentity.get();
9193 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9194 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
9195 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
9196 uid = tlsIdentity.uid;
9197 pid = tlsIdentity.pid;
9200 return checkComponentPermission(permission, pid, uid, -1, true);
9204 * Binder IPC calls go through the public entry point.
9205 * This can be called with or without the global lock held.
9207 int checkCallingPermission(String permission) {
9208 return checkPermission(permission,
9209 Binder.getCallingPid(),
9210 UserHandle.getAppId(Binder.getCallingUid()));
9214 * This can be called with or without the global lock held.
9216 void enforceCallingPermission(String permission, String func) {
9217 if (checkCallingPermission(permission)
9218 == PackageManager.PERMISSION_GRANTED) {
9222 String msg = "Permission Denial: " + func + " from pid="
9223 + Binder.getCallingPid()
9224 + ", uid=" + Binder.getCallingUid()
9225 + " requires " + permission;
9227 throw new SecurityException(msg);
9231 * This can be called with or without the global lock held.
9233 void enforcePermission(String permission, int pid, int uid, String func) {
9234 if (checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) {
9238 String msg = "Permission Denial: " + func + " from pid=" + pid + ", uid=" + uid
9239 + " requires " + permission;
9241 throw new SecurityException(msg);
9245 * This can be called with or without the global lock held.
9247 void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
9248 if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
9249 enforceCallingPermission(permission, func);
9254 * Determine if UID is holding permissions required to access {@link Uri} in
9255 * the given {@link ProviderInfo}. Final permission checking is always done
9256 * in {@link ContentProvider}.
9258 private final boolean checkHoldingPermissionsLocked(
9259 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
9260 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9261 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
9262 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
9263 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
9264 != PERMISSION_GRANTED) {
9268 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
9271 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
9272 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
9273 if (pi.applicationInfo.uid == uid) {
9275 } else if (!pi.exported) {
9279 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
9280 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
9282 // check if target holds top-level <provider> permissions
9283 if (!readMet && pi.readPermission != null && considerUidPermissions
9284 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
9287 if (!writeMet && pi.writePermission != null && considerUidPermissions
9288 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
9292 // track if unprotected read/write is allowed; any denied
9293 // <path-permission> below removes this ability
9294 boolean allowDefaultRead = pi.readPermission == null;
9295 boolean allowDefaultWrite = pi.writePermission == null;
9297 // check if target holds any <path-permission> that match uri
9298 final PathPermission[] pps = pi.pathPermissions;
9300 final String path = grantUri.uri.getPath();
9302 while (i > 0 && (!readMet || !writeMet)) {
9304 PathPermission pp = pps[i];
9305 if (pp.match(path)) {
9307 final String pprperm = pp.getReadPermission();
9308 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9309 "Checking read perm for " + pprperm + " for " + pp.getPath()
9310 + ": match=" + pp.match(path)
9311 + " check=" + pm.checkUidPermission(pprperm, uid));
9312 if (pprperm != null) {
9313 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
9314 == PERMISSION_GRANTED) {
9317 allowDefaultRead = false;
9322 final String ppwperm = pp.getWritePermission();
9323 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9324 "Checking write perm " + ppwperm + " for " + pp.getPath()
9325 + ": match=" + pp.match(path)
9326 + " check=" + pm.checkUidPermission(ppwperm, uid));
9327 if (ppwperm != null) {
9328 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
9329 == PERMISSION_GRANTED) {
9332 allowDefaultWrite = false;
9340 // grant unprotected <provider> read/write, if not blocked by
9341 // <path-permission> above
9342 if (allowDefaultRead) readMet = true;
9343 if (allowDefaultWrite) writeMet = true;
9345 } catch (RemoteException e) {
9349 return readMet && writeMet;
9352 public boolean isAppStartModeDisabled(int uid, String packageName) {
9353 synchronized (this) {
9354 return getAppStartModeLocked(uid, packageName, 0, -1, false, true, false)
9355 == ActivityManager.APP_START_MODE_DISABLED;
9359 // Unified app-op and target sdk check
9360 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9361 // Apps that target O+ are always subject to background check
9362 if (packageTargetSdk >= Build.VERSION_CODES.O) {
9363 if (DEBUG_BACKGROUND_CHECK) {
9364 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
9366 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9368 // ...and legacy apps get an AppOp check
9369 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
9371 if (DEBUG_BACKGROUND_CHECK) {
9372 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
9375 case AppOpsManager.MODE_ALLOWED:
9376 // If force-background-check is enabled, restrict all apps that aren't whitelisted.
9377 if (mForceBackgroundCheck &&
9378 !UserHandle.isCore(uid) &&
9379 !isOnDeviceIdleWhitelistLocked(uid, /*allowExceptIdleToo=*/ true)) {
9380 if (DEBUG_BACKGROUND_CHECK) {
9381 Slog.i(TAG, "Force background check: " +
9382 uid + "/" + packageName + " restricted");
9384 return ActivityManager.APP_START_MODE_DELAYED;
9386 return ActivityManager.APP_START_MODE_NORMAL;
9387 case AppOpsManager.MODE_IGNORED:
9388 return ActivityManager.APP_START_MODE_DELAYED;
9390 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9394 // Service launch is available to apps with run-in-background exemptions but
9395 // some other background operations are not. If we're doing a check
9396 // of service-launch policy, allow those callers to proceed unrestricted.
9397 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9399 if (mPackageManagerInt.isPackagePersistent(packageName)) {
9400 if (DEBUG_BACKGROUND_CHECK) {
9401 Slog.i(TAG, "App " + uid + "/" + packageName
9402 + " is persistent; not restricted in background");
9404 return ActivityManager.APP_START_MODE_NORMAL;
9407 // Non-persistent but background whitelisted?
9408 if (uidOnBackgroundWhitelist(uid)) {
9409 if (DEBUG_BACKGROUND_CHECK) {
9410 Slog.i(TAG, "App " + uid + "/" + packageName
9411 + " on background whitelist; not restricted in background");
9413 return ActivityManager.APP_START_MODE_NORMAL;
9416 // Is this app on the battery whitelist?
9417 if (isOnDeviceIdleWhitelistLocked(uid, /*allowExceptIdleToo=*/ false)) {
9418 if (DEBUG_BACKGROUND_CHECK) {
9419 Slog.i(TAG, "App " + uid + "/" + packageName
9420 + " on idle whitelist; not restricted in background");
9422 return ActivityManager.APP_START_MODE_NORMAL;
9425 // None of the service-policy criteria apply, so we apply the common criteria
9426 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
9429 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
9430 int callingPid, boolean alwaysRestrict, boolean disabledOnly, boolean forcedStandby) {
9431 UidRecord uidRec = mActiveUids.get(uid);
9432 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
9433 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
9434 + (uidRec != null ? uidRec.idle : false));
9435 if (uidRec == null || alwaysRestrict || forcedStandby || uidRec.idle) {
9437 if (uidRec == null) {
9438 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
9439 UserHandle.getUserId(uid), packageName);
9441 ephemeral = uidRec.ephemeral;
9445 // We are hard-core about ephemeral apps not running in the background.
9446 return ActivityManager.APP_START_MODE_DISABLED;
9449 // The caller is only interested in whether app starts are completely
9450 // disabled for the given package (that is, it is an instant app). So
9451 // we don't need to go further, which is all just seeing if we should
9452 // apply a "delayed" mode for a regular app.
9453 return ActivityManager.APP_START_MODE_NORMAL;
9455 final int startMode = (alwaysRestrict)
9456 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
9457 : appServicesRestrictedInBackgroundLocked(uid, packageName,
9459 if (DEBUG_BACKGROUND_CHECK) {
9460 Slog.d(TAG, "checkAllowBackground: uid=" + uid
9461 + " pkg=" + packageName + " startMode=" + startMode
9462 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid, false)
9463 + " onwhitelist(ei)=" + isOnDeviceIdleWhitelistLocked(uid, true));
9465 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
9466 // This is an old app that has been forced into a "compatible as possible"
9467 // mode of background check. To increase compatibility, we will allow other
9468 // foreground apps to cause its services to start.
9469 if (callingPid >= 0) {
9471 synchronized (mPidsSelfLocked) {
9472 proc = mPidsSelfLocked.get(callingPid);
9475 !ActivityManager.isProcStateBackground(proc.curProcState)) {
9476 // Whoever is instigating this is in the foreground, so we will allow it
9478 return ActivityManager.APP_START_MODE_NORMAL;
9485 return ActivityManager.APP_START_MODE_NORMAL;
9489 * @return whether a UID is in the system, user or temp doze whitelist.
9491 boolean isOnDeviceIdleWhitelistLocked(int uid, boolean allowExceptIdleToo) {
9492 final int appId = UserHandle.getAppId(uid);
9494 final int[] whitelist = allowExceptIdleToo
9495 ? mDeviceIdleExceptIdleWhitelist
9496 : mDeviceIdleWhitelist;
9498 return Arrays.binarySearch(whitelist, appId) >= 0
9499 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9500 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9503 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9504 ProviderInfo pi = null;
9505 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9510 pi = AppGlobals.getPackageManager().resolveContentProvider(
9511 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9513 } catch (RemoteException ex) {
9519 void grantEphemeralAccessLocked(int userId, Intent intent,
9520 int targetAppId, int ephemeralAppId) {
9521 getPackageManagerInternalLocked().
9522 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
9526 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
9527 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9528 if (targetUris != null) {
9529 return targetUris.get(grantUri);
9535 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
9536 String targetPkg, int targetUid, GrantUri grantUri) {
9537 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9538 if (targetUris == null) {
9539 targetUris = Maps.newArrayMap();
9540 mGrantedUriPermissions.put(targetUid, targetUris);
9543 UriPermission perm = targetUris.get(grantUri);
9545 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9546 targetUris.put(grantUri, perm);
9553 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
9554 final int modeFlags) {
9555 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
9556 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9557 : UriPermission.STRENGTH_OWNED;
9559 // Root gets to do everything.
9564 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9565 if (perms == null) return false;
9567 // First look for exact match
9568 final UriPermission exactPerm = perms.get(grantUri);
9569 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9573 // No exact match, look for prefixes
9574 final int N = perms.size();
9575 for (int i = 0; i < N; i++) {
9576 final UriPermission perm = perms.valueAt(i);
9577 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9578 && perm.getStrength(modeFlags) >= minStrength) {
9587 * @param uri This uri must NOT contain an embedded userId.
9588 * @param userId The userId in which the uri is to be resolved.
9591 public int checkUriPermission(Uri uri, int pid, int uid,
9592 final int modeFlags, int userId, IBinder callerToken) {
9593 enforceNotIsolatedCaller("checkUriPermission");
9595 // Another redirected-binder-call permissions check as in
9596 // {@link checkPermissionWithToken}.
9597 Identity tlsIdentity = sCallerIdentity.get();
9598 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9599 uid = tlsIdentity.uid;
9600 pid = tlsIdentity.pid;
9603 // Our own process gets to do everything.
9604 if (pid == MY_PID) {
9605 return PackageManager.PERMISSION_GRANTED;
9607 synchronized (this) {
9608 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9609 ? PackageManager.PERMISSION_GRANTED
9610 : PackageManager.PERMISSION_DENIED;
9615 * Check if the targetPkg can be granted permission to access uri by
9616 * the callingUid using the given modeFlags. Throws a security exception
9617 * if callingUid is not allowed to do this. Returns the uid of the target
9618 * if the URI permission grant should be performed; returns -1 if it is not
9619 * needed (for example targetPkg already has permission to access the URI).
9620 * If you already know the uid of the target, you can supply it in
9621 * lastTargetUid else set that to -1.
9624 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9625 final int modeFlags, int lastTargetUid) {
9626 if (!Intent.isAccessUriMode(modeFlags)) {
9630 if (targetPkg != null) {
9631 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9632 "Checking grant " + targetPkg + " permission to " + grantUri);
9635 final IPackageManager pm = AppGlobals.getPackageManager();
9637 // If this is not a content: uri, we can't do anything with it.
9638 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9639 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9640 "Can't grant URI permission for non-content URI: " + grantUri);
9644 // Bail early if system is trying to hand out permissions directly; it
9645 // must always grant permissions on behalf of someone explicit.
9646 final int callingAppId = UserHandle.getAppId(callingUid);
9647 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9648 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9649 // Exempted authority for
9650 // 1. cropping user photos and sharing a generated license html
9651 // file in Settings app
9652 // 2. sharing a generated license html file in TvSettings app
9654 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9655 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9660 final String authority = grantUri.uri.getAuthority();
9661 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9662 MATCH_DEBUG_TRIAGED_MISSING);
9664 Slog.w(TAG, "No content provider found for permission check: " +
9665 grantUri.uri.toSafeString());
9669 int targetUid = lastTargetUid;
9670 if (targetUid < 0 && targetPkg != null) {
9672 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9673 UserHandle.getUserId(callingUid));
9674 if (targetUid < 0) {
9675 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9676 "Can't grant URI permission no uid for: " + targetPkg);
9679 } catch (RemoteException ex) {
9684 // Figure out the value returned when access is allowed
9685 final int allowedResult;
9686 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9687 // If we're extending a persistable grant, then we need to return
9688 // "targetUid" so that we always create a grant data structure to
9689 // support take/release APIs
9690 allowedResult = targetUid;
9692 // Otherwise, we can return "-1" to indicate that no grant data
9693 // structures need to be created
9697 if (targetUid >= 0) {
9698 // First... does the target actually need this permission?
9699 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9700 // No need to grant the target this permission.
9701 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9702 "Target " + targetPkg + " already has full permission to " + grantUri);
9703 return allowedResult;
9706 // First... there is no target package, so can anyone access it?
9707 boolean allowed = pi.exported;
9708 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9709 if (pi.readPermission != null) {
9713 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9714 if (pi.writePermission != null) {
9718 if (pi.pathPermissions != null) {
9719 final int N = pi.pathPermissions.length;
9720 for (int i=0; i<N; i++) {
9721 if (pi.pathPermissions[i] != null
9722 && pi.pathPermissions[i].match(grantUri.uri.getPath())) {
9723 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9724 if (pi.pathPermissions[i].getReadPermission() != null) {
9728 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9729 if (pi.pathPermissions[i].getWritePermission() != null) {
9738 return allowedResult;
9742 /* There is a special cross user grant if:
9743 * - The target is on another user.
9744 * - Apps on the current user can access the uri without any uid permissions.
9745 * In this case, we grant a uri permission, even if the ContentProvider does not normally
9746 * grant uri permissions.
9748 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9749 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9750 modeFlags, false /*without considering the uid permissions*/);
9752 // Second... is the provider allowing granting of URI permissions?
9753 if (!specialCrossUserGrant) {
9754 if (!pi.grantUriPermissions) {
9755 throw new SecurityException("Provider " + pi.packageName
9757 + " does not allow granting of Uri permissions (uri "
9760 if (pi.uriPermissionPatterns != null) {
9761 final int N = pi.uriPermissionPatterns.length;
9762 boolean allowed = false;
9763 for (int i=0; i<N; i++) {
9764 if (pi.uriPermissionPatterns[i] != null
9765 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9771 throw new SecurityException("Provider " + pi.packageName
9773 + " does not allow granting of permission to path of Uri "
9779 // Third... does the caller itself have permission to access
9781 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9782 // Require they hold a strong enough Uri permission
9783 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9784 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9785 throw new SecurityException(
9786 "UID " + callingUid + " does not have permission to " + grantUri
9787 + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9788 + "or related APIs");
9790 throw new SecurityException(
9791 "UID " + callingUid + " does not have permission to " + grantUri);
9799 * @param uri This uri must NOT contain an embedded userId.
9800 * @param userId The userId in which the uri is to be resolved.
9803 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9804 final int modeFlags, int userId) {
9805 enforceNotIsolatedCaller("checkGrantUriPermission");
9806 synchronized(this) {
9807 return checkGrantUriPermissionLocked(callingUid, targetPkg,
9808 new GrantUri(userId, uri, false), modeFlags, -1);
9813 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9814 final int modeFlags, UriPermissionOwner owner) {
9815 if (!Intent.isAccessUriMode(modeFlags)) {
9819 // So here we are: the caller has the assumed permission
9820 // to the uri, and the target doesn't. Let's now give this to
9823 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9824 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9826 final String authority = grantUri.uri.getAuthority();
9827 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9828 MATCH_DEBUG_TRIAGED_MISSING);
9830 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9834 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9835 grantUri.prefix = true;
9837 final UriPermission perm = findOrCreateUriPermissionLocked(
9838 pi.packageName, targetPkg, targetUid, grantUri);
9839 perm.grantModes(modeFlags, owner);
9843 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9844 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9845 if (targetPkg == null) {
9846 throw new NullPointerException("targetPkg");
9849 final IPackageManager pm = AppGlobals.getPackageManager();
9851 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9852 } catch (RemoteException ex) {
9856 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9858 if (targetUid < 0) {
9862 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9866 static class NeededUriGrants extends ArrayList<GrantUri> {
9867 final String targetPkg;
9868 final int targetUid;
9871 NeededUriGrants(String targetPkg, int targetUid, int flags) {
9872 this.targetPkg = targetPkg;
9873 this.targetUid = targetUid;
9877 void writeToProto(ProtoOutputStream proto, long fieldId) {
9878 long token = proto.start(fieldId);
9879 proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9880 proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9881 proto.write(NeededUriGrantsProto.FLAGS, flags);
9883 final int N = this.size();
9884 for (int i=0; i<N; i++) {
9885 this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9892 * Like checkGrantUriPermissionLocked, but takes an Intent.
9895 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9896 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9897 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9898 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9899 + " clip=" + (intent != null ? intent.getClipData() : null)
9900 + " from " + intent + "; flags=0x"
9901 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9903 if (targetPkg == null) {
9904 throw new NullPointerException("targetPkg");
9907 if (intent == null) {
9910 Uri data = intent.getData();
9911 ClipData clip = intent.getClipData();
9912 if (data == null && clip == null) {
9915 // Default userId for uris in the intent (if they don't specify it themselves)
9916 int contentUserHint = intent.getContentUserHint();
9917 if (contentUserHint == UserHandle.USER_CURRENT) {
9918 contentUserHint = UserHandle.getUserId(callingUid);
9920 final IPackageManager pm = AppGlobals.getPackageManager();
9922 if (needed != null) {
9923 targetUid = needed.targetUid;
9926 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9928 } catch (RemoteException ex) {
9931 if (targetUid < 0) {
9932 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9933 "Can't grant URI permission no uid for: " + targetPkg
9934 + " on user " + targetUserId);
9939 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9940 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9942 if (targetUid > 0) {
9943 if (needed == null) {
9944 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9946 needed.add(grantUri);
9950 for (int i=0; i<clip.getItemCount(); i++) {
9951 Uri uri = clip.getItemAt(i).getUri();
9953 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9954 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9956 if (targetUid > 0) {
9957 if (needed == null) {
9958 needed = new NeededUriGrants(targetPkg, targetUid, mode);
9960 needed.add(grantUri);
9963 Intent clipIntent = clip.getItemAt(i).getIntent();
9964 if (clipIntent != null) {
9965 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9966 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9967 if (newNeeded != null) {
9979 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9982 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9983 UriPermissionOwner owner) {
9984 if (needed != null) {
9985 for (int i=0; i<needed.size(); i++) {
9986 GrantUri grantUri = needed.get(i);
9987 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9988 grantUri, needed.flags, owner);
9994 void grantUriPermissionFromIntentLocked(int callingUid,
9995 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9996 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9997 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9998 if (needed == null) {
10002 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
10006 * @param uri This uri must NOT contain an embedded userId.
10007 * @param userId The userId in which the uri is to be resolved.
10010 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
10011 final int modeFlags, int userId) {
10012 enforceNotIsolatedCaller("grantUriPermission");
10013 GrantUri grantUri = new GrantUri(userId, uri, false);
10014 synchronized(this) {
10015 final ProcessRecord r = getRecordForAppLocked(caller);
10017 throw new SecurityException("Unable to find app for caller "
10019 + " when granting permission to uri " + grantUri);
10021 if (targetPkg == null) {
10022 throw new IllegalArgumentException("null target");
10024 if (grantUri == null) {
10025 throw new IllegalArgumentException("null uri");
10028 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
10029 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
10030 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
10031 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
10033 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
10034 UserHandle.getUserId(r.uid));
10039 void removeUriPermissionIfNeededLocked(UriPermission perm) {
10040 if (perm.modeFlags == 0) {
10041 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10043 if (perms != null) {
10044 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10045 "Removing " + perm.targetUid + " permission to " + perm.uri);
10047 perms.remove(perm.uri);
10048 if (perms.isEmpty()) {
10049 mGrantedUriPermissions.remove(perm.targetUid);
10056 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
10057 final int modeFlags) {
10058 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10059 "Revoking all granted permissions to " + grantUri);
10061 final IPackageManager pm = AppGlobals.getPackageManager();
10062 final String authority = grantUri.uri.getAuthority();
10063 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
10064 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
10066 Slog.w(TAG, "No content provider found for permission revoke: "
10067 + grantUri.toSafeString());
10071 // Does the caller have this permission on the URI?
10072 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
10073 // If they don't have direct access to the URI, then revoke any
10074 // ownerless URI permissions that have been granted to them.
10075 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10076 if (perms != null) {
10077 boolean persistChanged = false;
10078 for (int i = perms.size()-1; i >= 0; i--) {
10079 final UriPermission perm = perms.valueAt(i);
10080 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
10083 if (perm.uri.sourceUserId == grantUri.sourceUserId
10084 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
10085 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10086 "Revoking non-owned " + perm.targetUid
10087 + " permission to " + perm.uri);
10088 persistChanged |= perm.revokeModes(
10089 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
10090 if (perm.modeFlags == 0) {
10095 if (perms.isEmpty()) {
10096 mGrantedUriPermissions.remove(callingUid);
10098 if (persistChanged) {
10099 schedulePersistUriGrants();
10105 boolean persistChanged = false;
10107 // Go through all of the permissions and remove any that match.
10108 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
10109 final int targetUid = mGrantedUriPermissions.keyAt(i);
10110 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10112 for (int j = perms.size()-1; j >= 0; j--) {
10113 final UriPermission perm = perms.valueAt(j);
10114 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
10117 if (perm.uri.sourceUserId == grantUri.sourceUserId
10118 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
10119 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10120 "Revoking " + perm.targetUid + " permission to " + perm.uri);
10121 persistChanged |= perm.revokeModes(
10122 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
10123 targetPackage == null);
10124 if (perm.modeFlags == 0) {
10130 if (perms.isEmpty()) {
10131 mGrantedUriPermissions.removeAt(i);
10135 if (persistChanged) {
10136 schedulePersistUriGrants();
10141 * @param uri This uri must NOT contain an embedded userId.
10142 * @param userId The userId in which the uri is to be resolved.
10145 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
10146 final int modeFlags, int userId) {
10147 enforceNotIsolatedCaller("revokeUriPermission");
10148 synchronized(this) {
10149 final ProcessRecord r = getRecordForAppLocked(caller);
10151 throw new SecurityException("Unable to find app for caller "
10153 + " when revoking permission to uri " + uri);
10156 Slog.w(TAG, "revokeUriPermission: null uri");
10160 if (!Intent.isAccessUriMode(modeFlags)) {
10164 final String authority = uri.getAuthority();
10165 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
10166 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
10168 Slog.w(TAG, "No content provider found for permission revoke: "
10169 + uri.toSafeString());
10173 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
10179 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
10182 * @param packageName Package name to match, or {@code null} to apply to all
10184 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
10186 * @param persistable If persistable grants should be removed.
10187 * @param targetOnly When {@code true}, only remove permissions where the app is the target,
10191 private void removeUriPermissionsForPackageLocked(
10192 String packageName, int userHandle, boolean persistable, boolean targetOnly) {
10193 if (userHandle == UserHandle.USER_ALL && packageName == null) {
10194 throw new IllegalArgumentException("Must narrow by either package or user");
10197 boolean persistChanged = false;
10199 int N = mGrantedUriPermissions.size();
10200 for (int i = 0; i < N; i++) {
10201 final int targetUid = mGrantedUriPermissions.keyAt(i);
10202 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10204 // Only inspect grants matching user
10205 if (userHandle == UserHandle.USER_ALL
10206 || userHandle == UserHandle.getUserId(targetUid)) {
10207 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
10208 final UriPermission perm = it.next();
10210 // Only inspect grants matching package
10211 if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
10212 || perm.targetPkg.equals(packageName)) {
10213 // Hacky solution as part of fixing a security bug; ignore
10214 // grants associated with DownloadManager so we don't have
10215 // to immediately launch it to regrant the permissions
10216 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
10217 && !persistable) continue;
10219 persistChanged |= perm.revokeModes(persistable
10220 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
10222 // Only remove when no modes remain; any persisted grants
10223 // will keep this alive.
10224 if (perm.modeFlags == 0) {
10230 if (perms.isEmpty()) {
10231 mGrantedUriPermissions.remove(targetUid);
10238 if (persistChanged) {
10239 schedulePersistUriGrants();
10244 public IBinder newUriPermissionOwner(String name) {
10245 enforceNotIsolatedCaller("newUriPermissionOwner");
10246 synchronized(this) {
10247 UriPermissionOwner owner = new UriPermissionOwner(this, name);
10248 return owner.getExternalTokenLocked();
10253 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
10254 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
10255 synchronized(this) {
10256 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10258 throw new IllegalArgumentException("Activity does not exist; token="
10261 return r.getUriPermissionsLocked().getExternalTokenLocked();
10265 * @param uri This uri must NOT contain an embedded userId.
10266 * @param sourceUserId The userId in which the uri is to be resolved.
10267 * @param targetUserId The userId of the app that receives the grant.
10270 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
10271 final int modeFlags, int sourceUserId, int targetUserId) {
10272 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
10273 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
10274 "grantUriPermissionFromOwner", null);
10275 synchronized(this) {
10276 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10277 if (owner == null) {
10278 throw new IllegalArgumentException("Unknown owner: " + token);
10280 if (fromUid != Binder.getCallingUid()) {
10281 if (Binder.getCallingUid() != myUid()) {
10282 // Only system code can grant URI permissions on behalf
10284 throw new SecurityException("nice try");
10287 if (targetPkg == null) {
10288 throw new IllegalArgumentException("null target");
10291 throw new IllegalArgumentException("null uri");
10294 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
10295 modeFlags, owner, targetUserId);
10300 * @param uri This uri must NOT contain an embedded userId.
10301 * @param userId The userId in which the uri is to be resolved.
10304 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
10305 synchronized(this) {
10306 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10307 if (owner == null) {
10308 throw new IllegalArgumentException("Unknown owner: " + token);
10312 owner.removeUriPermissionsLocked(mode);
10314 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
10315 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
10320 private void schedulePersistUriGrants() {
10321 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
10322 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
10323 10 * DateUtils.SECOND_IN_MILLIS);
10327 private void writeGrantedUriPermissions() {
10328 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
10330 final long startTime = SystemClock.uptimeMillis();
10332 // Snapshot permissions so we can persist without lock
10333 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
10334 synchronized (this) {
10335 final int size = mGrantedUriPermissions.size();
10336 for (int i = 0; i < size; i++) {
10337 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10338 for (UriPermission perm : perms.values()) {
10339 if (perm.persistedModeFlags != 0) {
10340 persist.add(perm.snapshot());
10346 FileOutputStream fos = null;
10348 fos = mGrantFile.startWrite(startTime);
10350 XmlSerializer out = new FastXmlSerializer();
10351 out.setOutput(fos, StandardCharsets.UTF_8.name());
10352 out.startDocument(null, true);
10353 out.startTag(null, TAG_URI_GRANTS);
10354 for (UriPermission.Snapshot perm : persist) {
10355 out.startTag(null, TAG_URI_GRANT);
10356 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
10357 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
10358 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
10359 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
10360 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
10361 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
10362 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
10363 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
10364 out.endTag(null, TAG_URI_GRANT);
10366 out.endTag(null, TAG_URI_GRANTS);
10369 mGrantFile.finishWrite(fos);
10370 } catch (IOException e) {
10372 mGrantFile.failWrite(fos);
10378 private void readGrantedUriPermissionsLocked() {
10379 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
10381 final long now = System.currentTimeMillis();
10383 FileInputStream fis = null;
10385 fis = mGrantFile.openRead();
10386 final XmlPullParser in = Xml.newPullParser();
10387 in.setInput(fis, StandardCharsets.UTF_8.name());
10390 while ((type = in.next()) != END_DOCUMENT) {
10391 final String tag = in.getName();
10392 if (type == START_TAG) {
10393 if (TAG_URI_GRANT.equals(tag)) {
10394 final int sourceUserId;
10395 final int targetUserId;
10396 final int userHandle = readIntAttribute(in,
10397 ATTR_USER_HANDLE, UserHandle.USER_NULL);
10398 if (userHandle != UserHandle.USER_NULL) {
10399 // For backwards compatibility.
10400 sourceUserId = userHandle;
10401 targetUserId = userHandle;
10403 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
10404 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
10406 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
10407 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
10408 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
10409 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
10410 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
10411 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
10413 // Sanity check that provider still belongs to source package
10414 // Both direct boot aware and unaware packages are fine as we
10415 // will do filtering at query time to avoid multiple parsing.
10416 final ProviderInfo pi = getProviderInfoLocked(
10417 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
10418 | MATCH_DIRECT_BOOT_UNAWARE);
10419 if (pi != null && sourcePkg.equals(pi.packageName)) {
10420 int targetUid = -1;
10422 targetUid = AppGlobals.getPackageManager().getPackageUid(
10423 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
10424 } catch (RemoteException e) {
10426 if (targetUid != -1) {
10427 final UriPermission perm = findOrCreateUriPermissionLocked(
10428 sourcePkg, targetPkg, targetUid,
10429 new GrantUri(sourceUserId, uri, prefix));
10430 perm.initPersistedModes(modeFlags, createdTime);
10433 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
10434 + " but instead found " + pi);
10439 } catch (FileNotFoundException e) {
10440 // Missing grants is okay
10441 } catch (IOException e) {
10442 Slog.wtf(TAG, "Failed reading Uri grants", e);
10443 } catch (XmlPullParserException e) {
10444 Slog.wtf(TAG, "Failed reading Uri grants", e);
10446 IoUtils.closeQuietly(fis);
10451 * @param uri This uri must NOT contain an embedded userId.
10452 * @param toPackage Name of package whose uri is being granted to (if {@code null}, uses
10454 * @param userId The userId in which the uri is to be resolved.
10457 public void takePersistableUriPermission(Uri uri, final int modeFlags,
10458 @Nullable String toPackage, int userId) {
10460 if (toPackage != null) {
10461 enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10462 "takePersistableUriPermission");
10463 uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10465 enforceNotIsolatedCaller("takePersistableUriPermission");
10466 uid = Binder.getCallingUid();
10469 Preconditions.checkFlagsArgument(modeFlags,
10470 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10472 synchronized (this) {
10473 boolean persistChanged = false;
10474 GrantUri grantUri = new GrantUri(userId, uri, false);
10476 UriPermission exactPerm = findUriPermissionLocked(uid, grantUri);
10477 UriPermission prefixPerm = findUriPermissionLocked(uid,
10478 new GrantUri(userId, uri, true));
10480 final boolean exactValid = (exactPerm != null)
10481 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
10482 final boolean prefixValid = (prefixPerm != null)
10483 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
10485 if (!(exactValid || prefixValid)) {
10486 throw new SecurityException("No persistable permission grants found for UID "
10487 + uid + " and Uri " + grantUri.toSafeString());
10491 persistChanged |= exactPerm.takePersistableModes(modeFlags);
10494 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
10497 persistChanged |= maybePrunePersistedUriGrantsLocked(uid);
10499 if (persistChanged) {
10500 schedulePersistUriGrants();
10506 * @param uri This uri must NOT contain an embedded userId.
10507 * @param toPackage Name of the target package whose uri is being released (if {@code null},
10508 * uses calling uid)
10509 * @param userId The userId in which the uri is to be resolved.
10512 public void releasePersistableUriPermission(Uri uri, final int modeFlags,
10513 @Nullable String toPackage, int userId) {
10516 if (toPackage != null) {
10517 enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10518 "releasePersistableUriPermission");
10519 uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10521 enforceNotIsolatedCaller("releasePersistableUriPermission");
10522 uid = Binder.getCallingUid();
10525 Preconditions.checkFlagsArgument(modeFlags,
10526 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10528 synchronized (this) {
10529 boolean persistChanged = false;
10531 UriPermission exactPerm = findUriPermissionLocked(uid,
10532 new GrantUri(userId, uri, false));
10533 UriPermission prefixPerm = findUriPermissionLocked(uid,
10534 new GrantUri(userId, uri, true));
10535 if (exactPerm == null && prefixPerm == null && toPackage == null) {
10536 throw new SecurityException("No permission grants found for UID " + uid
10537 + " and Uri " + uri.toSafeString());
10540 if (exactPerm != null) {
10541 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10542 removeUriPermissionIfNeededLocked(exactPerm);
10544 if (prefixPerm != null) {
10545 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10546 removeUriPermissionIfNeededLocked(prefixPerm);
10549 if (persistChanged) {
10550 schedulePersistUriGrants();
10556 * Prune any older {@link UriPermission} for the given UID until outstanding
10557 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10559 * @return if any mutations occured that require persisting.
10562 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
10563 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
10564 if (perms == null) return false;
10565 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
10567 final ArrayList<UriPermission> persisted = Lists.newArrayList();
10568 for (UriPermission perm : perms.values()) {
10569 if (perm.persistedModeFlags != 0) {
10570 persisted.add(perm);
10574 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10575 if (trimCount <= 0) return false;
10577 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10578 for (int i = 0; i < trimCount; i++) {
10579 final UriPermission perm = persisted.get(i);
10581 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10582 "Trimming grant created at " + perm.persistedCreateTime);
10584 perm.releasePersistableModes(~0);
10585 removeUriPermissionIfNeededLocked(perm);
10592 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10593 String packageName, boolean incoming) {
10594 enforceNotIsolatedCaller("getPersistedUriPermissions");
10595 Preconditions.checkNotNull(packageName, "packageName");
10597 final int callingUid = Binder.getCallingUid();
10598 final int callingUserId = UserHandle.getUserId(callingUid);
10599 final IPackageManager pm = AppGlobals.getPackageManager();
10601 final int packageUid = pm.getPackageUid(packageName,
10602 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
10603 if (packageUid != callingUid) {
10604 throw new SecurityException(
10605 "Package " + packageName + " does not belong to calling UID " + callingUid);
10607 } catch (RemoteException e) {
10608 throw new SecurityException("Failed to verify package name ownership");
10611 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10612 synchronized (this) {
10614 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10616 if (perms == null) {
10617 Slog.w(TAG, "No permission grants found for " + packageName);
10619 for (int j = 0; j < perms.size(); j++) {
10620 final UriPermission perm = perms.valueAt(j);
10621 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10622 result.add(perm.buildPersistedPublicApiObject());
10627 final int size = mGrantedUriPermissions.size();
10628 for (int i = 0; i < size; i++) {
10629 final ArrayMap<GrantUri, UriPermission> perms =
10630 mGrantedUriPermissions.valueAt(i);
10631 for (int j = 0; j < perms.size(); j++) {
10632 final UriPermission perm = perms.valueAt(j);
10633 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10634 result.add(perm.buildPersistedPublicApiObject());
10640 return new ParceledListSlice<android.content.UriPermission>(result);
10644 public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
10645 @Nullable String packageName, int userId) {
10646 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10647 "getGrantedUriPermissions");
10649 final List<GrantedUriPermission> result = new ArrayList<>();
10650 synchronized (this) {
10651 final int size = mGrantedUriPermissions.size();
10652 for (int i = 0; i < size; i++) {
10653 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10654 for (int j = 0; j < perms.size(); j++) {
10655 final UriPermission perm = perms.valueAt(j);
10656 if ((packageName == null || packageName.equals(perm.targetPkg))
10657 && perm.targetUserId == userId
10658 && perm.persistedModeFlags != 0) {
10659 result.add(perm.buildGrantedUriPermission());
10664 return new ParceledListSlice<>(result);
10668 public void clearGrantedUriPermissions(String packageName, int userId) {
10669 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10670 "clearGrantedUriPermissions");
10671 synchronized(this) {
10672 removeUriPermissionsForPackageLocked(packageName, userId, true, true);
10677 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10678 synchronized (this) {
10679 ProcessRecord app =
10680 who != null ? getRecordForAppLocked(who) : null;
10681 if (app == null) return;
10683 Message msg = Message.obtain();
10684 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10686 msg.arg1 = waiting ? 1 : 0;
10687 mUiHandler.sendMessage(msg);
10692 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10693 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10694 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10695 outInfo.availMem = getFreeMemory();
10696 outInfo.totalMem = getTotalMemory();
10697 outInfo.threshold = homeAppMem;
10698 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10699 outInfo.hiddenAppThreshold = cachedAppMem;
10700 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10701 ProcessList.SERVICE_ADJ);
10702 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10703 ProcessList.VISIBLE_APP_ADJ);
10704 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10705 ProcessList.FOREGROUND_APP_ADJ);
10708 // =========================================================
10710 // =========================================================
10713 public List<IBinder> getAppTasks(String callingPackage) {
10714 int callingUid = Binder.getCallingUid();
10715 long ident = Binder.clearCallingIdentity();
10717 synchronized(this) {
10718 return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10721 Binder.restoreCallingIdentity(ident);
10726 public List<RunningTaskInfo> getTasks(int maxNum) {
10727 return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10731 public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10732 @WindowingMode int ignoreWindowingMode) {
10733 final int callingUid = Binder.getCallingUid();
10734 ArrayList<RunningTaskInfo> list = new ArrayList<>();
10736 synchronized(this) {
10737 if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10739 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10741 mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10742 ignoreWindowingMode, callingUid, allowed);
10748 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10749 if (mRecentTasks.isCallerRecents(callingUid)) {
10750 // Always allow the recents component to get tasks
10754 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10755 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10757 if (checkPermission(android.Manifest.permission.GET_TASKS,
10758 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10759 // Temporary compatibility: some existing apps on the system image may
10760 // still be requesting the old permission and not switched to the new
10761 // one; if so, we'll still allow them full access. This means we need
10762 // to see if they are holding the old permission and are a system app.
10764 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10766 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10767 + " is using old GET_TASKS but privileged; allowing");
10769 } catch (RemoteException e) {
10774 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10775 + " does not hold REAL_GET_TASKS; limiting output");
10781 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10783 final int callingUid = Binder.getCallingUid();
10784 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10785 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10786 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10788 final boolean detailed = checkCallingPermission(
10789 android.Manifest.permission.GET_DETAILED_TASKS)
10790 == PackageManager.PERMISSION_GRANTED;
10792 synchronized (this) {
10793 return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10799 public ActivityManager.TaskDescription getTaskDescription(int id) {
10800 synchronized (this) {
10801 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10802 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10803 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10805 return tr.lastTaskDescription;
10812 public int addAppTask(IBinder activityToken, Intent intent,
10813 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10814 final int callingUid = Binder.getCallingUid();
10815 final long callingIdent = Binder.clearCallingIdentity();
10818 synchronized (this) {
10819 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10821 throw new IllegalArgumentException("Activity does not exist; token="
10824 ComponentName comp = intent.getComponent();
10825 if (comp == null) {
10826 throw new IllegalArgumentException("Intent " + intent
10827 + " must specify explicit component");
10829 if (thumbnail.getWidth() != mThumbnailWidth
10830 || thumbnail.getHeight() != mThumbnailHeight) {
10831 throw new IllegalArgumentException("Bad thumbnail size: got "
10832 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10833 + mThumbnailWidth + "x" + mThumbnailHeight);
10835 if (intent.getSelector() != null) {
10836 intent.setSelector(null);
10838 if (intent.getSourceBounds() != null) {
10839 intent.setSourceBounds(null);
10841 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10842 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10843 // The caller has added this as an auto-remove task... that makes no
10844 // sense, so turn off auto-remove.
10845 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10848 final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
10849 STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
10850 if (ainfo.applicationInfo.uid != callingUid) {
10851 throw new SecurityException(
10852 "Can't add task for another application: target uid="
10853 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10856 final ActivityStack stack = r.getStack();
10857 final TaskRecord task = stack.createTaskRecord(
10858 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
10859 null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
10860 if (!mRecentTasks.addToBottom(task)) {
10861 // The app has too many tasks already and we can't add any more
10862 stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
10863 return INVALID_TASK_ID;
10865 task.lastTaskDescription.copyFrom(description);
10867 // TODO: Send the thumbnail to WM to store it.
10869 return task.taskId;
10872 Binder.restoreCallingIdentity(callingIdent);
10877 public Point getAppTaskThumbnailSize() {
10878 synchronized (this) {
10879 return new Point(mThumbnailWidth, mThumbnailHeight);
10884 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10885 synchronized (this) {
10886 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10888 r.setTaskDescription(td);
10889 final TaskRecord task = r.getTask();
10890 task.updateTaskDescription();
10891 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10897 public void setTaskResizeable(int taskId, int resizeableMode) {
10898 synchronized (this) {
10899 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10900 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10901 if (task == null) {
10902 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10905 task.setResizeMode(resizeableMode);
10910 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10911 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10912 long ident = Binder.clearCallingIdentity();
10914 synchronized (this) {
10915 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10916 if (task == null) {
10917 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10920 // Place the task in the right stack if it isn't there already based on
10921 // the requested bounds.
10922 // The stack transition logic is:
10923 // - a null bounds on a freeform task moves that task to fullscreen
10924 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10925 // that task to freeform
10926 // - otherwise the task is not moved
10927 ActivityStack stack = task.getStack();
10928 if (!task.getWindowConfiguration().canResizeTask()) {
10929 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10931 if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10932 stack = stack.getDisplay().getOrCreateStack(
10933 WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10934 } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10935 stack = stack.getDisplay().getOrCreateStack(
10936 WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10939 // Reparent the task to the right stack if necessary
10940 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10941 if (stack != task.getStack()) {
10942 // Defer resume until the task is resized below
10943 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10944 DEFER_RESUME, "resizeTask");
10945 preserveWindow = false;
10948 // After reparenting (which only resizes the task to the stack bounds), resize the
10949 // task to the actual bounds provided
10950 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10953 Binder.restoreCallingIdentity(ident);
10958 public Rect getTaskBounds(int taskId) {
10959 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10960 long ident = Binder.clearCallingIdentity();
10961 Rect rect = new Rect();
10963 synchronized (this) {
10964 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10965 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10966 if (task == null) {
10967 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10970 if (task.getStack() != null) {
10971 // Return the bounds from window manager since it will be adjusted for various
10972 // things like the presense of a docked stack for tasks that aren't resizeable.
10973 task.getWindowContainerBounds(rect);
10975 // Task isn't in window manager yet since it isn't associated with a stack.
10976 // Return the persist value from activity manager
10977 if (!task.matchParentBounds()) {
10978 rect.set(task.getBounds());
10979 } else if (task.mLastNonFullscreenBounds != null) {
10980 rect.set(task.mLastNonFullscreenBounds);
10985 Binder.restoreCallingIdentity(ident);
10991 public void cancelTaskWindowTransition(int taskId) {
10992 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10993 "cancelTaskWindowTransition()");
10994 final long ident = Binder.clearCallingIdentity();
10996 synchronized (this) {
10997 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10998 MATCH_TASK_IN_STACKS_ONLY);
10999 if (task == null) {
11000 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
11003 task.cancelWindowTransition();
11006 Binder.restoreCallingIdentity(ident);
11011 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
11012 enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
11013 final long ident = Binder.clearCallingIdentity();
11015 final TaskRecord task;
11016 synchronized (this) {
11017 task = mStackSupervisor.anyTaskForIdLocked(taskId,
11018 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
11019 if (task == null) {
11020 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
11024 // Don't call this while holding the lock as this operation might hit the disk.
11025 return task.getSnapshot(reducedResolution);
11027 Binder.restoreCallingIdentity(ident);
11032 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
11033 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11034 userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
11036 final File passedIconFile = new File(filePath);
11037 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
11038 passedIconFile.getName());
11039 if (!legitIconFile.getPath().equals(filePath)
11040 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
11041 throw new IllegalArgumentException("Bad file path: " + filePath
11042 + " passed for userId " + userId);
11044 return mRecentTasks.getTaskDescriptionIcon(filePath);
11048 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
11049 throws RemoteException {
11050 final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
11051 final ActivityOptions activityOptions = safeOptions != null
11052 ? safeOptions.getOptions(mStackSupervisor)
11054 if (activityOptions == null
11055 || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
11056 || activityOptions.getCustomInPlaceResId() == 0) {
11057 throw new IllegalArgumentException("Expected in-place ActivityOption " +
11058 "with valid animation");
11060 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
11061 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
11062 activityOptions.getCustomInPlaceResId());
11063 mWindowManager.executeAppTransition();
11067 public void removeStack(int stackId) {
11068 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
11069 synchronized (this) {
11070 final long ident = Binder.clearCallingIdentity();
11072 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11073 if (stack == null) {
11074 Slog.w(TAG, "removeStack: No stack with id=" + stackId);
11077 if (!stack.isActivityTypeStandardOrUndefined()) {
11078 throw new IllegalArgumentException(
11079 "Removing non-standard stack is not allowed.");
11081 mStackSupervisor.removeStack(stack);
11083 Binder.restoreCallingIdentity(ident);
11089 * Removes stacks in the input windowing modes from the system if they are of activity type
11090 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
11093 public void removeStacksInWindowingModes(int[] windowingModes) {
11094 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11095 "removeStacksInWindowingModes()");
11096 synchronized (this) {
11097 final long ident = Binder.clearCallingIdentity();
11099 mStackSupervisor.removeStacksInWindowingModes(windowingModes);
11101 Binder.restoreCallingIdentity(ident);
11107 public void removeStacksWithActivityTypes(int[] activityTypes) {
11108 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11109 "removeStacksWithActivityTypes()");
11110 synchronized (this) {
11111 final long ident = Binder.clearCallingIdentity();
11113 mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
11115 Binder.restoreCallingIdentity(ident);
11121 * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
11124 String getPendingTempWhitelistTagForUidLocked(int uid) {
11125 final PendingTempWhitelist ptw = mPendingTempWhitelist.get(uid);
11126 return ptw != null ? ptw.tag : null;
11130 boolean isActivityStartsLoggingEnabled() {
11131 return mConstants.mFlagActivityStartsLoggingEnabled;
11135 public void moveStackToDisplay(int stackId, int displayId) {
11136 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
11138 synchronized (this) {
11139 final long ident = Binder.clearCallingIdentity();
11141 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
11142 + " to displayId=" + displayId);
11143 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
11145 Binder.restoreCallingIdentity(ident);
11151 public boolean removeTask(int taskId) {
11152 enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
11153 synchronized (this) {
11154 final long ident = Binder.clearCallingIdentity();
11156 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
11159 Binder.restoreCallingIdentity(ident);
11165 * TODO: Add mController hook
11168 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
11169 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
11171 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
11172 synchronized(this) {
11173 moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
11174 false /* fromRecents */);
11178 void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
11179 boolean fromRecents) {
11181 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11182 Binder.getCallingUid(), -1, -1, "Task to front")) {
11183 SafeActivityOptions.abort(options);
11186 final long origId = Binder.clearCallingIdentity();
11188 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11189 if (task == null) {
11190 Slog.d(TAG, "Could not find task for id: "+ taskId);
11193 if (mLockTaskController.isLockTaskModeViolation(task)) {
11194 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
11197 ActivityOptions realOptions = options != null
11198 ? options.getOptions(mStackSupervisor)
11200 mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
11201 false /* forceNonResizable */);
11203 final ActivityRecord topActivity = task.getTopActivity();
11204 if (topActivity != null) {
11206 // We are reshowing a task, use a starting window to hide the initial draw delay
11207 // so the transition can start earlier.
11208 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
11209 true /* taskSwitch */, fromRecents);
11212 Binder.restoreCallingIdentity(origId);
11214 SafeActivityOptions.abort(options);
11218 * Attempts to move a task backwards in z-order (the order of activities within the task is
11221 * There are several possible results of this call:
11222 * - if the task is locked, then we will show the lock toast
11223 * - if there is a task behind the provided task, then that task is made visible and resumed as
11224 * this task is moved to the back
11225 * - otherwise, if there are no other tasks in the stack:
11226 * - if this task is in the pinned stack, then we remove the stack completely, which will
11227 * have the effect of moving the task to the top or bottom of the fullscreen stack
11228 * (depending on whether it is visible)
11229 * - otherwise, we simply return home and hide this task
11231 * @param token A reference to the activity we wish to move
11232 * @param nonRoot If false then this only works if the activity is the root
11233 * of a task; if true it will work for any activity in a task.
11234 * @return Returns true if the move completed, false if not.
11237 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
11238 enforceNotIsolatedCaller("moveActivityTaskToBack");
11239 synchronized(this) {
11240 final long origId = Binder.clearCallingIdentity();
11242 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
11243 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11244 if (task != null) {
11245 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
11248 Binder.restoreCallingIdentity(origId);
11255 public void moveTaskBackwards(int task) {
11256 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
11257 "moveTaskBackwards()");
11259 synchronized(this) {
11260 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11261 Binder.getCallingUid(), -1, -1, "Task backwards")) {
11264 final long origId = Binder.clearCallingIdentity();
11265 moveTaskBackwardsLocked(task);
11266 Binder.restoreCallingIdentity(origId);
11270 private final void moveTaskBackwardsLocked(int task) {
11271 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
11275 public int createStackOnDisplay(int displayId) throws RemoteException {
11276 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
11277 synchronized (this) {
11278 final ActivityDisplay display =
11279 mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
11280 if (display == null) {
11281 return INVALID_STACK_ID;
11283 // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
11284 final ActivityStack stack = display.createStack(
11285 WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
11287 return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
11292 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
11293 synchronized (this) {
11294 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
11295 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
11296 return stack.mDisplayId;
11298 return DEFAULT_DISPLAY;
11303 public void exitFreeformMode(IBinder token) throws RemoteException {
11304 synchronized (this) {
11305 long ident = Binder.clearCallingIdentity();
11307 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11309 throw new IllegalArgumentException(
11310 "exitFreeformMode: No activity record matching token=" + token);
11313 final ActivityStack stack = r.getStack();
11314 if (stack == null || !stack.inFreeformWindowingMode()) {
11315 throw new IllegalStateException(
11316 "exitFreeformMode: You can only go fullscreen from freeform.");
11319 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11321 Binder.restoreCallingIdentity(ident);
11327 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
11328 if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
11329 setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
11330 toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
11333 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
11334 synchronized (this) {
11335 final long ident = Binder.clearCallingIdentity();
11337 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11338 if (task == null) {
11339 Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
11343 if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
11344 + " to windowingMode=" + windowingMode + " toTop=" + toTop);
11346 if (!task.isActivityTypeStandardOrUndefined()) {
11347 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11348 + " non-standard task " + taskId + " to windowing mode="
11352 final ActivityStack stack = task.getStack();
11354 stack.moveToFront("setTaskWindowingMode", task);
11356 stack.setWindowingMode(windowingMode);
11358 Binder.restoreCallingIdentity(ident);
11364 * Moves the specified task to the primary-split-screen stack.
11366 * @param taskId Id of task to move.
11367 * @param createMode The mode the primary split screen stack should be created in if it doesn't
11368 * exist already. See
11369 * {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
11371 * {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
11372 * @param toTop If the task and stack should be moved to the top.
11373 * @param animate Whether we should play an animation for the moving the task.
11374 * @param initialBounds If the primary stack gets created, it will use these bounds for the
11375 * stack. Pass {@code null} to use default bounds.
11376 * @param showRecents If the recents activity should be shown on the other side of the task
11377 * going into split-screen mode.
11380 public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
11381 boolean animate, Rect initialBounds, boolean showRecents) {
11382 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11383 "setTaskWindowingModeSplitScreenPrimary()");
11384 synchronized (this) {
11385 long ident = Binder.clearCallingIdentity();
11387 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11388 if (task == null) {
11389 Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
11392 if (DEBUG_STACK) Slog.d(TAG_STACK,
11393 "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
11394 + " to createMode=" + createMode + " toTop=" + toTop);
11395 if (!task.isActivityTypeStandardOrUndefined()) {
11396 throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11397 + " non-standard task " + taskId + " to split-screen windowing mode");
11400 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
11401 final int windowingMode = task.getWindowingMode();
11402 final ActivityStack stack = task.getStack();
11404 stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
11406 stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
11407 false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
11408 return windowingMode != task.getWindowingMode();
11410 Binder.restoreCallingIdentity(ident);
11416 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
11417 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
11418 synchronized (this) {
11419 long ident = Binder.clearCallingIdentity();
11421 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11422 if (task == null) {
11423 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
11427 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
11428 + " to stackId=" + stackId + " toTop=" + toTop);
11430 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11431 if (stack == null) {
11432 throw new IllegalStateException(
11433 "moveTaskToStack: No stack for stackId=" + stackId);
11435 if (!stack.isActivityTypeStandardOrUndefined()) {
11436 throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
11437 + taskId + " to stack " + stackId);
11439 if (stack.inSplitScreenPrimaryWindowingMode()) {
11440 mWindowManager.setDockedStackCreateState(
11441 SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
11443 task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
11444 "moveTaskToStack");
11446 Binder.restoreCallingIdentity(ident);
11452 * Dismisses split-screen multi-window mode.
11453 * @param toTop If true the current primary split-screen stack will be placed or left on top.
11456 public void dismissSplitScreenMode(boolean toTop) {
11457 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
11458 final long ident = Binder.clearCallingIdentity();
11460 synchronized (this) {
11461 final ActivityStack stack =
11462 mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
11463 if (stack == null) {
11464 Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
11469 // Caller wants the current split-screen primary stack to be the top stack after
11470 // it goes fullscreen, so move it to the front.
11471 stack.moveToFront("dismissSplitScreenMode");
11472 } else if (mStackSupervisor.isFocusedStack(stack)) {
11473 // In this case the current split-screen primary stack shouldn't be the top
11474 // stack after it goes fullscreen, but it current has focus, so we move the
11475 // focus to the top-most split-screen secondary stack next to it.
11476 final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
11477 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
11478 if (otherStack != null) {
11479 otherStack.moveToFront("dismissSplitScreenMode_other");
11483 stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11486 Binder.restoreCallingIdentity(ident);
11492 * @param animate True if the dismissal should be animated.
11493 * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
11494 * default animation duration should be used.
11497 public void dismissPip(boolean animate, int animationDuration) {
11498 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
11499 final long ident = Binder.clearCallingIdentity();
11501 synchronized (this) {
11502 final PinnedActivityStack stack =
11503 mStackSupervisor.getDefaultDisplay().getPinnedStack();
11504 if (stack == null) {
11505 Slog.w(TAG, "dismissPip: pinned stack not found.");
11508 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11509 throw new IllegalArgumentException("Stack: " + stack
11510 + " doesn't support animated resize.");
11513 stack.animateResizePinnedStack(null /* sourceHintBounds */,
11514 null /* destBounds */, animationDuration, false /* fromFullscreen */);
11516 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
11520 Binder.restoreCallingIdentity(ident);
11525 * Moves the top activity in the input stackId to the pinned stack.
11527 * @param stackId Id of stack to move the top activity to pinned stack.
11528 * @param bounds Bounds to use for pinned stack.
11530 * @return True if the top activity of the input stack was successfully moved to the pinned
11534 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
11535 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11536 "moveTopActivityToPinnedStack()");
11537 synchronized (this) {
11538 if (!mSupportsPictureInPicture) {
11539 throw new IllegalStateException("moveTopActivityToPinnedStack:"
11540 + "Device doesn't support picture-in-picture mode");
11543 long ident = Binder.clearCallingIdentity();
11545 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
11547 Binder.restoreCallingIdentity(ident);
11553 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
11554 boolean preserveWindows, boolean animate, int animationDuration) {
11555 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
11556 long ident = Binder.clearCallingIdentity();
11558 synchronized (this) {
11560 final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
11561 if (stack == null) {
11562 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11565 if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11566 throw new IllegalArgumentException("Stack: " + stackId
11567 + " doesn't support animated resize.");
11569 stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11570 animationDuration, false /* fromFullscreen */);
11572 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11573 if (stack == null) {
11574 Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11577 mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11578 null /* tempTaskInsetBounds */, preserveWindows,
11579 allowResizeInDockedMode, !DEFER_RESUME);
11583 Binder.restoreCallingIdentity(ident);
11588 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
11589 Rect tempDockedTaskInsetBounds,
11590 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
11591 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
11592 long ident = Binder.clearCallingIdentity();
11594 synchronized (this) {
11595 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11596 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11600 Binder.restoreCallingIdentity(ident);
11605 public void setSplitScreenResizing(boolean resizing) {
11606 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
11607 final long ident = Binder.clearCallingIdentity();
11609 synchronized (this) {
11610 mStackSupervisor.setSplitScreenResizing(resizing);
11613 Binder.restoreCallingIdentity(ident);
11618 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11619 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11620 final long ident = Binder.clearCallingIdentity();
11622 synchronized (this) {
11623 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11626 Binder.restoreCallingIdentity(ident);
11631 * Try to place task to provided position. The final position might be different depending on
11632 * current user and stacks state. The task will be moved to target stack if it's currently in
11636 public void positionTaskInStack(int taskId, int stackId, int position) {
11637 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11638 synchronized (this) {
11639 long ident = Binder.clearCallingIdentity();
11641 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
11642 + taskId + " in stackId=" + stackId + " at position=" + position);
11643 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11644 if (task == null) {
11645 throw new IllegalArgumentException("positionTaskInStack: no task for id="
11649 final ActivityStack stack = mStackSupervisor.getStack(stackId);
11651 if (stack == null) {
11652 throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11655 if (!stack.isActivityTypeStandardOrUndefined()) {
11656 throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11657 + " the position of task " + taskId + " in/to non-standard stack");
11660 // TODO: Have the callers of this API call a separate reparent method if that is
11661 // what they intended to do vs. having this method also do reparenting.
11662 if (task.getStack() == stack) {
11663 // Change position in current stack.
11664 stack.positionChildAt(task, position);
11666 // Reparent to new stack.
11667 task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11668 !DEFER_RESUME, "positionTaskInStack");
11671 Binder.restoreCallingIdentity(ident);
11677 public List<StackInfo> getAllStackInfos() {
11678 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11679 long ident = Binder.clearCallingIdentity();
11681 synchronized (this) {
11682 return mStackSupervisor.getAllStackInfosLocked();
11685 Binder.restoreCallingIdentity(ident);
11690 public StackInfo getStackInfo(int windowingMode, int activityType) {
11691 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11692 long ident = Binder.clearCallingIdentity();
11694 synchronized (this) {
11695 return mStackSupervisor.getStackInfo(windowingMode, activityType);
11698 Binder.restoreCallingIdentity(ident);
11703 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11704 synchronized(this) {
11705 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11710 public void updateDeviceOwner(String packageName) {
11711 final int callingUid = Binder.getCallingUid();
11712 if (callingUid != 0 && callingUid != SYSTEM_UID) {
11713 throw new SecurityException("updateDeviceOwner called from non-system process");
11715 synchronized (this) {
11716 mDeviceOwnerName = packageName;
11721 public void updateLockTaskPackages(int userId, String[] packages) {
11722 final int callingUid = Binder.getCallingUid();
11723 if (callingUid != 0 && callingUid != SYSTEM_UID) {
11724 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11725 "updateLockTaskPackages()");
11727 synchronized (this) {
11728 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11729 Arrays.toString(packages));
11730 mLockTaskController.updateLockTaskPackages(userId, packages);
11735 public void updateLockTaskFeatures(int userId, int flags) {
11736 final int callingUid = Binder.getCallingUid();
11737 if (callingUid != 0 && callingUid != SYSTEM_UID) {
11738 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11739 "updateLockTaskFeatures()");
11741 synchronized (this) {
11742 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11743 Integer.toHexString(flags));
11744 mLockTaskController.updateLockTaskFeatures(userId, flags);
11748 private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11749 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11750 if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11754 final ActivityStack stack = mStackSupervisor.getFocusedStack();
11755 if (stack == null || task != stack.topTask()) {
11756 throw new IllegalArgumentException("Invalid task, not in foreground");
11759 // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11760 // system or a specific app.
11761 // * System-initiated requests will only start the pinned mode (screen pinning)
11762 // * App-initiated requests
11763 // - will put the device in fully locked mode (LockTask), if the app is whitelisted
11764 // - will start the pinned mode, otherwise
11765 final int callingUid = Binder.getCallingUid();
11766 long ident = Binder.clearCallingIdentity();
11768 // When a task is locked, dismiss the pinned stack if it exists
11769 mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11771 mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11773 Binder.restoreCallingIdentity(ident);
11778 public void startLockTaskModeByToken(IBinder token) {
11779 synchronized (this) {
11780 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11784 startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11789 public void startSystemLockTaskMode(int taskId) throws RemoteException {
11790 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11791 // This makes inner call to look as if it was initiated by system.
11792 long ident = Binder.clearCallingIdentity();
11794 synchronized (this) {
11795 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11797 // When starting lock task mode the stack must be in front and focused
11798 task.getStack().moveToFront("startSystemLockTaskMode");
11799 startLockTaskModeLocked(task, true /* isSystemCaller */);
11802 Binder.restoreCallingIdentity(ident);
11807 public void stopLockTaskModeByToken(IBinder token) {
11808 synchronized (this) {
11809 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11813 stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11818 * This API should be called by SystemUI only when user perform certain action to dismiss
11819 * lock task mode. We should only dismiss pinned lock task mode in this case.
11822 public void stopSystemLockTaskMode() throws RemoteException {
11823 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11824 stopLockTaskModeInternal(null, true /* isSystemCaller */);
11827 private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11828 final int callingUid = Binder.getCallingUid();
11829 long ident = Binder.clearCallingIdentity();
11831 synchronized (this) {
11832 mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11834 // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11835 // task and jumping straight into a call in the case of emergency call back.
11836 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11838 tm.showInCallScreen(false);
11841 Binder.restoreCallingIdentity(ident);
11846 public boolean isInLockTaskMode() {
11847 return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11851 public int getLockTaskModeState() {
11852 synchronized (this) {
11853 return mLockTaskController.getLockTaskModeState();
11858 public void showLockTaskEscapeMessage(IBinder token) {
11859 synchronized (this) {
11860 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11864 mLockTaskController.showLockTaskToast();
11869 public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11870 throws RemoteException {
11871 synchronized (this) {
11872 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11874 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11878 final long origId = Binder.clearCallingIdentity();
11880 r.setDisablePreviewScreenshots(disable);
11882 Binder.restoreCallingIdentity(origId);
11887 // =========================================================
11888 // CONTENT PROVIDERS
11889 // =========================================================
11891 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11892 List<ProviderInfo> providers = null;
11894 providers = AppGlobals.getPackageManager()
11895 .queryContentProviders(app.processName, app.uid,
11896 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11897 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11899 } catch (RemoteException ex) {
11901 if (DEBUG_MU) Slog.v(TAG_MU,
11902 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11903 int userId = app.userId;
11904 if (providers != null) {
11905 int N = providers.size();
11906 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11907 for (int i=0; i<N; i++) {
11908 // TODO: keep logic in sync with installEncryptionUnawareProviders
11910 (ProviderInfo)providers.get(i);
11911 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11912 cpi.name, cpi.flags);
11913 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11914 // This is a singleton provider, but a user besides the
11915 // default user is asking to initialize a process it runs
11916 // in... well, no, it doesn't actually run in this process,
11917 // it runs in the process of the default user. Get rid of it.
11918 providers.remove(i);
11924 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11925 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11927 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11928 mProviderMap.putProviderByClass(comp, cpr);
11930 if (DEBUG_MU) Slog.v(TAG_MU,
11931 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11932 app.pubProviders.put(cpi.name, cpr);
11933 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11934 // Don't add this if it is a platform component that is marked
11935 // to run in multiple processes, because this is actually
11936 // part of the framework so doesn't make sense to track as a
11937 // separate apk in the process.
11938 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11941 notifyPackageUse(cpi.applicationInfo.packageName,
11942 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11949 * Check if the calling UID has a possible chance at accessing the provider
11950 * at the given authority and user.
11952 public String checkContentProviderAccess(String authority, int userId) {
11953 if (userId == UserHandle.USER_ALL) {
11954 mContext.enforceCallingOrSelfPermission(
11955 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11956 userId = UserHandle.getCallingUserId();
11959 ProviderInfo cpi = null;
11961 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11962 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11963 | PackageManager.MATCH_DISABLED_COMPONENTS
11964 | PackageManager.MATCH_DIRECT_BOOT_AWARE
11965 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11967 } catch (RemoteException ignored) {
11970 return "Failed to find provider " + authority + " for user " + userId
11971 + "; expected to find a valid ContentProvider for this authority";
11974 ProcessRecord r = null;
11975 synchronized (mPidsSelfLocked) {
11976 r = mPidsSelfLocked.get(Binder.getCallingPid());
11979 return "Failed to find PID " + Binder.getCallingPid();
11982 synchronized (this) {
11983 return checkContentProviderPermissionLocked(cpi, r, userId, true);
11988 * Check if {@link ProcessRecord} has a possible chance at accessing the
11989 * given {@link ProviderInfo}. Final permission checking is always done
11990 * in {@link ContentProvider}.
11992 private final String checkContentProviderPermissionLocked(
11993 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11994 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11995 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11996 boolean checkedGrants = false;
11998 // Looking for cross-user grants before enforcing the typical cross-users permissions
11999 int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
12000 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
12001 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
12004 checkedGrants = true;
12006 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
12007 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
12008 if (userId != tmpTargetUserId) {
12009 // When we actually went to determine the final targer user ID, this ended
12010 // up different than our initial check for the authority. This is because
12011 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
12012 // SELF. So we need to re-check the grants again.
12013 checkedGrants = false;
12016 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
12017 cpi.applicationInfo.uid, cpi.exported)
12018 == PackageManager.PERMISSION_GRANTED) {
12021 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
12022 cpi.applicationInfo.uid, cpi.exported)
12023 == PackageManager.PERMISSION_GRANTED) {
12027 PathPermission[] pps = cpi.pathPermissions;
12029 int i = pps.length;
12032 PathPermission pp = pps[i];
12033 String pprperm = pp.getReadPermission();
12034 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
12035 cpi.applicationInfo.uid, cpi.exported)
12036 == PackageManager.PERMISSION_GRANTED) {
12039 String ppwperm = pp.getWritePermission();
12040 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
12041 cpi.applicationInfo.uid, cpi.exported)
12042 == PackageManager.PERMISSION_GRANTED) {
12047 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
12051 final String suffix;
12052 if (!cpi.exported) {
12053 suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
12054 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
12055 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
12057 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
12059 final String msg = "Permission Denial: opening provider " + cpi.name
12060 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
12061 + ", uid=" + callingUid + ")" + suffix;
12067 * Returns if the ContentProvider has granted a uri to callingUid
12069 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
12070 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
12071 if (perms != null) {
12072 for (int i=perms.size()-1; i>=0; i--) {
12073 GrantUri grantUri = perms.keyAt(i);
12074 if (grantUri.sourceUserId == userId || !checkUser) {
12075 if (matchesProvider(grantUri.uri, cpi)) {
12085 * Returns true if the uri authority is one of the authorities specified in the provider.
12087 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
12088 String uriAuth = uri.getAuthority();
12089 String cpiAuth = cpi.authority;
12090 if (cpiAuth.indexOf(';') == -1) {
12091 return cpiAuth.equals(uriAuth);
12093 String[] cpiAuths = cpiAuth.split(";");
12094 int length = cpiAuths.length;
12095 for (int i = 0; i < length; i++) {
12096 if (cpiAuths[i].equals(uriAuth)) return true;
12101 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
12102 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
12104 for (int i=0; i<r.conProviders.size(); i++) {
12105 ContentProviderConnection conn = r.conProviders.get(i);
12106 if (conn.provider == cpr) {
12107 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
12108 "Adding provider requested by "
12109 + r.processName + " from process "
12110 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
12111 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
12113 conn.stableCount++;
12114 conn.numStableIncs++;
12116 conn.unstableCount++;
12117 conn.numUnstableIncs++;
12122 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
12124 conn.stableCount = 1;
12125 conn.numStableIncs = 1;
12127 conn.unstableCount = 1;
12128 conn.numUnstableIncs = 1;
12130 cpr.connections.add(conn);
12131 r.conProviders.add(conn);
12132 startAssociationLocked(r.uid, r.processName, r.curProcState,
12133 cpr.uid, cpr.name, cpr.info.processName);
12136 cpr.addExternalProcessHandleLocked(externalProcessToken);
12140 boolean decProviderCountLocked(ContentProviderConnection conn,
12141 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
12142 if (conn != null) {
12143 cpr = conn.provider;
12144 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
12145 "Removing provider requested by "
12146 + conn.client.processName + " from process "
12147 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
12148 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
12150 conn.stableCount--;
12152 conn.unstableCount--;
12154 if (conn.stableCount == 0 && conn.unstableCount == 0) {
12155 cpr.connections.remove(conn);
12156 conn.client.conProviders.remove(conn);
12157 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
12158 // The client is more important than last activity -- note the time this
12159 // is happening, so we keep the old provider process around a bit as last
12160 // activity to avoid thrashing it.
12161 if (cpr.proc != null) {
12162 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
12165 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
12170 cpr.removeExternalProcessHandleLocked(externalProcessToken);
12174 private void checkTime(long startTime, String where) {
12175 long now = SystemClock.uptimeMillis();
12176 if ((now-startTime) > 50) {
12177 // If we are taking more than 50ms, log about it.
12178 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
12182 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
12184 PROC_SPACE_TERM|PROC_PARENS,
12185 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
12188 private final long[] mProcessStateStatsLongs = new long[1];
12190 private boolean isProcessAliveLocked(ProcessRecord proc) {
12191 if (proc.pid <= 0) {
12192 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
12195 if (proc.procStatFile == null) {
12196 proc.procStatFile = "/proc/" + proc.pid + "/stat";
12198 mProcessStateStatsLongs[0] = 0;
12199 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
12200 mProcessStateStatsLongs, null)) {
12201 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
12204 final long state = mProcessStateStatsLongs[0];
12205 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
12207 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
12210 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
12211 String name, IBinder token, boolean stable, int userId) {
12212 ContentProviderRecord cpr;
12213 ContentProviderConnection conn = null;
12214 ProviderInfo cpi = null;
12215 boolean providerRunning = false;
12217 synchronized(this) {
12218 long startTime = SystemClock.uptimeMillis();
12220 ProcessRecord r = null;
12221 if (caller != null) {
12222 r = getRecordForAppLocked(caller);
12224 throw new SecurityException(
12225 "Unable to find app for caller " + caller
12226 + " (pid=" + Binder.getCallingPid()
12227 + ") when getting content provider " + name);
12231 boolean checkCrossUser = true;
12233 checkTime(startTime, "getContentProviderImpl: getProviderByName");
12235 // First check if this content provider has been published...
12236 cpr = mProviderMap.getProviderByName(name, userId);
12237 // If that didn't work, check if it exists for user 0 and then
12238 // verify that it's a singleton provider before using it.
12239 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
12240 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
12243 if (isSingleton(cpi.processName, cpi.applicationInfo,
12244 cpi.name, cpi.flags)
12245 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
12246 userId = UserHandle.USER_SYSTEM;
12247 checkCrossUser = false;
12255 if (cpr != null && cpr.proc != null) {
12256 providerRunning = !cpr.proc.killed;
12258 // Note if killedByAm is also set, this means the provider process has just been
12259 // killed by AM (in ProcessRecord.kill()), but appDiedLocked() hasn't been called
12260 // yet. So we need to call appDiedLocked() here and let it clean up.
12261 // (See the commit message on I2c4ba1e87c2d47f2013befff10c49b3dc337a9a7 to see
12262 // how to test this case.)
12263 if (cpr.proc.killed && cpr.proc.killedByAm) {
12264 checkTime(startTime, "getContentProviderImpl: before appDied (killedByAm)");
12265 final long iden = Binder.clearCallingIdentity();
12267 appDiedLocked(cpr.proc);
12269 Binder.restoreCallingIdentity(iden);
12271 checkTime(startTime, "getContentProviderImpl: after appDied (killedByAm)");
12275 if (providerRunning) {
12278 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12279 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
12281 throw new SecurityException(msg);
12283 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12285 if (r != null && cpr.canRunHere(r)) {
12286 // This provider has been published or is in the process
12287 // of being published... but it is also allowed to run
12288 // in the caller's process, so don't make a connection
12289 // and just let the caller instantiate its own instance.
12290 ContentProviderHolder holder = cpr.newHolder(null);
12291 // don't give caller the provider object, it needs
12292 // to make its own.
12293 holder.provider = null;
12296 // Don't expose providers between normal apps and instant apps
12298 if (AppGlobals.getPackageManager()
12299 .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
12302 } catch (RemoteException e) {
12305 final long origId = Binder.clearCallingIdentity();
12307 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
12309 // In this case the provider instance already exists, so we can
12310 // return it right away.
12311 conn = incProviderCountLocked(r, cpr, token, stable);
12312 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
12313 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12314 // If this is a perceptible app accessing the provider,
12315 // make sure to count it as being accessed and thus
12316 // back up on the LRU list. This is good because
12317 // content providers are often expensive to start.
12318 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
12319 updateLruProcessLocked(cpr.proc, false, null);
12320 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
12324 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
12325 final int verifiedAdj = cpr.proc.verifiedAdj;
12326 boolean success = updateOomAdjLocked(cpr.proc, true);
12327 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
12328 // if the process has been successfully adjusted. So to reduce races with
12329 // it, we will check whether the process still exists. Note that this doesn't
12330 // completely get rid of races with LMK killing the process, but should make
12331 // them much smaller.
12332 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
12335 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
12336 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
12337 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
12338 // NOTE: there is still a race here where a signal could be
12339 // pending on the process even though we managed to update its
12340 // adj level. Not sure what to do about this, but at least
12341 // the race is now smaller.
12343 // Uh oh... it looks like the provider's process
12344 // has been killed on us. We need to wait for a new
12345 // process to be started, and make sure its death
12346 // doesn't kill our process.
12347 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
12348 + " is crashing; detaching " + r);
12349 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
12350 checkTime(startTime, "getContentProviderImpl: before appDied");
12351 appDiedLocked(cpr.proc);
12352 checkTime(startTime, "getContentProviderImpl: after appDied");
12354 // This wasn't the last ref our process had on
12355 // the provider... we have now been killed, bail.
12358 providerRunning = false;
12361 cpr.proc.verifiedAdj = cpr.proc.setAdj;
12364 Binder.restoreCallingIdentity(origId);
12367 if (!providerRunning) {
12369 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
12370 cpi = AppGlobals.getPackageManager().
12371 resolveContentProvider(name,
12372 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
12373 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
12374 } catch (RemoteException ex) {
12379 // If the provider is a singleton AND
12380 // (it's a call within the same user || the provider is a
12382 // Then allow connecting to the singleton provider
12383 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
12384 cpi.name, cpi.flags)
12385 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
12387 userId = UserHandle.USER_SYSTEM;
12389 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
12390 checkTime(startTime, "getContentProviderImpl: got app info for user");
12393 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12394 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
12396 throw new SecurityException(msg);
12398 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12400 if (!mProcessesReady
12401 && !cpi.processName.equals("system")) {
12402 // If this content provider does not run in the system
12403 // process, and the system is not yet ready to run other
12404 // processes, then fail fast instead of hanging.
12405 throw new IllegalArgumentException(
12406 "Attempt to launch content provider before system ready");
12409 // If system providers are not installed yet we aggressively crash to avoid
12410 // creating multiple instance of these providers and then bad things happen!
12411 if (!mSystemProvidersInstalled && cpi.applicationInfo.isSystemApp()
12412 && "system".equals(cpi.processName)) {
12413 throw new IllegalStateException("Cannot access system provider: '"
12414 + cpi.authority + "' before system providers are installed!");
12417 // Make sure that the user who owns this provider is running. If not,
12418 // we don't want to allow it to run.
12419 if (!mUserController.isUserRunning(userId, 0)) {
12420 Slog.w(TAG, "Unable to launch app "
12421 + cpi.applicationInfo.packageName + "/"
12422 + cpi.applicationInfo.uid + " for provider "
12423 + name + ": user " + userId + " is stopped");
12427 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
12428 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
12429 cpr = mProviderMap.getProviderByClass(comp, userId);
12430 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
12431 final boolean firstClass = cpr == null;
12433 final long ident = Binder.clearCallingIdentity();
12435 // If permissions need a review before any of the app components can run,
12436 // we return no provider and launch a review activity if the calling app
12437 // is in the foreground.
12438 if (mPermissionReviewRequired) {
12439 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
12445 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
12446 ApplicationInfo ai =
12447 AppGlobals.getPackageManager().
12448 getApplicationInfo(
12449 cpi.applicationInfo.packageName,
12450 STOCK_PM_FLAGS, userId);
12451 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
12453 Slog.w(TAG, "No package info for content provider "
12457 ai = getAppInfoForUser(ai, userId);
12458 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
12459 } catch (RemoteException ex) {
12460 // pm is in same process, this will never happen.
12462 Binder.restoreCallingIdentity(ident);
12466 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
12468 if (r != null && cpr.canRunHere(r)) {
12469 // If this is a multiprocess provider, then just return its
12470 // info and allow the caller to instantiate it. Only do
12471 // this if the provider is the same user as the caller's
12472 // process, or can run as root (so can be in any process).
12473 return cpr.newHolder(null);
12476 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
12477 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
12478 + cpr.info.name + " callers=" + Debug.getCallers(6));
12480 // This is single process, and our app is now connecting to it.
12481 // See if we are already in the process of launching this
12483 final int N = mLaunchingProviders.size();
12485 for (i = 0; i < N; i++) {
12486 if (mLaunchingProviders.get(i) == cpr) {
12491 // If the provider is not already being launched, then get it
12494 final long origId = Binder.clearCallingIdentity();
12497 // Content provider is now in use, its package can't be stopped.
12499 checkTime(startTime, "getContentProviderImpl: before set stopped state");
12500 AppGlobals.getPackageManager().setPackageStoppedState(
12501 cpr.appInfo.packageName, false, userId);
12502 checkTime(startTime, "getContentProviderImpl: after set stopped state");
12503 } catch (RemoteException e) {
12504 } catch (IllegalArgumentException e) {
12505 Slog.w(TAG, "Failed trying to unstop package "
12506 + cpr.appInfo.packageName + ": " + e);
12509 // Use existing process if already started
12510 checkTime(startTime, "getContentProviderImpl: looking for process record");
12511 ProcessRecord proc = getProcessRecordLocked(
12512 cpi.processName, cpr.appInfo.uid, false);
12513 if (proc != null && proc.thread != null && !proc.killed) {
12514 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
12515 "Installing in existing process " + proc);
12516 if (!proc.pubProviders.containsKey(cpi.name)) {
12517 checkTime(startTime, "getContentProviderImpl: scheduling install");
12518 proc.pubProviders.put(cpi.name, cpr);
12520 proc.thread.scheduleInstallProvider(cpi);
12521 } catch (RemoteException e) {
12525 checkTime(startTime, "getContentProviderImpl: before start process");
12526 proc = startProcessLocked(cpi.processName,
12527 cpr.appInfo, false, 0, "content provider",
12528 new ComponentName(cpi.applicationInfo.packageName,
12529 cpi.name), false, false, false);
12530 checkTime(startTime, "getContentProviderImpl: after start process");
12531 if (proc == null) {
12532 Slog.w(TAG, "Unable to launch app "
12533 + cpi.applicationInfo.packageName + "/"
12534 + cpi.applicationInfo.uid + " for provider "
12535 + name + ": process is bad");
12539 cpr.launchingApp = proc;
12540 mLaunchingProviders.add(cpr);
12542 Binder.restoreCallingIdentity(origId);
12546 checkTime(startTime, "getContentProviderImpl: updating data structures");
12548 // Make sure the provider is published (the same provider class
12549 // may be published under multiple names).
12551 mProviderMap.putProviderByClass(comp, cpr);
12554 mProviderMap.putProviderByName(name, cpr);
12555 conn = incProviderCountLocked(r, cpr, token, stable);
12556 if (conn != null) {
12557 conn.waiting = true;
12560 checkTime(startTime, "getContentProviderImpl: done!");
12562 grantEphemeralAccessLocked(userId, null /*intent*/,
12563 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
12566 // Wait for the provider to be published...
12567 final long timeout = SystemClock.uptimeMillis() + CONTENT_PROVIDER_WAIT_TIMEOUT;
12568 synchronized (cpr) {
12569 while (cpr.provider == null) {
12570 if (cpr.launchingApp == null) {
12571 Slog.w(TAG, "Unable to launch app "
12572 + cpi.applicationInfo.packageName + "/"
12573 + cpi.applicationInfo.uid + " for provider "
12574 + name + ": launching app became null");
12575 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
12576 UserHandle.getUserId(cpi.applicationInfo.uid),
12577 cpi.applicationInfo.packageName,
12578 cpi.applicationInfo.uid, name);
12582 final long wait = Math.max(0L, timeout - SystemClock.uptimeMillis());
12583 if (DEBUG_MU) Slog.v(TAG_MU,
12584 "Waiting to start provider " + cpr
12585 + " launchingApp=" + cpr.launchingApp + " for " + wait + " ms");
12586 if (conn != null) {
12587 conn.waiting = true;
12590 if (cpr.provider == null) {
12591 Slog.wtf(TAG, "Timeout waiting for provider "
12592 + cpi.applicationInfo.packageName + "/"
12593 + cpi.applicationInfo.uid + " for provider "
12595 + " providerRunning=" + providerRunning);
12598 } catch (InterruptedException ex) {
12600 if (conn != null) {
12601 conn.waiting = false;
12606 return cpr != null ? cpr.newHolder(conn) : null;
12609 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
12610 ProcessRecord r, final int userId) {
12611 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
12612 cpi.packageName, userId)) {
12614 final boolean callerForeground = r == null || r.setSchedGroup
12615 != ProcessList.SCHED_GROUP_BACKGROUND;
12617 // Show a permission review UI only for starting from a foreground app
12618 if (!callerForeground) {
12619 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
12620 + cpi.packageName + " requires a permissions review");
12624 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
12625 intent.addFlags(FLAG_ACTIVITY_NEW_TASK
12626 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
12627 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
12629 if (DEBUG_PERMISSIONS_REVIEW) {
12630 Slog.i(TAG, "u" + userId + " Launching permission review "
12631 + "for package " + cpi.packageName);
12634 final UserHandle userHandle = new UserHandle(userId);
12635 mHandler.post(new Runnable() {
12637 public void run() {
12638 mContext.startActivityAsUser(intent, userHandle);
12649 * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
12650 * PackageManager could be unavailable at construction time and therefore needs to be accessed
12653 IPackageManager getPackageManager() {
12654 return AppGlobals.getPackageManager();
12657 ActivityStartController getActivityStartController() {
12658 return mActivityStartController;
12661 LockTaskController getLockTaskController() {
12662 return mLockTaskController;
12665 ClientLifecycleManager getLifecycleManager() {
12666 return mLifecycleManager;
12669 PackageManagerInternal getPackageManagerInternalLocked() {
12670 if (mPackageManagerInt == null) {
12671 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12673 return mPackageManagerInt;
12677 public final ContentProviderHolder getContentProvider(
12678 IApplicationThread caller, String name, int userId, boolean stable) {
12679 enforceNotIsolatedCaller("getContentProvider");
12680 if (caller == null) {
12681 String msg = "null IApplicationThread when getting content provider "
12684 throw new SecurityException(msg);
12686 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
12687 // with cross-user grant.
12688 return getContentProviderImpl(caller, name, null, stable, userId);
12691 public ContentProviderHolder getContentProviderExternal(
12692 String name, int userId, IBinder token) {
12693 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12694 "Do not have permission in call getContentProviderExternal()");
12695 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12696 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
12697 return getContentProviderExternalUnchecked(name, token, userId);
12700 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12701 IBinder token, int userId) {
12702 return getContentProviderImpl(null, name, token, true, userId);
12706 * Drop a content provider from a ProcessRecord's bookkeeping
12708 public void removeContentProvider(IBinder connection, boolean stable) {
12709 enforceNotIsolatedCaller("removeContentProvider");
12710 long ident = Binder.clearCallingIdentity();
12712 synchronized (this) {
12713 ContentProviderConnection conn;
12715 conn = (ContentProviderConnection)connection;
12716 } catch (ClassCastException e) {
12717 String msg ="removeContentProvider: " + connection
12718 + " not a ContentProviderConnection";
12720 throw new IllegalArgumentException(msg);
12722 if (conn == null) {
12723 throw new NullPointerException("connection is null");
12725 if (decProviderCountLocked(conn, null, null, stable)) {
12726 updateOomAdjLocked();
12730 Binder.restoreCallingIdentity(ident);
12734 public void removeContentProviderExternal(String name, IBinder token) {
12735 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12736 "Do not have permission in call removeContentProviderExternal()");
12737 int userId = UserHandle.getCallingUserId();
12738 long ident = Binder.clearCallingIdentity();
12740 removeContentProviderExternalUnchecked(name, token, userId);
12742 Binder.restoreCallingIdentity(ident);
12746 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12747 synchronized (this) {
12748 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12750 //remove from mProvidersByClass
12751 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12755 //update content provider record entry info
12756 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12757 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12758 if (localCpr.hasExternalProcessHandles()) {
12759 if (localCpr.removeExternalProcessHandleLocked(token)) {
12760 updateOomAdjLocked();
12762 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12763 + " with no external reference for token: "
12767 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12768 + " with no external references.");
12773 public final void publishContentProviders(IApplicationThread caller,
12774 List<ContentProviderHolder> providers) {
12775 if (providers == null) {
12779 enforceNotIsolatedCaller("publishContentProviders");
12780 synchronized (this) {
12781 final ProcessRecord r = getRecordForAppLocked(caller);
12782 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12784 throw new SecurityException(
12785 "Unable to find app for caller " + caller
12786 + " (pid=" + Binder.getCallingPid()
12787 + ") when publishing content providers");
12790 final long origId = Binder.clearCallingIdentity();
12792 final int N = providers.size();
12793 for (int i = 0; i < N; i++) {
12794 ContentProviderHolder src = providers.get(i);
12795 if (src == null || src.info == null || src.provider == null) {
12798 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12799 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12801 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12802 mProviderMap.putProviderByClass(comp, dst);
12803 String names[] = dst.info.authority.split(";");
12804 for (int j = 0; j < names.length; j++) {
12805 mProviderMap.putProviderByName(names[j], dst);
12808 int launchingCount = mLaunchingProviders.size();
12810 boolean wasInLaunchingProviders = false;
12811 for (j = 0; j < launchingCount; j++) {
12812 if (mLaunchingProviders.get(j) == dst) {
12813 mLaunchingProviders.remove(j);
12814 wasInLaunchingProviders = true;
12819 if (wasInLaunchingProviders) {
12820 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12822 synchronized (dst) {
12823 dst.provider = src.provider;
12827 updateOomAdjLocked(r, true);
12828 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12829 src.info.authority);
12833 Binder.restoreCallingIdentity(origId);
12837 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12838 ContentProviderConnection conn;
12840 conn = (ContentProviderConnection)connection;
12841 } catch (ClassCastException e) {
12842 String msg ="refContentProvider: " + connection
12843 + " not a ContentProviderConnection";
12845 throw new IllegalArgumentException(msg);
12847 if (conn == null) {
12848 throw new NullPointerException("connection is null");
12851 synchronized (this) {
12853 conn.numStableIncs += stable;
12855 stable = conn.stableCount + stable;
12857 throw new IllegalStateException("stableCount < 0: " + stable);
12860 if (unstable > 0) {
12861 conn.numUnstableIncs += unstable;
12863 unstable = conn.unstableCount + unstable;
12864 if (unstable < 0) {
12865 throw new IllegalStateException("unstableCount < 0: " + unstable);
12868 if ((stable+unstable) <= 0) {
12869 throw new IllegalStateException("ref counts can't go to zero here: stable="
12870 + stable + " unstable=" + unstable);
12872 conn.stableCount = stable;
12873 conn.unstableCount = unstable;
12878 public void unstableProviderDied(IBinder connection) {
12879 ContentProviderConnection conn;
12881 conn = (ContentProviderConnection)connection;
12882 } catch (ClassCastException e) {
12883 String msg ="refContentProvider: " + connection
12884 + " not a ContentProviderConnection";
12886 throw new IllegalArgumentException(msg);
12888 if (conn == null) {
12889 throw new NullPointerException("connection is null");
12892 // Safely retrieve the content provider associated with the connection.
12893 IContentProvider provider;
12894 synchronized (this) {
12895 provider = conn.provider.provider;
12898 if (provider == null) {
12899 // Um, yeah, we're way ahead of you.
12903 // Make sure the caller is being honest with us.
12904 if (provider.asBinder().pingBinder()) {
12905 // Er, no, still looks good to us.
12906 synchronized (this) {
12907 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12908 + " says " + conn + " died, but we don't agree");
12913 // Well look at that! It's dead!
12914 synchronized (this) {
12915 if (conn.provider.provider != provider) {
12916 // But something changed... good enough.
12920 ProcessRecord proc = conn.provider.proc;
12921 if (proc == null || proc.thread == null) {
12922 // Seems like the process is already cleaned up.
12926 // As far as we're concerned, this is just like receiving a
12927 // death notification... just a bit prematurely.
12928 reportUidInfoMessageLocked(TAG,
12929 "Process " + proc.processName + " (pid " + proc.pid
12930 + ") early provider death",
12932 final long ident = Binder.clearCallingIdentity();
12934 appDiedLocked(proc);
12936 Binder.restoreCallingIdentity(ident);
12942 public void appNotRespondingViaProvider(IBinder connection) {
12943 enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12945 final ContentProviderConnection conn = (ContentProviderConnection) connection;
12946 if (conn == null) {
12947 Slog.w(TAG, "ContentProviderConnection is null");
12951 final ProcessRecord host = conn.provider.proc;
12952 if (host == null) {
12953 Slog.w(TAG, "Failed to find hosting ProcessRecord");
12957 mHandler.post(new Runnable() {
12959 public void run() {
12960 mAppErrors.appNotResponding(host, null, null, false,
12961 "ContentProvider not responding");
12966 public final void installSystemProviders() {
12967 List<ProviderInfo> providers;
12968 synchronized (this) {
12969 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12970 providers = generateApplicationProvidersLocked(app);
12971 if (providers != null) {
12972 for (int i=providers.size()-1; i>=0; i--) {
12973 ProviderInfo pi = (ProviderInfo)providers.get(i);
12974 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12975 Slog.w(TAG, "Not installing system proc provider " + pi.name
12976 + ": not system .apk");
12977 providers.remove(i);
12982 if (providers != null) {
12983 mSystemThread.installSystemProviders(providers);
12986 synchronized (this) {
12987 mSystemProvidersInstalled = true;
12990 mConstants.start(mContext.getContentResolver());
12991 mCoreSettingsObserver = new CoreSettingsObserver(this);
12992 mFontScaleSettingObserver = new FontScaleSettingObserver();
12993 mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
12994 GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12996 // Now that the settings provider is published we can consider sending
12997 // in a rescue party.
12998 RescueParty.onSettingsProviderPublished(mContext);
13000 //mUsageStatsService.monitorPackages();
13003 void startPersistentApps(int matchFlags) {
13004 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
13006 synchronized (this) {
13008 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
13009 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
13010 for (ApplicationInfo app : apps) {
13011 if (!"android".equals(app.packageName)) {
13012 addAppLocked(app, null, false, null /* ABI override */);
13015 } catch (RemoteException ex) {
13021 * When a user is unlocked, we need to install encryption-unaware providers
13022 * belonging to any running apps.
13024 void installEncryptionUnawareProviders(int userId) {
13025 // We're only interested in providers that are encryption unaware, and
13026 // we don't care about uninstalled apps, since there's no way they're
13027 // running at this point.
13028 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
13030 synchronized (this) {
13031 final int NP = mProcessNames.getMap().size();
13032 for (int ip = 0; ip < NP; ip++) {
13033 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13034 final int NA = apps.size();
13035 for (int ia = 0; ia < NA; ia++) {
13036 final ProcessRecord app = apps.valueAt(ia);
13037 if (app.userId != userId || app.thread == null || app.unlocked) continue;
13039 final int NG = app.pkgList.size();
13040 for (int ig = 0; ig < NG; ig++) {
13042 final String pkgName = app.pkgList.keyAt(ig);
13043 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
13044 .getPackageInfo(pkgName, matchFlags, userId);
13045 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
13046 for (ProviderInfo pi : pkgInfo.providers) {
13047 // TODO: keep in sync with generateApplicationProvidersLocked
13048 final boolean processMatch = Objects.equals(pi.processName,
13049 app.processName) || pi.multiprocess;
13050 final boolean userMatch = isSingleton(pi.processName,
13051 pi.applicationInfo, pi.name, pi.flags)
13052 ? (app.userId == UserHandle.USER_SYSTEM) : true;
13053 if (processMatch && userMatch) {
13054 Log.v(TAG, "Installing " + pi);
13055 app.thread.scheduleInstallProvider(pi);
13057 Log.v(TAG, "Skipping " + pi);
13061 } catch (RemoteException ignored) {
13070 * Allows apps to retrieve the MIME type of a URI.
13071 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
13072 * users, then it does not need permission to access the ContentProvider.
13073 * Either, it needs cross-user uri grants.
13075 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
13077 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
13078 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
13080 public String getProviderMimeType(Uri uri, int userId) {
13081 enforceNotIsolatedCaller("getProviderMimeType");
13082 final String name = uri.getAuthority();
13083 int callingUid = Binder.getCallingUid();
13084 int callingPid = Binder.getCallingPid();
13086 boolean clearedIdentity = false;
13087 userId = mUserController.unsafeConvertIncomingUser(userId);
13088 if (canClearIdentity(callingPid, callingUid, userId)) {
13089 clearedIdentity = true;
13090 ident = Binder.clearCallingIdentity();
13092 ContentProviderHolder holder = null;
13094 holder = getContentProviderExternalUnchecked(name, null, userId);
13095 if (holder != null) {
13096 return holder.provider.getType(uri);
13098 } catch (RemoteException e) {
13099 Log.w(TAG, "Content provider dead retrieving " + uri, e);
13101 } catch (Exception e) {
13102 Log.w(TAG, "Exception while determining type of " + uri, e);
13105 // We need to clear the identity to call removeContentProviderExternalUnchecked
13106 if (!clearedIdentity) {
13107 ident = Binder.clearCallingIdentity();
13110 if (holder != null) {
13111 removeContentProviderExternalUnchecked(name, null, userId);
13114 Binder.restoreCallingIdentity(ident);
13121 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
13122 if (UserHandle.getUserId(callingUid) == userId) {
13125 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13126 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
13127 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13128 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13134 // =========================================================
13135 // GLOBAL MANAGEMENT
13136 // =========================================================
13139 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
13140 boolean isolated, int isolatedUid) {
13141 String proc = customProcess != null ? customProcess : info.processName;
13142 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13143 final int userId = UserHandle.getUserId(info.uid);
13144 int uid = info.uid;
13146 if (isolatedUid == 0) {
13147 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
13149 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
13150 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
13151 mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
13153 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
13154 mNextIsolatedProcessUid++;
13155 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
13156 // No process for this uid, use it.
13160 if (stepsLeft <= 0) {
13165 // Special case for startIsolatedProcess (internal only), where
13166 // the uid of the isolated process is specified by the caller.
13169 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
13171 // Register the isolated UID with this application so BatteryStats knows to
13172 // attribute resource usage to the application.
13174 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
13175 // about the process state of the isolated UID *before* it is registered with the
13176 // owning application.
13177 mBatteryStatsService.addIsolatedUid(uid, info.uid);
13179 final ProcessRecord r = new ProcessRecord(this, stats, info, proc, uid);
13180 if (!mBooted && !mBooting
13181 && userId == UserHandle.USER_SYSTEM
13182 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
13183 // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
13184 r.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
13185 r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
13186 r.persistent = true;
13187 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
13189 if (isolated && isolatedUid != 0) {
13190 // Special case for startIsolatedProcess (internal only) - assume the process
13191 // is required by the system server to prevent it being killed.
13192 r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
13194 addProcessNameLocked(r);
13198 private boolean uidOnBackgroundWhitelist(final int uid) {
13199 final int appId = UserHandle.getAppId(uid);
13200 final int[] whitelist = mBackgroundAppIdWhitelist;
13201 final int N = whitelist.length;
13202 for (int i = 0; i < N; i++) {
13203 if (appId == whitelist[i]) {
13211 public boolean isBackgroundRestricted(String packageName) {
13212 final int callingUid = Binder.getCallingUid();
13213 final IPackageManager pm = AppGlobals.getPackageManager();
13215 final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
13216 UserHandle.getUserId(callingUid));
13217 if (packageUid != callingUid) {
13218 throw new IllegalArgumentException("Uid " + callingUid
13219 + " cannot query restriction state for package " + packageName);
13221 } catch (RemoteException exc) {
13224 return isBackgroundRestrictedNoCheck(callingUid, packageName);
13227 boolean isBackgroundRestrictedNoCheck(final int uid, final String packageName) {
13228 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
13230 return mode != AppOpsManager.MODE_ALLOWED;
13234 public void backgroundWhitelistUid(final int uid) {
13235 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13236 throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
13239 if (DEBUG_BACKGROUND_CHECK) {
13240 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
13242 synchronized (this) {
13243 final int N = mBackgroundAppIdWhitelist.length;
13244 int[] newList = new int[N+1];
13245 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
13246 newList[N] = UserHandle.getAppId(uid);
13247 mBackgroundAppIdWhitelist = newList;
13252 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13253 String abiOverride) {
13254 return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
13258 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13259 boolean disableHiddenApiChecks, String abiOverride) {
13262 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
13269 app = newProcessRecordLocked(info, customProcess, isolated, 0);
13270 updateLruProcessLocked(app, false, null);
13271 updateOomAdjLocked();
13274 // This package really, really can not be stopped.
13276 AppGlobals.getPackageManager().setPackageStoppedState(
13277 info.packageName, false, UserHandle.getUserId(app.uid));
13278 } catch (RemoteException e) {
13279 } catch (IllegalArgumentException e) {
13280 Slog.w(TAG, "Failed trying to unstop package "
13281 + info.packageName + ": " + e);
13284 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
13285 app.persistent = true;
13286 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
13288 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
13289 mPersistentStartingProcesses.add(app);
13290 startProcessLocked(app, "added application",
13291 customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
13298 public void unhandledBack() {
13299 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
13300 "unhandledBack()");
13302 synchronized(this) {
13303 final long origId = Binder.clearCallingIdentity();
13305 getFocusedStack().unhandledBackLocked();
13307 Binder.restoreCallingIdentity(origId);
13312 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
13313 enforceNotIsolatedCaller("openContentUri");
13314 final int userId = UserHandle.getCallingUserId();
13315 final Uri uri = Uri.parse(uriString);
13316 String name = uri.getAuthority();
13317 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
13318 ParcelFileDescriptor pfd = null;
13320 // We record the binder invoker's uid in thread-local storage before
13321 // going to the content provider to open the file. Later, in the code
13322 // that handles all permissions checks, we look for this uid and use
13323 // that rather than the Activity Manager's own uid. The effect is that
13324 // we do the check against the caller's permissions even though it looks
13325 // to the content provider like the Activity Manager itself is making
13327 Binder token = new Binder();
13328 sCallerIdentity.set(new Identity(
13329 token, Binder.getCallingPid(), Binder.getCallingUid()));
13331 pfd = cph.provider.openFile(null, uri, "r", null, token);
13332 } catch (FileNotFoundException e) {
13333 // do nothing; pfd will be returned null
13335 // Ensure that whatever happens, we clean up the identity state
13336 sCallerIdentity.remove();
13337 // Ensure we're done with the provider.
13338 removeContentProviderExternalUnchecked(name, null, userId);
13341 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
13346 // Actually is sleeping or shutting down or whatever else in the future
13347 // is an inactive state.
13348 boolean isSleepingOrShuttingDownLocked() {
13349 return isSleepingLocked() || mShuttingDown;
13352 boolean isShuttingDownLocked() {
13353 return mShuttingDown;
13356 boolean isSleepingLocked() {
13360 void reportGlobalUsageEventLocked(int event) {
13361 mUsageStatsService.reportEvent("android", mUserController.getCurrentUserId(), event);
13362 int[] profiles = mUserController.getCurrentProfileIds();
13363 if (profiles != null) {
13364 for (int i = profiles.length - 1; i >= 0; i--) {
13365 mUsageStatsService.reportEvent((String)null, profiles[i], event);
13370 void reportCurWakefulnessUsageEventLocked() {
13371 reportGlobalUsageEventLocked(mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE
13372 ? UsageEvents.Event.SCREEN_INTERACTIVE
13373 : UsageEvents.Event.SCREEN_NON_INTERACTIVE);
13376 void reportCurKeyguardUsageEventLocked() {
13377 reportGlobalUsageEventLocked(mKeyguardShown
13378 ? UsageEvents.Event.KEYGUARD_SHOWN
13379 : UsageEvents.Event.KEYGUARD_HIDDEN);
13382 void onWakefulnessChanged(int wakefulness) {
13383 synchronized(this) {
13384 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13385 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13386 mWakefulness = wakefulness;
13388 if (wasAwake != isAwake) {
13389 // Also update state in a special way for running foreground services UI.
13390 mServices.updateScreenStateLocked(isAwake);
13391 reportCurWakefulnessUsageEventLocked();
13392 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
13395 updateOomAdjLocked();
13400 void finishRunningVoiceLocked() {
13401 if (mRunningVoice != null) {
13402 mRunningVoice = null;
13403 mVoiceWakeLock.release();
13404 updateSleepIfNeededLocked();
13408 void startTimeTrackingFocusedActivityLocked() {
13409 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
13410 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
13411 mCurAppTimeTracker.start(resumedActivity.packageName);
13416 void updateSleepIfNeededLocked() {
13417 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
13418 final boolean wasSleeping = mSleeping;
13420 if (!shouldSleep) {
13421 // If wasSleeping is true, we need to wake up activity manager state from when
13422 // we started sleeping. In either case, we need to apply the sleep tokens, which
13423 // will wake up stacks or put them to sleep as appropriate.
13426 startTimeTrackingFocusedActivityLocked();
13427 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
13428 mStackSupervisor.comeOutOfSleepIfNeededLocked();
13430 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
13432 updateOomAdjLocked();
13434 } else if (!mSleeping && shouldSleep) {
13436 if (mCurAppTimeTracker != null) {
13437 mCurAppTimeTracker.stop();
13439 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
13440 mStackSupervisor.goingToSleepLocked();
13441 updateResumedAppTrace(null /* resumed */);
13442 updateOomAdjLocked();
13446 /** Pokes the task persister. */
13447 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
13448 mRecentTasks.notifyTaskPersisterLocked(task, flush);
13452 * Notifies all listeners when the pinned stack animation starts.
13455 public void notifyPinnedStackAnimationStarted() {
13456 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
13460 * Notifies all listeners when the pinned stack animation ends.
13463 public void notifyPinnedStackAnimationEnded() {
13464 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
13468 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
13469 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
13473 public boolean shutdown(int timeout) {
13474 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
13475 != PackageManager.PERMISSION_GRANTED) {
13476 throw new SecurityException("Requires permission "
13477 + android.Manifest.permission.SHUTDOWN);
13480 boolean timedout = false;
13482 synchronized(this) {
13483 mShuttingDown = true;
13484 mStackSupervisor.prepareForShutdownLocked();
13485 updateEventDispatchingLocked();
13486 timedout = mStackSupervisor.shutdownLocked(timeout);
13489 mAppOpsService.shutdown();
13490 if (mUsageStatsService != null) {
13491 mUsageStatsService.prepareShutdown();
13493 mBatteryStatsService.shutdown();
13494 synchronized (this) {
13495 mProcessStats.shutdownLocked();
13496 notifyTaskPersisterLocked(null, true);
13502 public final void activitySlept(IBinder token) {
13503 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
13505 final long origId = Binder.clearCallingIdentity();
13507 synchronized (this) {
13508 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13510 mStackSupervisor.activitySleptLocked(r);
13514 Binder.restoreCallingIdentity(origId);
13518 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
13519 Slog.d(TAG, "<<< startRunningVoiceLocked()");
13520 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
13521 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
13522 boolean wasRunningVoice = mRunningVoice != null;
13523 mRunningVoice = session;
13524 if (!wasRunningVoice) {
13525 mVoiceWakeLock.acquire();
13526 updateSleepIfNeededLocked();
13531 private void updateEventDispatchingLocked() {
13532 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
13536 public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
13537 int secondaryDisplayShowing) {
13538 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
13539 != PackageManager.PERMISSION_GRANTED) {
13540 throw new SecurityException("Requires permission "
13541 + android.Manifest.permission.DEVICE_POWER);
13544 synchronized(this) {
13545 long ident = Binder.clearCallingIdentity();
13546 if (mKeyguardShown != keyguardShowing) {
13547 mKeyguardShown = keyguardShowing;
13548 reportCurKeyguardUsageEventLocked();
13551 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
13552 secondaryDisplayShowing);
13554 Binder.restoreCallingIdentity(ident);
13558 mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
13563 public void notifyLockedProfile(@UserIdInt int userId) {
13565 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
13566 throw new SecurityException("Only privileged app can call notifyLockedProfile");
13568 } catch (RemoteException ex) {
13569 throw new SecurityException("Fail to check is caller a privileged app", ex);
13572 synchronized (this) {
13573 final long ident = Binder.clearCallingIdentity();
13575 if (mUserController.shouldConfirmCredentials(userId)) {
13576 if (mKeyguardController.isKeyguardLocked()) {
13577 // Showing launcher to avoid user entering credential twice.
13578 final int currentUserId = mUserController.getCurrentUserId();
13579 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
13581 mStackSupervisor.lockAllProfileTasks(userId);
13584 Binder.restoreCallingIdentity(ident);
13590 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
13591 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
13592 synchronized (this) {
13593 final long ident = Binder.clearCallingIdentity();
13595 intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
13596 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
13597 FLAG_ACTIVITY_TASK_ON_HOME);
13598 ActivityOptions activityOptions = options != null
13599 ? new ActivityOptions(options)
13600 : ActivityOptions.makeBasic();
13601 activityOptions.setLaunchTaskId(
13602 mStackSupervisor.getHomeActivity().getTask().taskId);
13603 mContext.startActivityAsUser(intent, activityOptions.toBundle(),
13604 UserHandle.CURRENT);
13606 Binder.restoreCallingIdentity(ident);
13612 public void stopAppSwitches() {
13613 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
13614 synchronized(this) {
13615 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
13616 + APP_SWITCH_DELAY_TIME;
13617 mDidAppSwitch = false;
13618 mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
13622 public void resumeAppSwitches() {
13623 enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
13624 synchronized(this) {
13625 // Note that we don't execute any pending app switches... we will
13626 // let those wait until either the timeout, or the next start
13627 // activity request.
13628 mAppSwitchesAllowedTime = 0;
13632 boolean checkAllowAppSwitchUid(int uid) {
13633 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
13634 if (types != null) {
13635 for (int i = types.size() - 1; i >= 0; i--) {
13636 if (types.valueAt(i).intValue() == uid) {
13644 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
13645 int callingPid, int callingUid, String name) {
13646 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
13650 if (mRecentTasks.isCallerRecents(sourceUid)) {
13654 int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
13655 if (perm == PackageManager.PERMISSION_GRANTED) {
13658 if (checkAllowAppSwitchUid(sourceUid)) {
13662 // If the actual IPC caller is different from the logical source, then
13663 // also see if they are allowed to control app switches.
13664 if (callingUid != -1 && callingUid != sourceUid) {
13665 perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
13666 if (perm == PackageManager.PERMISSION_GRANTED) {
13669 if (checkAllowAppSwitchUid(callingUid)) {
13674 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
13678 public void setDebugApp(String packageName, boolean waitForDebugger,
13679 boolean persistent) {
13680 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
13683 long ident = Binder.clearCallingIdentity();
13685 // Note that this is not really thread safe if there are multiple
13686 // callers into it at the same time, but that's not a situation we
13689 final ContentResolver resolver = mContext.getContentResolver();
13690 Settings.Global.putString(
13691 resolver, Settings.Global.DEBUG_APP,
13693 Settings.Global.putInt(
13694 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13695 waitForDebugger ? 1 : 0);
13698 synchronized (this) {
13700 mOrigDebugApp = mDebugApp;
13701 mOrigWaitForDebugger = mWaitForDebugger;
13703 mDebugApp = packageName;
13704 mWaitForDebugger = waitForDebugger;
13705 mDebugTransient = !persistent;
13706 if (packageName != null) {
13707 forceStopPackageLocked(packageName, -1, false, false, true, true,
13708 false, UserHandle.USER_ALL, "set debug app");
13712 Binder.restoreCallingIdentity(ident);
13717 * Set or remove an agent to be run whenever an app with the given process name starts.
13719 * This method will not check whether the given process name matches a debuggable app. That
13720 * would require scanning all current packages, and a rescan when new packages are installed
13723 * Instead, do the check when an application is started and matched to a stored agent.
13725 * @param packageName the process name of the app.
13726 * @param agent the agent string to be used, or null to remove any previously set agent.
13729 public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
13730 synchronized (this) {
13731 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13732 // its own permission.
13733 if (checkCallingPermission(
13734 android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
13735 PackageManager.PERMISSION_GRANTED) {
13736 throw new SecurityException(
13737 "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13740 if (agent == null) {
13741 if (mAppAgentMap != null) {
13742 mAppAgentMap.remove(packageName);
13743 if (mAppAgentMap.isEmpty()) {
13744 mAppAgentMap = null;
13748 if (mAppAgentMap == null) {
13749 mAppAgentMap = new HashMap<>();
13751 if (mAppAgentMap.size() >= 100) {
13752 // Limit the size of the map, to avoid OOMEs.
13753 Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
13757 mAppAgentMap.put(packageName, agent);
13762 void setTrackAllocationApp(ApplicationInfo app, String processName) {
13763 synchronized (this) {
13764 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13765 if (!isDebuggable) {
13766 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13767 throw new SecurityException("Process not debuggable: " + app.packageName);
13771 mTrackAllocationApp = processName;
13775 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
13776 synchronized (this) {
13777 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13778 if (!isDebuggable) {
13779 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13780 throw new SecurityException("Process not debuggable: " + app.packageName);
13783 mProfileApp = processName;
13785 if (mProfilerInfo != null) {
13786 if (mProfilerInfo.profileFd != null) {
13788 mProfilerInfo.profileFd.close();
13789 } catch (IOException e) {
13793 mProfilerInfo = new ProfilerInfo(profilerInfo);
13798 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
13799 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13800 if (!isDebuggable) {
13801 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13802 throw new SecurityException("Process not debuggable: " + app.packageName);
13805 mNativeDebuggingApp = processName;
13809 public void setAlwaysFinish(boolean enabled) {
13810 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13811 "setAlwaysFinish()");
13813 long ident = Binder.clearCallingIdentity();
13815 Settings.Global.putInt(
13816 mContext.getContentResolver(),
13817 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13819 synchronized (this) {
13820 mAlwaysFinishActivities = enabled;
13823 Binder.restoreCallingIdentity(ident);
13828 public void setActivityController(IActivityController controller, boolean imAMonkey) {
13829 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13830 "setActivityController()");
13831 synchronized (this) {
13832 mController = controller;
13833 mControllerIsAMonkey = imAMonkey;
13834 Watchdog.getInstance().setActivityController(controller);
13839 public void setUserIsMonkey(boolean userIsMonkey) {
13840 synchronized (this) {
13841 synchronized (mPidsSelfLocked) {
13842 final int callingPid = Binder.getCallingPid();
13843 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13844 if (proc == null) {
13845 throw new SecurityException("Unknown process: " + callingPid);
13847 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13848 throw new SecurityException("Only an instrumentation process "
13849 + "with a UiAutomation can call setUserIsMonkey");
13852 mUserIsMonkey = userIsMonkey;
13857 public boolean isUserAMonkey() {
13858 synchronized (this) {
13859 // If there is a controller also implies the user is a monkey.
13860 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13865 * @deprecated This method is only used by a few internal components and it will soon be
13866 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13867 * No new code should be calling it.
13871 public void requestBugReport(int bugreportType) {
13872 String extraOptions = null;
13873 switch (bugreportType) {
13874 case ActivityManager.BUGREPORT_OPTION_FULL:
13875 // Default options.
13877 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13878 extraOptions = "bugreportplus";
13880 case ActivityManager.BUGREPORT_OPTION_REMOTE:
13881 extraOptions = "bugreportremote";
13883 case ActivityManager.BUGREPORT_OPTION_WEAR:
13884 extraOptions = "bugreportwear";
13886 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13887 extraOptions = "bugreporttelephony";
13889 case ActivityManager.BUGREPORT_OPTION_WIFI:
13890 extraOptions = "bugreportwifi";
13893 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13896 // Always log caller, even if it does not have permission to dump.
13897 String type = extraOptions == null ? "bugreport" : extraOptions;
13898 Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13900 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13901 if (extraOptions != null) {
13902 SystemProperties.set("dumpstate.options", extraOptions);
13904 SystemProperties.set("ctl.start", "bugreport");
13908 * @deprecated This method is only used by a few internal components and it will soon be
13909 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13910 * No new code should be calling it.
13913 private void requestBugReportWithDescription(String shareTitle, String shareDescription,
13914 int bugreportType) {
13915 if (!TextUtils.isEmpty(shareTitle)) {
13916 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13917 String errorStr = "shareTitle should be less than " +
13918 MAX_BUGREPORT_TITLE_SIZE + " characters";
13919 throw new IllegalArgumentException(errorStr);
13921 if (!TextUtils.isEmpty(shareDescription)) {
13924 length = shareDescription.getBytes("UTF-8").length;
13925 } catch (UnsupportedEncodingException e) {
13926 String errorStr = "shareDescription: UnsupportedEncodingException";
13927 throw new IllegalArgumentException(errorStr);
13929 if (length > SystemProperties.PROP_VALUE_MAX) {
13930 String errorStr = "shareTitle should be less than " +
13931 SystemProperties.PROP_VALUE_MAX + " bytes";
13932 throw new IllegalArgumentException(errorStr);
13934 SystemProperties.set("dumpstate.options.description", shareDescription);
13937 SystemProperties.set("dumpstate.options.title", shareTitle);
13941 Slog.d(TAG, "Bugreport notification title " + shareTitle
13942 + " description " + shareDescription);
13943 requestBugReport(bugreportType);
13947 * @deprecated This method is only used by a few internal components and it will soon be
13948 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13949 * No new code should be calling it.
13953 public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13954 requestBugReportWithDescription(shareTitle, shareDescription,
13955 ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13959 * @deprecated This method is only used by a few internal components and it will soon be
13960 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13961 * No new code should be calling it.
13965 public void requestWifiBugReport(String shareTitle, String shareDescription) {
13966 requestBugReportWithDescription(shareTitle, shareDescription,
13967 ActivityManager.BUGREPORT_OPTION_WIFI);
13971 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13972 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13975 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13976 if (r != null && (r.instr != null || r.usingWrapper)) {
13977 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13979 return KEY_DISPATCHING_TIMEOUT;
13983 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13984 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13985 != PackageManager.PERMISSION_GRANTED) {
13986 throw new SecurityException("Requires permission "
13987 + android.Manifest.permission.FILTER_EVENTS);
13989 ProcessRecord proc;
13991 synchronized (this) {
13992 synchronized (mPidsSelfLocked) {
13993 proc = mPidsSelfLocked.get(pid);
13995 timeout = getInputDispatchingTimeoutLocked(proc);
13998 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
14006 * Handle input dispatching timeouts.
14007 * Returns whether input dispatching should be aborted or not.
14009 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
14010 final ActivityRecord activity, final ActivityRecord parent,
14011 final boolean aboveSystem, String reason) {
14012 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
14013 != PackageManager.PERMISSION_GRANTED) {
14014 throw new SecurityException("Requires permission "
14015 + android.Manifest.permission.FILTER_EVENTS);
14018 final String annotation;
14019 if (reason == null) {
14020 annotation = "Input dispatching timed out";
14022 annotation = "Input dispatching timed out (" + reason + ")";
14025 if (proc != null) {
14026 synchronized (this) {
14027 if (proc.debugging) {
14031 if (proc.instr != null) {
14032 Bundle info = new Bundle();
14033 info.putString("shortMsg", "keyDispatchingTimedOut");
14034 info.putString("longMsg", annotation);
14035 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
14039 mHandler.post(new Runnable() {
14041 public void run() {
14042 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
14051 public Bundle getAssistContextExtras(int requestType) {
14052 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
14053 null, null, true /* focused */, true /* newSessionId */,
14054 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
14058 synchronized (pae) {
14059 while (!pae.haveResult) {
14062 } catch (InterruptedException e) {
14066 synchronized (this) {
14067 buildAssistBundleLocked(pae, pae.result);
14068 mPendingAssistExtras.remove(pae);
14069 mUiHandler.removeCallbacks(pae);
14075 public boolean isAssistDataAllowedOnCurrentActivity() {
14077 synchronized (this) {
14078 final ActivityStack focusedStack = getFocusedStack();
14079 if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
14083 final ActivityRecord activity = focusedStack.getTopActivity();
14084 if (activity == null) {
14087 userId = activity.userId;
14089 return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
14093 public boolean showAssistFromActivity(IBinder token, Bundle args) {
14094 long ident = Binder.clearCallingIdentity();
14096 synchronized (this) {
14097 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
14098 ActivityRecord top = getFocusedStack().getTopActivity();
14099 if (top != caller) {
14100 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
14101 + " is not current top " + top);
14104 if (!top.nowVisible) {
14105 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
14106 + " is not visible");
14110 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
14113 Binder.restoreCallingIdentity(ident);
14118 public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
14119 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
14120 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
14121 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
14122 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
14126 public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
14127 IBinder activityToken, int flags) {
14128 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
14129 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
14130 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
14133 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
14134 IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
14135 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
14137 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
14138 "enqueueAssistContext()");
14140 synchronized (this) {
14141 ActivityRecord activity = getFocusedStack().getTopActivity();
14142 if (activity == null) {
14143 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
14146 if (activity.app == null || activity.app.thread == null) {
14147 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
14151 if (activityToken != null) {
14152 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
14153 if (activity != caller) {
14154 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
14155 + " is not current top " + activity);
14160 activity = ActivityRecord.forTokenLocked(activityToken);
14161 if (activity == null) {
14162 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
14163 + " couldn't be found");
14166 if (activity.app == null || activity.app.thread == null) {
14167 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
14172 PendingAssistExtras pae;
14173 Bundle extras = new Bundle();
14174 if (args != null) {
14175 extras.putAll(args);
14177 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
14178 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
14180 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
14182 pae.isHome = activity.isActivityTypeHome();
14184 // Increment the sessionId if necessary
14185 if (newSessionId) {
14189 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
14190 mViSessionId, flags);
14191 mPendingAssistExtras.add(pae);
14192 mUiHandler.postDelayed(pae, timeout);
14193 } catch (RemoteException e) {
14194 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
14201 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
14202 IAssistDataReceiver receiver;
14203 synchronized (this) {
14204 mPendingAssistExtras.remove(pae);
14205 receiver = pae.receiver;
14207 if (receiver != null) {
14208 // Caller wants result sent back to them.
14209 Bundle sendBundle = new Bundle();
14210 // At least return the receiver extras
14211 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
14213 pae.receiver.onHandleAssistData(sendBundle);
14214 } catch (RemoteException e) {
14219 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
14220 if (result != null) {
14221 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
14223 if (pae.hint != null) {
14224 pae.extras.putBoolean(pae.hint, true);
14228 /** Called from an app when assist data is ready. */
14230 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
14231 AssistContent content, Uri referrer) {
14232 PendingAssistExtras pae = (PendingAssistExtras)token;
14233 synchronized (pae) {
14234 pae.result = extras;
14235 pae.structure = structure;
14236 pae.content = content;
14237 if (referrer != null) {
14238 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
14240 if (structure != null) {
14241 structure.setHomeActivity(pae.isHome);
14243 pae.haveResult = true;
14245 if (pae.intent == null && pae.receiver == null) {
14246 // Caller is just waiting for the result.
14250 // We are now ready to launch the assist activity.
14251 IAssistDataReceiver sendReceiver = null;
14252 Bundle sendBundle = null;
14253 synchronized (this) {
14254 buildAssistBundleLocked(pae, extras);
14255 boolean exists = mPendingAssistExtras.remove(pae);
14256 mUiHandler.removeCallbacks(pae);
14262 if ((sendReceiver=pae.receiver) != null) {
14263 // Caller wants result sent back to them.
14264 sendBundle = new Bundle();
14265 sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
14266 sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
14267 sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
14268 sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
14271 if (sendReceiver != null) {
14273 sendReceiver.onHandleAssistData(sendBundle);
14274 } catch (RemoteException e) {
14279 final long ident = Binder.clearCallingIdentity();
14281 if (TextUtils.equals(pae.intent.getAction(),
14282 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
14283 pae.intent.putExtras(pae.extras);
14284 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
14286 pae.intent.replaceExtras(pae.extras);
14287 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
14288 | Intent.FLAG_ACTIVITY_SINGLE_TOP
14289 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
14290 closeSystemDialogs("assist");
14293 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
14294 } catch (ActivityNotFoundException e) {
14295 Slog.w(TAG, "No activity to handle assist action.", e);
14299 Binder.restoreCallingIdentity(ident);
14303 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
14305 return enqueueAssistContext(requestType, intent, hint, null, null, null,
14306 true /* focused */, true /* newSessionId */, userHandle, args,
14307 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
14310 public void registerProcessObserver(IProcessObserver observer) {
14311 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
14312 "registerProcessObserver()");
14313 synchronized (this) {
14314 mProcessObservers.register(observer);
14319 public void unregisterProcessObserver(IProcessObserver observer) {
14320 synchronized (this) {
14321 mProcessObservers.unregister(observer);
14326 public int getUidProcessState(int uid, String callingPackage) {
14327 if (!hasUsageStatsPermission(callingPackage)) {
14328 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14329 "getUidProcessState");
14332 synchronized (this) {
14333 UidRecord uidRec = mActiveUids.get(uid);
14334 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
14339 public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
14340 String callingPackage) {
14341 if (!hasUsageStatsPermission(callingPackage)) {
14342 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14343 "registerUidObserver");
14345 synchronized (this) {
14346 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
14347 callingPackage, which, cutpoint));
14352 public void unregisterUidObserver(IUidObserver observer) {
14353 synchronized (this) {
14354 mUidObservers.unregister(observer);
14359 public boolean isUidActive(int uid, String callingPackage) {
14360 if (!hasUsageStatsPermission(callingPackage)) {
14361 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14364 synchronized (this) {
14365 return isUidActiveLocked(uid);
14369 boolean isUidActiveLocked(int uid) {
14370 final UidRecord uidRecord = mActiveUids.get(uid);
14371 return uidRecord != null && !uidRecord.setIdle;
14375 public boolean convertFromTranslucent(IBinder token) {
14376 final long origId = Binder.clearCallingIdentity();
14378 synchronized (this) {
14379 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14383 final boolean translucentChanged = r.changeWindowTranslucency(true);
14384 if (translucentChanged) {
14385 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14387 mWindowManager.setAppFullscreen(token, true);
14388 return translucentChanged;
14391 Binder.restoreCallingIdentity(origId);
14396 public boolean convertToTranslucent(IBinder token, Bundle options) {
14397 SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
14398 final long origId = Binder.clearCallingIdentity();
14400 synchronized (this) {
14401 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14405 final TaskRecord task = r.getTask();
14406 int index = task.mActivities.lastIndexOf(r);
14408 ActivityRecord under = task.mActivities.get(index - 1);
14409 under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
14411 final boolean translucentChanged = r.changeWindowTranslucency(false);
14412 if (translucentChanged) {
14413 r.getStack().convertActivityToTranslucent(r);
14415 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14416 mWindowManager.setAppFullscreen(token, false);
14417 return translucentChanged;
14420 Binder.restoreCallingIdentity(origId);
14425 public Bundle getActivityOptions(IBinder token) {
14426 final long origId = Binder.clearCallingIdentity();
14428 synchronized (this) {
14429 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14431 final ActivityOptions activityOptions = r.takeOptionsLocked();
14432 return activityOptions == null ? null : activityOptions.toBundle();
14437 Binder.restoreCallingIdentity(origId);
14442 public void setImmersive(IBinder token, boolean immersive) {
14443 synchronized(this) {
14444 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14446 throw new IllegalArgumentException();
14448 r.immersive = immersive;
14450 // update associated state if we're frontmost
14451 if (r == mStackSupervisor.getResumedActivityLocked()) {
14452 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
14453 applyUpdateLockStateLocked(r);
14459 public boolean isImmersive(IBinder token) {
14460 synchronized (this) {
14461 ActivityRecord r = ActivityRecord.isInStackLocked(token);
14463 throw new IllegalArgumentException();
14465 return r.immersive;
14470 public void setVrThread(int tid) {
14471 enforceSystemHasVrFeature();
14472 synchronized (this) {
14473 synchronized (mPidsSelfLocked) {
14474 final int pid = Binder.getCallingPid();
14475 final ProcessRecord proc = mPidsSelfLocked.get(pid);
14476 mVrController.setVrThreadLocked(tid, pid, proc);
14482 public void setPersistentVrThread(int tid) {
14483 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
14484 final String msg = "Permission Denial: setPersistentVrThread() from pid="
14485 + Binder.getCallingPid()
14486 + ", uid=" + Binder.getCallingUid()
14487 + " requires " + permission.RESTRICTED_VR_ACCESS;
14489 throw new SecurityException(msg);
14491 enforceSystemHasVrFeature();
14492 synchronized (this) {
14493 synchronized (mPidsSelfLocked) {
14494 final int pid = Binder.getCallingPid();
14495 final ProcessRecord proc = mPidsSelfLocked.get(pid);
14496 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
14502 * Schedule the given thread a normal scheduling priority.
14504 * @param tid the tid of the thread to adjust the scheduling of.
14505 * @param suppressLogs {@code true} if any error logging should be disabled.
14507 * @return {@code true} if this succeeded.
14509 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
14511 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
14513 } catch (IllegalArgumentException e) {
14514 if (!suppressLogs) {
14515 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14517 } catch (SecurityException e) {
14518 if (!suppressLogs) {
14519 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14526 * Schedule the given thread an FIFO scheduling priority.
14528 * @param tid the tid of the thread to adjust the scheduling of.
14529 * @param suppressLogs {@code true} if any error logging should be disabled.
14531 * @return {@code true} if this succeeded.
14533 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
14535 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
14537 } catch (IllegalArgumentException e) {
14538 if (!suppressLogs) {
14539 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14541 } catch (SecurityException e) {
14542 if (!suppressLogs) {
14543 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14550 * Check that we have the features required for VR-related API calls, and throw an exception if
14553 private void enforceSystemHasVrFeature() {
14554 if (!mContext.getPackageManager().hasSystemFeature(
14555 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
14556 throw new UnsupportedOperationException("VR mode not supported on this device!");
14561 public void setRenderThread(int tid) {
14562 synchronized (this) {
14563 ProcessRecord proc;
14564 int pid = Binder.getCallingPid();
14565 if (pid == Process.myPid()) {
14566 demoteSystemServerRenderThread(tid);
14569 synchronized (mPidsSelfLocked) {
14570 proc = mPidsSelfLocked.get(pid);
14571 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
14572 // ensure the tid belongs to the process
14573 if (!isThreadInProcess(pid, tid)) {
14574 throw new IllegalArgumentException(
14575 "Render thread does not belong to process");
14577 proc.renderThreadTid = tid;
14578 if (DEBUG_OOM_ADJ) {
14579 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
14581 // promote to FIFO now
14582 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
14583 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
14584 if (mUseFifoUiScheduling) {
14585 setThreadScheduler(proc.renderThreadTid,
14586 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
14588 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
14592 if (DEBUG_OOM_ADJ) {
14593 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
14594 "PID: " + pid + ", TID: " + tid + " FIFO: " +
14595 mUseFifoUiScheduling);
14603 * We only use RenderThread in system_server to store task snapshots to the disk, which should
14604 * happen in the background. Thus, demote render thread from system_server to a lower priority.
14606 * @param tid the tid of the RenderThread
14608 private void demoteSystemServerRenderThread(int tid) {
14609 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
14613 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
14614 enforceSystemHasVrFeature();
14616 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14619 synchronized (this) {
14620 r = ActivityRecord.isInStackLocked(token);
14624 throw new IllegalArgumentException();
14628 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
14629 VrManagerInternal.NO_ERROR) {
14633 // Clear the binder calling uid since this path may call moveToTask().
14634 final long callingId = Binder.clearCallingIdentity();
14636 synchronized(this) {
14637 r.requestedVrComponent = (enabled) ? packageName : null;
14639 // Update associated state if this activity is currently focused
14640 if (r == mStackSupervisor.getResumedActivityLocked()) {
14641 applyUpdateVrModeLocked(r);
14646 Binder.restoreCallingIdentity(callingId);
14651 public boolean isVrModePackageEnabled(ComponentName packageName) {
14652 enforceSystemHasVrFeature();
14654 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14656 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
14657 VrManagerInternal.NO_ERROR;
14660 public boolean isTopActivityImmersive() {
14661 enforceNotIsolatedCaller("startActivity");
14662 synchronized (this) {
14663 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
14664 return (r != null) ? r.immersive : false;
14669 * @return whether the system should disable UI modes incompatible with VR mode.
14671 boolean shouldDisableNonVrUiLocked() {
14672 return mVrController.shouldDisableNonVrUiLocked();
14676 public boolean isTopOfTask(IBinder token) {
14677 synchronized (this) {
14678 ActivityRecord r = ActivityRecord.isInStackLocked(token);
14680 throw new IllegalArgumentException();
14682 return r.getTask().getTopActivity() == r;
14687 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
14688 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
14689 String msg = "Permission Denial: setHasTopUi() from pid="
14690 + Binder.getCallingPid()
14691 + ", uid=" + Binder.getCallingUid()
14692 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
14694 throw new SecurityException(msg);
14696 final int pid = Binder.getCallingPid();
14697 final long origId = Binder.clearCallingIdentity();
14699 synchronized (this) {
14700 boolean changed = false;
14702 synchronized (mPidsSelfLocked) {
14703 pr = mPidsSelfLocked.get(pid);
14705 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
14708 if (pr.hasTopUi != hasTopUi) {
14709 if (DEBUG_OOM_ADJ) {
14710 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
14712 pr.hasTopUi = hasTopUi;
14717 updateOomAdjLocked(pr, true);
14721 Binder.restoreCallingIdentity(origId);
14725 void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
14726 if (pid == Process.myPid()) {
14727 Slog.wtf(TAG, "system can't run remote animation");
14730 synchronized (ActivityManagerService.this) {
14731 final ProcessRecord pr;
14732 synchronized (mPidsSelfLocked) {
14733 pr = mPidsSelfLocked.get(pid);
14735 Slog.w(TAG, "setRunningRemoteAnimation called on unknown pid: " + pid);
14739 if (pr.runningRemoteAnimation == runningRemoteAnimation) {
14742 pr.runningRemoteAnimation = runningRemoteAnimation;
14743 if (DEBUG_OOM_ADJ) {
14744 Slog.i(TAG, "Setting runningRemoteAnimation=" + pr.runningRemoteAnimation
14745 + " for pid=" + pid);
14747 updateOomAdjLocked(pr, true);
14751 public final void enterSafeMode() {
14752 synchronized(this) {
14753 // It only makes sense to do this before the system is ready
14754 // and started launching other packages.
14755 if (!mSystemReady) {
14757 AppGlobals.getPackageManager().enterSafeMode();
14758 } catch (RemoteException e) {
14766 public final void showSafeModeOverlay() {
14767 View v = LayoutInflater.from(mContext).inflate(
14768 com.android.internal.R.layout.safe_mode, null);
14769 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
14770 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
14771 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
14772 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
14773 lp.gravity = Gravity.BOTTOM | Gravity.START;
14774 lp.format = v.getBackground().getOpacity();
14775 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
14776 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
14777 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
14778 ((WindowManager)mContext.getSystemService(
14779 Context.WINDOW_SERVICE)).addView(v, lp);
14783 public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
14784 String sourcePkg, String tag) {
14785 if (workSource != null && workSource.isEmpty()) {
14789 if (sourceUid <= 0 && workSource == null) {
14790 // Try and derive a UID to attribute things to based on the caller.
14791 if (sender != null) {
14792 if (!(sender instanceof PendingIntentRecord)) {
14796 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14797 final int callerUid = Binder.getCallingUid();
14798 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14800 // TODO(narayan): Should we throw an exception in this case ? It means that we
14801 // haven't been able to derive a UID to attribute things to.
14807 Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
14808 + ", workSource=" + workSource + ", tag=" + tag + "]");
14811 mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
14815 public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14817 if (workSource != null && workSource.isEmpty()) {
14821 if (sourceUid <= 0 && workSource == null) {
14822 // Try and derive a UID to attribute things to based on the caller.
14823 if (sender != null) {
14824 if (!(sender instanceof PendingIntentRecord)) {
14828 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14829 final int callerUid = Binder.getCallingUid();
14830 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14832 // TODO(narayan): Should we throw an exception in this case ? It means that we
14833 // haven't been able to derive a UID to attribute things to.
14839 Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14840 ", tag=" + tag + "]");
14843 mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14847 public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14849 if (workSource != null && workSource.isEmpty()) {
14853 if (sourceUid <= 0 && workSource == null) {
14854 // Try and derive a UID to attribute things to based on the caller.
14855 if (sender != null) {
14856 if (!(sender instanceof PendingIntentRecord)) {
14860 final PendingIntentRecord rec = (PendingIntentRecord) sender;
14861 final int callerUid = Binder.getCallingUid();
14862 sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14864 // TODO(narayan): Should we throw an exception in this case ? It means that we
14865 // haven't been able to derive a UID to attribute things to.
14871 Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14872 ", tag=" + tag + "]");
14875 mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
14878 public boolean killPids(int[] pids, String pReason, boolean secure) {
14879 if (Binder.getCallingUid() != SYSTEM_UID) {
14880 throw new SecurityException("killPids only available to the system");
14882 String reason = (pReason == null) ? "Unknown" : pReason;
14883 // XXX Note: don't acquire main activity lock here, because the window
14884 // manager calls in with its locks held.
14886 boolean killed = false;
14887 synchronized (mPidsSelfLocked) {
14889 for (int i=0; i<pids.length; i++) {
14890 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14891 if (proc != null) {
14892 int type = proc.setAdj;
14893 if (type > worstType) {
14899 // If the worst oom_adj is somewhere in the cached proc LRU range,
14900 // then constrain it so we will kill all cached procs.
14901 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14902 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14903 worstType = ProcessList.CACHED_APP_MIN_ADJ;
14906 // If this is not a secure call, don't let it kill processes that
14908 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14909 worstType = ProcessList.SERVICE_ADJ;
14912 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14913 for (int i=0; i<pids.length; i++) {
14914 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14915 if (proc == null) {
14918 int adj = proc.setAdj;
14919 if (adj >= worstType && !proc.killedByAm) {
14920 proc.kill(reason, true);
14929 public void killUid(int appId, int userId, String reason) {
14930 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14931 synchronized (this) {
14932 final long identity = Binder.clearCallingIdentity();
14934 killPackageProcessesLocked(null, appId, userId,
14935 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14936 reason != null ? reason : "kill uid");
14938 Binder.restoreCallingIdentity(identity);
14944 public boolean killProcessesBelowForeground(String reason) {
14945 if (Binder.getCallingUid() != SYSTEM_UID) {
14946 throw new SecurityException("killProcessesBelowForeground() only available to system");
14949 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14952 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14953 if (Binder.getCallingUid() != SYSTEM_UID) {
14954 throw new SecurityException("killProcessesBelowAdj() only available to system");
14957 boolean killed = false;
14958 synchronized (mPidsSelfLocked) {
14959 final int size = mPidsSelfLocked.size();
14960 for (int i = 0; i < size; i++) {
14961 final int pid = mPidsSelfLocked.keyAt(i);
14962 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14963 if (proc == null) continue;
14965 final int adj = proc.setAdj;
14966 if (adj > belowAdj && !proc.killedByAm) {
14967 proc.kill(reason, true);
14976 public void hang(final IBinder who, boolean allowRestart) {
14977 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14978 != PackageManager.PERMISSION_GRANTED) {
14979 throw new SecurityException("Requires permission "
14980 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14983 final IBinder.DeathRecipient death = new DeathRecipient() {
14985 public void binderDied() {
14986 synchronized (this) {
14993 who.linkToDeath(death, 0);
14994 } catch (RemoteException e) {
14995 Slog.w(TAG, "hang: given caller IBinder is already dead.");
14999 synchronized (this) {
15000 Watchdog.getInstance().setAllowRestart(allowRestart);
15001 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
15002 synchronized (death) {
15003 while (who.isBinderAlive()) {
15006 } catch (InterruptedException e) {
15010 Watchdog.getInstance().setAllowRestart(true);
15015 public void restart() {
15016 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15017 != PackageManager.PERMISSION_GRANTED) {
15018 throw new SecurityException("Requires permission "
15019 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15022 Log.i(TAG, "Sending shutdown broadcast...");
15024 BroadcastReceiver br = new BroadcastReceiver() {
15025 @Override public void onReceive(Context context, Intent intent) {
15026 // Now the broadcast is done, finish up the low-level shutdown.
15027 Log.i(TAG, "Shutting down activity manager...");
15029 Log.i(TAG, "Shutdown complete, restarting!");
15030 killProcess(myPid());
15035 // First send the high-level shut down broadcast.
15036 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
15037 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15038 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
15039 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
15040 mContext.sendOrderedBroadcastAsUser(intent,
15041 UserHandle.ALL, null, br, mHandler, 0, null, null);
15043 br.onReceive(mContext, intent);
15046 private long getLowRamTimeSinceIdle(long now) {
15047 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
15051 public void performIdleMaintenance() {
15052 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15053 != PackageManager.PERMISSION_GRANTED) {
15054 throw new SecurityException("Requires permission "
15055 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15058 synchronized (this) {
15059 final long now = SystemClock.uptimeMillis();
15060 final long timeSinceLastIdle = now - mLastIdleTime;
15061 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
15062 mLastIdleTime = now;
15063 mLowRamTimeSinceLastIdle = 0;
15064 if (mLowRamStartTime != 0) {
15065 mLowRamStartTime = now;
15068 StringBuilder sb = new StringBuilder(128);
15069 sb.append("Idle maintenance over ");
15070 TimeUtils.formatDuration(timeSinceLastIdle, sb);
15071 sb.append(" low RAM for ");
15072 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
15073 Slog.i(TAG, sb.toString());
15075 // If at least 1/3 of our time since the last idle period has been spent
15076 // with RAM low, then we want to kill processes.
15077 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
15079 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15080 ProcessRecord proc = mLruProcesses.get(i);
15081 if (proc.notCachedSinceIdle) {
15082 if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
15083 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
15084 if (doKilling && proc.initialIdlePss != 0
15085 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
15086 sb = new StringBuilder(128);
15088 sb.append(proc.processName);
15089 sb.append(" in idle maint: pss=");
15090 sb.append(proc.lastPss);
15091 sb.append(", swapPss=");
15092 sb.append(proc.lastSwapPss);
15093 sb.append(", initialPss=");
15094 sb.append(proc.initialIdlePss);
15095 sb.append(", period=");
15096 TimeUtils.formatDuration(timeSinceLastIdle, sb);
15097 sb.append(", lowRamPeriod=");
15098 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
15099 Slog.wtfQuiet(TAG, sb.toString());
15100 proc.kill("idle maint (pss " + proc.lastPss
15101 + " from " + proc.initialIdlePss + ")", true);
15104 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
15105 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
15106 proc.notCachedSinceIdle = true;
15107 proc.initialIdlePss = 0;
15108 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
15109 mTestPssMode, isSleepingLocked(), now);
15116 public void sendIdleJobTrigger() {
15117 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15118 != PackageManager.PERMISSION_GRANTED) {
15119 throw new SecurityException("Requires permission "
15120 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15123 final long ident = Binder.clearCallingIdentity();
15125 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
15126 .setPackage("android")
15127 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15128 broadcastIntent(null, intent, null, null, 0, null, null, null,
15129 OP_NONE, null, false, false, UserHandle.USER_ALL);
15131 Binder.restoreCallingIdentity(ident);
15135 private void retrieveSettings() {
15136 final ContentResolver resolver = mContext.getContentResolver();
15137 final boolean freeformWindowManagement =
15138 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
15139 || Settings.Global.getInt(
15140 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
15142 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
15143 final boolean supportsPictureInPicture = supportsMultiWindow &&
15144 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
15145 final boolean supportsSplitScreenMultiWindow =
15146 ActivityManager.supportsSplitScreenMultiWindow(mContext);
15147 final boolean supportsMultiDisplay = mContext.getPackageManager()
15148 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
15149 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
15150 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
15151 final boolean alwaysFinishActivities =
15152 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
15153 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
15154 final boolean forceResizable = Settings.Global.getInt(
15155 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
15156 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
15157 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
15158 final boolean supportsLeanbackOnly =
15159 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
15160 mHiddenApiBlacklist.registerObserver();
15162 // Transfer any global setting for forcing RTL layout, into a System Property
15163 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
15165 final Configuration configuration = new Configuration();
15166 Settings.System.getConfiguration(resolver, configuration);
15168 // This will take care of setting the correct layout direction flags
15169 configuration.setLayoutDirection(configuration.locale);
15172 synchronized (this) {
15173 mDebugApp = mOrigDebugApp = debugApp;
15174 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
15175 mAlwaysFinishActivities = alwaysFinishActivities;
15176 mSupportsLeanbackOnly = supportsLeanbackOnly;
15177 mForceResizableActivities = forceResizable;
15178 final boolean multiWindowFormEnabled = freeformWindowManagement
15179 || supportsSplitScreenMultiWindow
15180 || supportsPictureInPicture
15181 || supportsMultiDisplay;
15182 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
15183 mSupportsMultiWindow = true;
15184 mSupportsFreeformWindowManagement = freeformWindowManagement;
15185 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
15186 mSupportsPictureInPicture = supportsPictureInPicture;
15187 mSupportsMultiDisplay = supportsMultiDisplay;
15189 mSupportsMultiWindow = false;
15190 mSupportsFreeformWindowManagement = false;
15191 mSupportsSplitScreenMultiWindow = false;
15192 mSupportsPictureInPicture = false;
15193 mSupportsMultiDisplay = false;
15195 mWindowManager.setForceResizableTasks(mForceResizableActivities);
15196 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
15197 // This happens before any activities are started, so we can change global configuration
15199 updateConfigurationLocked(configuration, null, true);
15200 final Configuration globalConfig = getGlobalConfiguration();
15201 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
15203 // Load resources only after the current configuration has been set.
15204 final Resources res = mContext.getResources();
15205 mThumbnailWidth = res.getDimensionPixelSize(
15206 com.android.internal.R.dimen.thumbnail_width);
15207 mThumbnailHeight = res.getDimensionPixelSize(
15208 com.android.internal.R.dimen.thumbnail_height);
15209 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
15210 com.android.internal.R.string.config_appsNotReportingCrashes));
15211 mUserController.mUserSwitchUiEnabled = !res.getBoolean(
15212 com.android.internal.R.bool.config_customUserSwitchUi);
15213 mUserController.mMaxRunningUsers = res.getInteger(
15214 com.android.internal.R.integer.config_multiuserMaxRunningUsers);
15216 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
15217 mFullscreenThumbnailScale = (float) res
15218 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
15219 (float) globalConfig.screenWidthDp;
15221 mFullscreenThumbnailScale = res.getFraction(
15222 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
15224 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
15228 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
15229 traceLog.traceBegin("PhaseActivityManagerReady");
15230 synchronized(this) {
15231 if (mSystemReady) {
15232 // If we're done calling all the receivers, run the next "boot phase" passed in
15233 // by the SystemServer
15234 if (goingCallback != null) {
15235 goingCallback.run();
15240 mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
15241 PackageManager.FEATURE_CANT_SAVE_STATE);
15242 mLocalDeviceIdleController
15243 = LocalServices.getService(DeviceIdleController.LocalService.class);
15244 mAssistUtils = new AssistUtils(mContext);
15245 mVrController.onSystemReady();
15246 // Make sure we have the current profile info, since it is needed for security checks.
15247 mUserController.onSystemReady();
15248 mRecentTasks.onSystemReadyLocked();
15249 mAppOpsService.systemReady();
15250 mSystemReady = true;
15254 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
15255 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
15257 } catch (RemoteException e) {}
15259 ArrayList<ProcessRecord> procsToKill = null;
15260 synchronized(mPidsSelfLocked) {
15261 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
15262 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
15263 if (!isAllowedWhileBooting(proc.info)){
15264 if (procsToKill == null) {
15265 procsToKill = new ArrayList<ProcessRecord>();
15267 procsToKill.add(proc);
15272 synchronized(this) {
15273 if (procsToKill != null) {
15274 for (int i=procsToKill.size()-1; i>=0; i--) {
15275 ProcessRecord proc = procsToKill.get(i);
15276 Slog.i(TAG, "Removing system update proc: " + proc);
15277 removeProcessLocked(proc, true, false, "system update done");
15281 // Now that we have cleaned up any update processes, we
15282 // are ready to start launching real processes and know that
15283 // we won't trample on them any more.
15284 mProcessesReady = true;
15287 Slog.i(TAG, "System now ready");
15288 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
15289 SystemClock.uptimeMillis());
15291 synchronized(this) {
15292 // Make sure we have no pre-ready processes sitting around.
15294 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
15295 ResolveInfo ri = mContext.getPackageManager()
15296 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
15298 CharSequence errorMsg = null;
15300 ActivityInfo ai = ri.activityInfo;
15301 ApplicationInfo app = ai.applicationInfo;
15302 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
15303 mTopAction = Intent.ACTION_FACTORY_TEST;
15305 mTopComponent = new ComponentName(app.packageName,
15308 errorMsg = mContext.getResources().getText(
15309 com.android.internal.R.string.factorytest_not_system);
15312 errorMsg = mContext.getResources().getText(
15313 com.android.internal.R.string.factorytest_no_action);
15315 if (errorMsg != null) {
15318 mTopComponent = null;
15319 Message msg = Message.obtain();
15320 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
15321 msg.getData().putCharSequence("msg", errorMsg);
15322 mUiHandler.sendMessage(msg);
15327 retrieveSettings();
15328 final int currentUserId = mUserController.getCurrentUserId();
15329 synchronized (this) {
15330 readGrantedUriPermissionsLocked();
15333 final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
15335 pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
15336 state -> updateForceBackgroundCheck(state.batterySaverEnabled));
15337 updateForceBackgroundCheck(
15338 pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
15340 Slog.wtf(TAG, "PowerManagerInternal not found.");
15343 if (goingCallback != null) goingCallback.run();
15344 traceLog.traceBegin("ActivityManagerStartApps");
15345 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
15346 Integer.toString(currentUserId), currentUserId);
15347 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
15348 Integer.toString(currentUserId), currentUserId);
15349 mSystemServiceManager.startUser(currentUserId);
15351 synchronized (this) {
15352 // Only start up encryption-aware persistent apps; once user is
15353 // unlocked we'll come back around and start unaware apps
15354 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
15356 // Start up initial activity.
15358 // Enable home activity for system user, so that the system can always boot. We don't
15359 // do this when the system user is not setup since the setup wizard should be the one
15360 // to handle home activity in this case.
15361 if (UserManager.isSplitSystemUser() &&
15362 Settings.Secure.getInt(mContext.getContentResolver(),
15363 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
15364 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
15366 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
15367 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
15368 UserHandle.USER_SYSTEM);
15369 } catch (RemoteException e) {
15370 throw e.rethrowAsRuntimeException();
15373 startHomeActivityLocked(currentUserId, "systemReady");
15376 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
15377 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
15378 + " data partition or your device will be unstable.");
15379 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
15381 } catch (RemoteException e) {
15384 if (!Build.isBuildConsistent()) {
15385 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
15386 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
15389 long ident = Binder.clearCallingIdentity();
15391 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
15392 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15393 | Intent.FLAG_RECEIVER_FOREGROUND);
15394 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15395 broadcastIntentLocked(null, null, intent,
15396 null, null, 0, null, null, null, OP_NONE,
15397 null, false, false, MY_PID, SYSTEM_UID,
15399 intent = new Intent(Intent.ACTION_USER_STARTING);
15400 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15401 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15402 broadcastIntentLocked(null, null, intent,
15403 null, new IIntentReceiver.Stub() {
15405 public void performReceive(Intent intent, int resultCode, String data,
15406 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
15407 throws RemoteException {
15410 new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
15411 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
15412 } catch (Throwable t) {
15413 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
15415 Binder.restoreCallingIdentity(ident);
15417 mStackSupervisor.resumeFocusedStackTopActivityLocked();
15418 mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
15420 BinderInternal.nSetBinderProxyCountWatermarks(6000,5500);
15421 BinderInternal.nSetBinderProxyCountEnabled(true);
15422 BinderInternal.setBinderProxyCountCallback(
15423 new BinderInternal.BinderProxyLimitListener() {
15425 public void onLimitReached(int uid) {
15426 Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
15427 + Process.myUid());
15428 if (uid == Process.SYSTEM_UID) {
15429 Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
15431 killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
15432 "Too many Binders sent to SYSTEM");
15437 traceLog.traceEnd(); // ActivityManagerStartApps
15438 traceLog.traceEnd(); // PhaseActivityManagerReady
15442 private void updateForceBackgroundCheck(boolean enabled) {
15443 synchronized (this) {
15444 if (mForceBackgroundCheck != enabled) {
15445 mForceBackgroundCheck = enabled;
15447 if (DEBUG_BACKGROUND_CHECK) {
15448 Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
15451 if (mForceBackgroundCheck) {
15452 // Stop background services for idle UIDs.
15453 doStopUidForIdleUidsLocked();
15459 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
15460 synchronized (this) {
15461 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
15465 void skipCurrentReceiverLocked(ProcessRecord app) {
15466 for (BroadcastQueue queue : mBroadcastQueues) {
15467 queue.skipCurrentReceiverLocked(app);
15472 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
15473 * The application process will exit immediately after this call returns.
15474 * @param app object of the crashing app, null for the system server
15475 * @param crashInfo describing the exception
15477 public void handleApplicationCrash(IBinder app,
15478 ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15479 ProcessRecord r = findAppProcess(app, "Crash");
15480 final String processName = app == null ? "system_server"
15481 : (r == null ? "unknown" : r.processName);
15483 handleApplicationCrashInner("crash", r, processName, crashInfo);
15486 /* Native crash reporting uses this inner version because it needs to be somewhat
15487 * decoupled from the AM-managed cleanup lifecycle
15489 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
15490 ApplicationErrorReport.CrashInfo crashInfo) {
15491 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
15492 UserHandle.getUserId(Binder.getCallingUid()), processName,
15493 r == null ? -1 : r.info.flags,
15494 crashInfo.exceptionClassName,
15495 crashInfo.exceptionMessage,
15496 crashInfo.throwFileName,
15497 crashInfo.throwLineNumber);
15499 StatsLog.write(StatsLog.APP_CRASH_OCCURRED,
15500 Binder.getCallingUid(),
15503 Binder.getCallingPid(),
15504 (r != null && r.info != null) ? r.info.packageName : "",
15505 (r != null && r.info != null) ? (r.info.isInstantApp()
15506 ? StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__TRUE
15507 : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__FALSE)
15508 : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__UNAVAILABLE,
15509 r != null ? (r.isInterestingToUserLocked()
15510 ? StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__FOREGROUND
15511 : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__BACKGROUND)
15512 : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__UNKNOWN
15515 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
15517 mAppErrors.crashApplication(r, crashInfo);
15520 public void handleApplicationStrictModeViolation(
15523 StrictMode.ViolationInfo info) {
15524 // We're okay if the ProcessRecord is missing; it probably means that
15525 // we're reporting a violation from the system process itself.
15526 final ProcessRecord r = findAppProcess(app, "StrictMode");
15528 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
15529 Integer stackFingerprint = info.hashCode();
15530 boolean logIt = true;
15531 synchronized (mAlreadyLoggedViolatedStacks) {
15532 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
15534 // TODO: sub-sample into EventLog for these, with
15535 // the info.durationMillis? Then we'd get
15536 // the relative pain numbers, without logging all
15537 // the stack traces repeatedly. We'd want to do
15538 // likewise in the client code, which also does
15539 // dup suppression, before the Binder call.
15541 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
15542 mAlreadyLoggedViolatedStacks.clear();
15544 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
15548 logStrictModeViolationToDropBox(r, info);
15552 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
15553 AppErrorResult result = new AppErrorResult();
15554 synchronized (this) {
15555 final long origId = Binder.clearCallingIdentity();
15557 Message msg = Message.obtain();
15558 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
15559 HashMap<String, Object> data = new HashMap<String, Object>();
15560 data.put("result", result);
15561 data.put("app", r);
15562 data.put("violationMask", violationMask);
15563 data.put("info", info);
15565 mUiHandler.sendMessage(msg);
15567 Binder.restoreCallingIdentity(origId);
15569 int res = result.get();
15570 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
15574 // Depending on the policy in effect, there could be a bunch of
15575 // these in quick succession so we try to batch these together to
15576 // minimize disk writes, number of dropbox entries, and maximize
15577 // compression, by having more fewer, larger records.
15578 private void logStrictModeViolationToDropBox(
15579 ProcessRecord process,
15580 StrictMode.ViolationInfo info) {
15581 if (info == null) {
15584 final boolean isSystemApp = process == null ||
15585 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
15586 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
15587 final String processName = process == null ? "unknown" : process.processName;
15588 final DropBoxManager dbox = (DropBoxManager)
15589 mContext.getSystemService(Context.DROPBOX_SERVICE);
15591 // Exit early if the dropbox isn't configured to accept this report type.
15592 final String dropboxTag = processClass(process) + "_strictmode";
15593 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15595 final StringBuilder sb = new StringBuilder(1024);
15596 synchronized (sb) {
15597 appendDropBoxProcessHeaders(process, processName, sb);
15598 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15599 sb.append("System-App: ").append(isSystemApp).append("\n");
15600 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
15601 if (info.violationNumThisLoop != 0) {
15602 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
15604 if (info.numAnimationsRunning != 0) {
15605 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
15607 if (info.broadcastIntentAction != null) {
15608 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
15610 if (info.durationMillis != -1) {
15611 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
15613 if (info.numInstances != -1) {
15614 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
15616 if (info.tags != null) {
15617 for (String tag : info.tags) {
15618 sb.append("Span-Tag: ").append(tag).append("\n");
15622 sb.append(info.getStackTrace());
15624 if (info.getViolationDetails() != null) {
15625 sb.append(info.getViolationDetails());
15630 final String res = sb.toString();
15631 IoThread.getHandler().post(() -> {
15632 dbox.addText(dropboxTag, res);
15637 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
15638 * @param app object of the crashing app, null for the system server
15639 * @param tag reported by the caller
15640 * @param system whether this wtf is coming from the system
15641 * @param crashInfo describing the context of the error
15642 * @return true if the process should exit immediately (WTF is fatal)
15644 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
15645 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15646 final int callingUid = Binder.getCallingUid();
15647 final int callingPid = Binder.getCallingPid();
15650 // If this is coming from the system, we could very well have low-level
15651 // system locks held, so we want to do this all asynchronously. And we
15652 // never want this to become fatal, so there is that too.
15653 mHandler.post(new Runnable() {
15654 @Override public void run() {
15655 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
15661 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
15664 final boolean isFatal = Build.IS_ENG || Settings.Global
15665 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
15666 final boolean isSystem = (r == null) || r.persistent;
15668 if (isFatal && !isSystem) {
15669 mAppErrors.crashApplication(r, crashInfo);
15676 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
15677 final ApplicationErrorReport.CrashInfo crashInfo) {
15678 final ProcessRecord r = findAppProcess(app, "WTF");
15679 final String processName = app == null ? "system_server"
15680 : (r == null ? "unknown" : r.processName);
15682 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
15683 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
15685 StatsLog.write(StatsLog.WTF_OCCURRED, callingUid, tag, processName,
15688 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
15694 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
15695 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
15697 private ProcessRecord findAppProcess(IBinder app, String reason) {
15702 synchronized (this) {
15703 final int NP = mProcessNames.getMap().size();
15704 for (int ip=0; ip<NP; ip++) {
15705 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
15706 final int NA = apps.size();
15707 for (int ia=0; ia<NA; ia++) {
15708 ProcessRecord p = apps.valueAt(ia);
15709 if (p.thread != null && p.thread.asBinder() == app) {
15715 Slog.w(TAG, "Can't find mystery application for " + reason
15716 + " from pid=" + Binder.getCallingPid()
15717 + " uid=" + Binder.getCallingUid() + ": " + app);
15723 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
15724 * to append various headers to the dropbox log text.
15726 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
15727 StringBuilder sb) {
15728 // Watchdog thread ends up invoking this function (with
15729 // a null ProcessRecord) to add the stack file to dropbox.
15730 // Do not acquire a lock on this (am) in such cases, as it
15731 // could cause a potential deadlock, if and when watchdog
15732 // is invoked due to unavailability of lock on am and it
15733 // would prevent watchdog from killing system_server.
15734 if (process == null) {
15735 sb.append("Process: ").append(processName).append("\n");
15738 // Note: ProcessRecord 'process' is guarded by the service
15739 // instance. (notably process.pkgList, which could otherwise change
15740 // concurrently during execution of this method)
15741 synchronized (this) {
15742 sb.append("Process: ").append(processName).append("\n");
15743 sb.append("PID: ").append(process.pid).append("\n");
15744 int flags = process.info.flags;
15745 IPackageManager pm = AppGlobals.getPackageManager();
15746 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
15747 for (int ip=0; ip<process.pkgList.size(); ip++) {
15748 String pkg = process.pkgList.keyAt(ip);
15749 sb.append("Package: ").append(pkg);
15751 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
15753 sb.append(" v").append(pi.getLongVersionCode());
15754 if (pi.versionName != null) {
15755 sb.append(" (").append(pi.versionName).append(")");
15758 } catch (RemoteException e) {
15759 Slog.e(TAG, "Error getting package info: " + pkg, e);
15763 if (process.info.isInstantApp()) {
15764 sb.append("Instant-App: true\n");
15769 private static String processClass(ProcessRecord process) {
15770 if (process == null || process.pid == MY_PID) {
15771 return "system_server";
15772 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15773 return "system_app";
15779 private volatile long mWtfClusterStart;
15780 private volatile int mWtfClusterCount;
15783 * Write a description of an error (crash, WTF, ANR) to the drop box.
15784 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
15785 * @param process which caused the error, null means the system server
15786 * @param activity which triggered the error, null if unknown
15787 * @param parent activity related to the error, null if unknown
15788 * @param subject line related to the error, null if absent
15789 * @param report in long form describing the error, null if absent
15790 * @param dataFile text file to include in the report, null if none
15791 * @param crashInfo giving an application stack trace, null if absent
15793 public void addErrorToDropBox(String eventType,
15794 ProcessRecord process, String processName, ActivityRecord activity,
15795 ActivityRecord parent, String subject,
15796 final String report, final File dataFile,
15797 final ApplicationErrorReport.CrashInfo crashInfo) {
15798 // NOTE -- this must never acquire the ActivityManagerService lock,
15799 // otherwise the watchdog may be prevented from resetting the system.
15801 // Bail early if not published yet
15802 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
15803 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
15805 // Exit early if the dropbox isn't configured to accept this report type.
15806 final String dropboxTag = processClass(process) + "_" + eventType;
15807 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15809 // Rate-limit how often we're willing to do the heavy lifting below to
15810 // collect and record logs; currently 5 logs per 10 second period.
15811 final long now = SystemClock.elapsedRealtime();
15812 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
15813 mWtfClusterStart = now;
15814 mWtfClusterCount = 1;
15816 if (mWtfClusterCount++ >= 5) return;
15819 final StringBuilder sb = new StringBuilder(1024);
15820 appendDropBoxProcessHeaders(process, processName, sb);
15821 if (process != null) {
15822 sb.append("Foreground: ")
15823 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
15826 if (activity != null) {
15827 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15829 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15830 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15832 if (parent != null && parent != activity) {
15833 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15835 if (subject != null) {
15836 sb.append("Subject: ").append(subject).append("\n");
15838 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15839 if (Debug.isDebuggerConnected()) {
15840 sb.append("Debugger: Connected\n");
15844 // Do the rest in a worker thread to avoid blocking the caller on I/O
15845 // (After this point, we shouldn't access AMS internal data structures.)
15846 Thread worker = new Thread("Error dump: " + dropboxTag) {
15848 public void run() {
15849 if (report != null) {
15853 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
15854 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
15855 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
15856 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
15858 if (dataFile != null && maxDataFileSize > 0) {
15860 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15861 "\n\n[[TRUNCATED]]"));
15862 } catch (IOException e) {
15863 Slog.e(TAG, "Error reading " + dataFile, e);
15866 if (crashInfo != null && crashInfo.stackTrace != null) {
15867 sb.append(crashInfo.stackTrace);
15873 // Merge several logcat streams, and take the last N lines
15874 InputStreamReader input = null;
15876 java.lang.Process logcat = new ProcessBuilder(
15877 "/system/bin/timeout", "-k", "15s", "10s",
15878 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
15879 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
15880 .redirectErrorStream(true).start();
15882 try { logcat.getOutputStream().close(); } catch (IOException e) {}
15883 try { logcat.getErrorStream().close(); } catch (IOException e) {}
15884 input = new InputStreamReader(logcat.getInputStream());
15887 char[] buf = new char[8192];
15888 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
15889 } catch (IOException e) {
15890 Slog.e(TAG, "Error running logcat", e);
15892 if (input != null) try { input.close(); } catch (IOException e) {}
15896 dbox.addText(dropboxTag, sb.toString());
15900 if (process == null) {
15901 // If process is null, we are being called from some internal code
15902 // and may be about to die -- run this synchronously.
15903 final int oldMask = StrictMode.allowThreadDiskWritesMask();
15907 StrictMode.setThreadPolicyMask(oldMask);
15915 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15916 enforceNotIsolatedCaller("getProcessesInErrorState");
15917 // assume our apps are happy - lazy create the list
15918 List<ActivityManager.ProcessErrorStateInfo> errList = null;
15920 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15921 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15922 int userId = UserHandle.getUserId(Binder.getCallingUid());
15924 synchronized (this) {
15926 // iterate across all processes
15927 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15928 ProcessRecord app = mLruProcesses.get(i);
15929 if (!allUsers && app.userId != userId) {
15932 if ((app.thread != null) && (app.crashing || app.notResponding)) {
15933 // This one's in trouble, so we'll generate a report for it
15934 // crashes are higher priority (in case there's a crash *and* an anr)
15935 ActivityManager.ProcessErrorStateInfo report = null;
15936 if (app.crashing) {
15937 report = app.crashingReport;
15938 } else if (app.notResponding) {
15939 report = app.notRespondingReport;
15942 if (report != null) {
15943 if (errList == null) {
15944 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15946 errList.add(report);
15948 Slog.w(TAG, "Missing app error report, app = " + app.processName +
15949 " crashing = " + app.crashing +
15950 " notResponding = " + app.notResponding);
15959 static int procStateToImportance(int procState, int memAdj,
15960 ActivityManager.RunningAppProcessInfo currApp,
15961 int clientTargetSdk) {
15962 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15963 procState, clientTargetSdk);
15964 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15965 currApp.lru = memAdj;
15972 private void fillInProcMemInfo(ProcessRecord app,
15973 ActivityManager.RunningAppProcessInfo outInfo,
15974 int clientTargetSdk) {
15975 outInfo.pid = app.pid;
15976 outInfo.uid = app.info.uid;
15977 if (mHeavyWeightProcess == app) {
15978 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15980 if (app.persistent) {
15981 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15983 if (app.activities.size() > 0) {
15984 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15986 outInfo.lastTrimLevel = app.trimMemoryLevel;
15987 int adj = app.curAdj;
15988 int procState = app.curProcState;
15989 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15990 outInfo.importanceReasonCode = app.adjTypeCode;
15991 outInfo.processState = app.curProcState;
15995 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15996 enforceNotIsolatedCaller("getRunningAppProcesses");
15998 final int callingUid = Binder.getCallingUid();
15999 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
16001 // Lazy instantiation of list
16002 List<ActivityManager.RunningAppProcessInfo> runList = null;
16003 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
16004 callingUid) == PackageManager.PERMISSION_GRANTED;
16005 final int userId = UserHandle.getUserId(callingUid);
16006 final boolean allUids = isGetTasksAllowed(
16007 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
16009 synchronized (this) {
16010 // Iterate across all processes
16011 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16012 ProcessRecord app = mLruProcesses.get(i);
16013 if ((!allUsers && app.userId != userId)
16014 || (!allUids && app.uid != callingUid)) {
16017 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
16018 // Generate process state info for running application
16019 ActivityManager.RunningAppProcessInfo currApp =
16020 new ActivityManager.RunningAppProcessInfo(app.processName,
16021 app.pid, app.getPackageList());
16022 fillInProcMemInfo(app, currApp, clientTargetSdk);
16023 if (app.adjSource instanceof ProcessRecord) {
16024 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
16025 currApp.importanceReasonImportance =
16026 ActivityManager.RunningAppProcessInfo.procStateToImportance(
16027 app.adjSourceProcState);
16028 } else if (app.adjSource instanceof ActivityRecord) {
16029 ActivityRecord r = (ActivityRecord)app.adjSource;
16030 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
16032 if (app.adjTarget instanceof ComponentName) {
16033 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
16035 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
16036 // + " lru=" + currApp.lru);
16037 if (runList == null) {
16038 runList = new ArrayList<>();
16040 runList.add(currApp);
16048 public List<ApplicationInfo> getRunningExternalApplications() {
16049 enforceNotIsolatedCaller("getRunningExternalApplications");
16050 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
16051 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
16052 if (runningApps != null && runningApps.size() > 0) {
16053 Set<String> extList = new HashSet<String>();
16054 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
16055 if (app.pkgList != null) {
16056 for (String pkg : app.pkgList) {
16061 IPackageManager pm = AppGlobals.getPackageManager();
16062 for (String pkg : extList) {
16064 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
16065 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
16068 } catch (RemoteException e) {
16076 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outState) {
16077 if (outState == null) {
16078 throw new IllegalArgumentException("outState is null");
16080 enforceNotIsolatedCaller("getMyMemoryState");
16082 final int callingUid = Binder.getCallingUid();
16083 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
16085 synchronized (this) {
16086 ProcessRecord proc;
16087 synchronized (mPidsSelfLocked) {
16088 proc = mPidsSelfLocked.get(Binder.getCallingPid());
16090 if (proc != null) {
16091 fillInProcMemInfo(proc, outState, clientTargetSdk);
16097 public int getMemoryTrimLevel() {
16098 enforceNotIsolatedCaller("getMyMemoryState");
16099 synchronized (this) {
16100 return mLastMemoryLevel;
16105 public void onShellCommand(FileDescriptor in, FileDescriptor out,
16106 FileDescriptor err, String[] args, ShellCallback callback,
16107 ResultReceiver resultReceiver) {
16108 (new ActivityManagerShellCommand(this, false)).exec(
16109 this, in, out, err, args, callback, resultReceiver);
16112 SleepToken acquireSleepToken(String tag, int displayId) {
16113 synchronized (this) {
16114 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
16115 updateSleepIfNeededLocked();
16121 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
16122 PriorityDump.dump(mPriorityDumper, fd, pw, args);
16126 * Wrapper function to print out debug data filtered by specified arguments.
16128 private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
16129 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
16131 boolean dumpAll = false;
16132 boolean dumpClient = false;
16133 boolean dumpCheckin = false;
16134 boolean dumpCheckinFormat = false;
16135 boolean dumpNormalPriority = false;
16136 boolean dumpVisibleStacksOnly = false;
16137 boolean dumpFocusedStackOnly = false;
16138 String dumpPackage = null;
16141 while (opti < args.length) {
16142 String opt = args[opti];
16143 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16147 if ("-a".equals(opt)) {
16149 } else if ("-c".equals(opt)) {
16151 } else if ("-v".equals(opt)) {
16152 dumpVisibleStacksOnly = true;
16153 } else if ("-f".equals(opt)) {
16154 dumpFocusedStackOnly = true;
16155 } else if ("-p".equals(opt)) {
16156 if (opti < args.length) {
16157 dumpPackage = args[opti];
16160 pw.println("Error: -p option requires package argument");
16164 } else if ("--checkin".equals(opt)) {
16165 dumpCheckin = dumpCheckinFormat = true;
16166 } else if ("-C".equals(opt)) {
16167 dumpCheckinFormat = true;
16168 } else if ("--normal-priority".equals(opt)) {
16169 dumpNormalPriority = true;
16170 } else if ("-h".equals(opt)) {
16171 ActivityManagerShellCommand.dumpHelp(pw, true);
16174 pw.println("Unknown argument: " + opt + "; use -h for help");
16178 long origId = Binder.clearCallingIdentity();
16181 final ProtoOutputStream proto = new ProtoOutputStream(fd);
16182 String cmd = opti < args.length ? args[opti] : "";
16185 if ("activities".equals(cmd) || "a".equals(cmd)) {
16186 // output proto is ActivityManagerServiceDumpActivitiesProto
16187 synchronized (this) {
16188 writeActivitiesToProtoLocked(proto);
16190 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
16191 // output proto is ActivityManagerServiceDumpBroadcastsProto
16192 synchronized (this) {
16193 writeBroadcastsToProtoLocked(proto);
16195 } else if ("provider".equals(cmd)) {
16198 if (opti >= args.length) {
16200 newArgs = EMPTY_STRING_ARRAY;
16204 newArgs = new String[args.length - opti];
16205 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16206 args.length - opti);
16208 if (!dumpProviderProto(fd, pw, name, newArgs)) {
16209 pw.println("No providers match: " + name);
16210 pw.println("Use -h for help.");
16212 } else if ("service".equals(cmd)) {
16213 // output proto is ActivityManagerServiceDumpServicesProto
16214 mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
16215 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
16216 if (opti < args.length) {
16217 dumpPackage = args[opti];
16220 // output proto is ProcessProto
16221 synchronized (this) {
16222 writeProcessesToProtoLocked(proto, dumpPackage);
16225 // default option, dump everything, output is ActivityManagerServiceProto
16226 synchronized (this) {
16227 long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
16228 writeActivitiesToProtoLocked(proto);
16229 proto.end(activityToken);
16231 long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
16232 writeBroadcastsToProtoLocked(proto);
16233 proto.end(broadcastToken);
16235 long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
16236 mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
16237 proto.end(serviceToken);
16239 long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
16240 writeProcessesToProtoLocked(proto, dumpPackage);
16241 proto.end(processToken);
16245 Binder.restoreCallingIdentity(origId);
16249 int dumpAppId = getAppId(dumpPackage);
16250 boolean more = false;
16251 // Is the caller requesting to dump a particular piece of data?
16252 if (opti < args.length) {
16253 String cmd = args[opti];
16255 if ("activities".equals(cmd) || "a".equals(cmd)) {
16256 synchronized (this) {
16257 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16259 } else if ("lastanr".equals(cmd)) {
16260 synchronized (this) {
16261 dumpLastANRLocked(pw);
16263 } else if ("starter".equals(cmd)) {
16264 synchronized (this) {
16265 dumpActivityStarterLocked(pw, dumpPackage);
16267 } else if ("containers".equals(cmd)) {
16268 synchronized (this) {
16269 dumpActivityContainersLocked(pw);
16271 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
16272 synchronized (this) {
16273 if (mRecentTasks != null) {
16274 mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
16277 } else if ("binder-proxies".equals(cmd)) {
16278 if (opti >= args.length) {
16279 dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
16280 "Counts of Binder Proxies held by SYSTEM");
16282 String uid = args[opti];
16284 // Ensure Binder Proxy Count is as up to date as possible
16286 System.runFinalization();
16288 pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
16290 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
16291 if (opti < args.length) {
16292 dumpPackage = args[opti];
16295 synchronized (this) {
16296 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
16298 } else if ("broadcast-stats".equals(cmd)) {
16299 if (opti < args.length) {
16300 dumpPackage = args[opti];
16303 synchronized (this) {
16304 if (dumpCheckinFormat) {
16305 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
16308 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
16311 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
16312 if (opti < args.length) {
16313 dumpPackage = args[opti];
16316 synchronized (this) {
16317 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
16319 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
16320 if (opti < args.length) {
16321 dumpPackage = args[opti];
16324 synchronized (this) {
16325 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
16327 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
16328 synchronized (this) {
16329 dumpOomLocked(fd, pw, args, opti, true);
16331 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
16332 synchronized (this) {
16333 dumpPermissionsLocked(fd, pw, args, opti, true, null);
16335 } else if ("provider".equals(cmd)) {
16338 if (opti >= args.length) {
16340 newArgs = EMPTY_STRING_ARRAY;
16344 newArgs = new String[args.length - opti];
16345 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16347 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
16348 pw.println("No providers match: " + name);
16349 pw.println("Use -h for help.");
16351 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
16352 synchronized (this) {
16353 dumpProvidersLocked(fd, pw, args, opti, true, null);
16355 } else if ("service".equals(cmd)) {
16358 if (opti >= args.length) {
16360 newArgs = EMPTY_STRING_ARRAY;
16364 newArgs = new String[args.length - opti];
16365 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16366 args.length - opti);
16368 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
16369 pw.println("No services match: " + name);
16370 pw.println("Use -h for help.");
16372 } else if ("package".equals(cmd)) {
16374 if (opti >= args.length) {
16375 pw.println("package: no package name specified");
16376 pw.println("Use -h for help.");
16378 dumpPackage = args[opti];
16380 newArgs = new String[args.length - opti];
16381 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16382 args.length - opti);
16387 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
16388 synchronized (this) {
16389 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16391 } else if ("settings".equals(cmd)) {
16392 synchronized (this) {
16393 mConstants.dump(pw);
16395 } else if ("services".equals(cmd) || "s".equals(cmd)) {
16397 ActiveServices.ServiceDumper dumper;
16398 synchronized (this) {
16399 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16402 dumper.dumpWithClient();
16404 synchronized (this) {
16405 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16406 dumpPackage).dumpLocked();
16409 } else if ("locks".equals(cmd)) {
16410 LockGuard.dump(fd, pw, args);
16412 // Dumping a single activity?
16413 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
16414 dumpFocusedStackOnly)) {
16415 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
16416 int res = shell.exec(this, null, fd, null, args, null,
16417 new ResultReceiver(null));
16419 pw.println("Bad activity command, or no activities match: " + cmd);
16420 pw.println("Use -h for help.");
16425 Binder.restoreCallingIdentity(origId);
16430 // No piece of data specified, dump everything.
16431 if (dumpCheckinFormat) {
16432 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
16433 } else if (dumpClient) {
16434 ActiveServices.ServiceDumper sdumper;
16435 synchronized (this) {
16436 mConstants.dump(pw);
16439 pw.println("-------------------------------------------------------------------------------");
16441 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16444 pw.println("-------------------------------------------------------------------------------");
16446 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16449 pw.println("-------------------------------------------------------------------------------");
16451 if (dumpAll || dumpPackage != null) {
16452 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16455 pw.println("-------------------------------------------------------------------------------");
16458 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16461 pw.println("-------------------------------------------------------------------------------");
16463 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16466 pw.println("-------------------------------------------------------------------------------");
16468 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
16471 sdumper.dumpWithClient();
16473 synchronized (this) {
16475 pw.println("-------------------------------------------------------------------------------");
16477 if (mRecentTasks != null) {
16478 mRecentTasks.dump(pw, dumpAll, dumpPackage);
16482 pw.println("-------------------------------------------------------------------------------");
16484 dumpLastANRLocked(pw);
16487 pw.println("-------------------------------------------------------------------------------");
16489 dumpActivityStarterLocked(pw, dumpPackage);
16492 pw.println("-------------------------------------------------------------------------------");
16494 dumpActivityContainersLocked(pw);
16497 pw.println("-------------------------------------------------------------------------------");
16499 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16500 if (mAssociations.size() > 0) {
16503 pw.println("-------------------------------------------------------------------------------");
16505 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16509 pw.println("-------------------------------------------------------------------------------");
16511 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16515 synchronized (this) {
16516 mConstants.dump(pw);
16519 pw.println("-------------------------------------------------------------------------------");
16521 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16524 pw.println("-------------------------------------------------------------------------------");
16526 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16529 pw.println("-------------------------------------------------------------------------------");
16531 if (dumpAll || dumpPackage != null) {
16532 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16535 pw.println("-------------------------------------------------------------------------------");
16538 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16541 pw.println("-------------------------------------------------------------------------------");
16543 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16546 pw.println("-------------------------------------------------------------------------------");
16548 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
16552 pw.println("-------------------------------------------------------------------------------");
16554 if (mRecentTasks != null) {
16555 mRecentTasks.dump(pw, dumpAll, dumpPackage);
16559 pw.println("-------------------------------------------------------------------------------");
16561 dumpLastANRLocked(pw);
16564 pw.println("-------------------------------------------------------------------------------");
16566 dumpActivityStarterLocked(pw, dumpPackage);
16569 pw.println("-------------------------------------------------------------------------------");
16571 dumpActivityContainersLocked(pw);
16572 // Activities section is dumped as part of the Critical priority dump. Exclude the
16573 // section if priority is Normal.
16574 if (!dumpNormalPriority){
16577 pw.println("-------------------------------------------------------------------------------");
16579 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16581 if (mAssociations.size() > 0) {
16584 pw.println("-------------------------------------------------------------------------------");
16586 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16590 pw.println("-------------------------------------------------------------------------------");
16592 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16595 Binder.restoreCallingIdentity(origId);
16598 private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
16599 // The output proto of "activity --proto activities" is ActivityManagerServiceDumpActivitiesProto
16600 mStackSupervisor.writeToProto(proto, ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
16603 private void dumpLastANRLocked(PrintWriter pw) {
16604 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
16605 if (mLastANRState == null) {
16606 pw.println(" <no ANR has occurred since boot>");
16608 pw.println(mLastANRState);
16612 private void dumpActivityContainersLocked(PrintWriter pw) {
16613 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
16614 mStackSupervisor.dumpChildrenNames(pw, " ");
16618 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
16619 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
16620 mActivityStartController.dump(pw, "", dumpPackage);
16623 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16624 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16625 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
16626 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
16629 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16630 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
16631 pw.println(header);
16633 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
16635 boolean needSep = printedAnything;
16637 boolean printed = ActivityStackSupervisor.printThisActivity(pw,
16638 mStackSupervisor.getResumedActivityLocked(),
16639 dumpPackage, needSep, " ResumedActivity: ");
16641 printedAnything = true;
16645 if (dumpPackage == null) {
16649 printedAnything = true;
16650 mStackSupervisor.dump(pw, " ");
16653 if (!printedAnything) {
16654 pw.println(" (nothing)");
16658 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16659 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16660 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
16663 if (dumpPackage != null) {
16664 IPackageManager pm = AppGlobals.getPackageManager();
16666 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
16667 } catch (RemoteException e) {
16671 boolean printedAnything = false;
16673 final long now = SystemClock.uptimeMillis();
16675 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
16676 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
16677 = mAssociations.valueAt(i1);
16678 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
16679 SparseArray<ArrayMap<String, Association>> sourceUids
16680 = targetComponents.valueAt(i2);
16681 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
16682 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
16683 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
16684 Association ass = sourceProcesses.valueAt(i4);
16685 if (dumpPackage != null) {
16686 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
16687 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
16691 printedAnything = true;
16693 pw.print(ass.mTargetProcess);
16695 UserHandle.formatUid(pw, ass.mTargetUid);
16697 pw.print(ass.mSourceProcess);
16699 UserHandle.formatUid(pw, ass.mSourceUid);
16702 pw.print(ass.mTargetComponent.flattenToShortString());
16705 long dur = ass.mTime;
16706 if (ass.mNesting > 0) {
16707 dur += now - ass.mStartTime;
16709 TimeUtils.formatDuration(dur, pw);
16711 pw.print(ass.mCount);
16712 pw.print(" times)");
16714 for (int i=0; i<ass.mStateTimes.length; i++) {
16715 long amt = ass.mStateTimes[i];
16716 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16717 amt += now - ass.mLastStateUptime;
16721 pw.print(ProcessList.makeProcStateString(
16722 i + ActivityManager.MIN_PROCESS_STATE));
16724 TimeUtils.formatDuration(amt, pw);
16725 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16731 if (ass.mNesting > 0) {
16732 pw.print(" Currently active: ");
16733 TimeUtils.formatDuration(now - ass.mStartTime, pw);
16742 if (!printedAnything) {
16743 pw.println(" (nothing)");
16747 private int getAppId(String dumpPackage) {
16748 if (dumpPackage != null) {
16750 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
16752 return UserHandle.getAppId(info.uid);
16753 } catch (NameNotFoundException e) {
16754 e.printStackTrace();
16760 boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
16761 String header, boolean needSep) {
16762 boolean printed = false;
16763 for (int i=0; i<uids.size(); i++) {
16764 UidRecord uidRec = uids.valueAt(i);
16765 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
16774 pw.println(header);
16777 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
16778 pw.print(": "); pw.println(uidRec);
16783 boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
16784 if(counts != null) {
16785 pw.println(header);
16786 for (int i = 0; i < counts.size(); i++) {
16787 final int uid = counts.keyAt(i);
16788 final int binderCount = counts.valueAt(i);
16791 pw.print(", binder count = ");
16792 pw.print(binderCount);
16793 pw.print(", package(s)= ");
16794 final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
16795 if (pkgNames != null) {
16796 for (int j = 0; j < pkgNames.length; j++) {
16797 pw.print(pkgNames[j]);
16801 pw.print("NO PACKAGE NAME FOUND");
16812 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16813 int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
16814 boolean needSep = false;
16817 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
16820 final int NP = mProcessNames.getMap().size();
16821 for (int ip=0; ip<NP; ip++) {
16822 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16823 final int NA = procs.size();
16824 for (int ia=0; ia<NA; ia++) {
16825 ProcessRecord r = procs.valueAt(ia);
16826 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16830 pw.println(" All known processes:");
16833 pw.print(r.persistent ? " *PERS*" : " *APP*");
16834 pw.print(" UID "); pw.print(procs.keyAt(ia));
16835 pw.print(" "); pw.println(r);
16837 if (r.persistent) {
16844 if (mIsolatedProcesses.size() > 0) {
16845 boolean printed = false;
16846 for (int i=0; i<mIsolatedProcesses.size(); i++) {
16847 ProcessRecord r = mIsolatedProcesses.valueAt(i);
16848 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16855 pw.println(" Isolated process list (sorted by uid):");
16859 pw.print(" Isolated #"); pw.print(i); pw.print(": ");
16864 if (mActiveInstrumentation.size() > 0) {
16865 boolean printed = false;
16866 for (int i=0; i<mActiveInstrumentation.size(); i++) {
16867 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16868 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16869 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16876 pw.println(" Active instrumentation:");
16880 pw.print(" Instrumentation #"); pw.print(i); pw.print(": ");
16886 if (mActiveUids.size() > 0) {
16887 if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16892 if (mValidateUids.size() > 0) {
16893 if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16900 if (mLruProcesses.size() > 0) {
16904 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16905 pw.print(" total, non-act at ");
16906 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16907 pw.print(", non-svc at ");
16908 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16910 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
16914 if (dumpAll || dumpPackage != null) {
16915 synchronized (mPidsSelfLocked) {
16916 boolean printed = false;
16917 for (int i=0; i<mPidsSelfLocked.size(); i++) {
16918 ProcessRecord r = mPidsSelfLocked.valueAt(i);
16919 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16923 if (needSep) pw.println();
16925 pw.println(" PID mappings:");
16928 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16929 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16934 if (mImportantProcesses.size() > 0) {
16935 synchronized (mPidsSelfLocked) {
16936 boolean printed = false;
16937 for (int i = 0; i< mImportantProcesses.size(); i++) {
16938 ProcessRecord r = mPidsSelfLocked.get(
16939 mImportantProcesses.valueAt(i).pid);
16940 if (dumpPackage != null && (r == null
16941 || !r.pkgList.containsKey(dumpPackage))) {
16945 if (needSep) pw.println();
16947 pw.println(" Foreground Processes:");
16950 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i));
16951 pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16956 if (mPersistentStartingProcesses.size() > 0) {
16957 if (needSep) pw.println();
16959 pw.println(" Persisent processes that are starting:");
16960 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
16961 "Starting Norm", "Restarting PERS", dumpPackage);
16964 if (mRemovedProcesses.size() > 0) {
16965 if (needSep) pw.println();
16967 pw.println(" Processes that are being removed:");
16968 dumpProcessList(pw, this, mRemovedProcesses, " ",
16969 "Removed Norm", "Removed PERS", dumpPackage);
16972 if (mProcessesOnHold.size() > 0) {
16973 if (needSep) pw.println();
16975 pw.println(" Processes that are on old until the system is ready:");
16976 dumpProcessList(pw, this, mProcessesOnHold, " ",
16977 "OnHold Norm", "OnHold PERS", dumpPackage);
16980 needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16982 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16984 if (dumpPackage == null) {
16987 mUserController.dump(pw, dumpAll);
16989 if (mHomeProcess != null && (dumpPackage == null
16990 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16995 pw.println(" mHomeProcess: " + mHomeProcess);
16997 if (mPreviousProcess != null && (dumpPackage == null
16998 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
17003 pw.println(" mPreviousProcess: " + mPreviousProcess);
17005 if (dumpAll && (mPreviousProcess == null || dumpPackage == null
17006 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
17007 StringBuilder sb = new StringBuilder(128);
17008 sb.append(" mPreviousProcessVisibleTime: ");
17009 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
17012 if (mHeavyWeightProcess != null && (dumpPackage == null
17013 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
17018 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
17020 if (dumpAll && mPendingStarts.size() > 0) {
17021 if (needSep) pw.println();
17023 pw.println(" mPendingStarts: ");
17024 for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
17025 pw.println(" " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
17028 if (dumpPackage == null) {
17029 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration());
17030 mStackSupervisor.dumpDisplayConfigs(pw, " ");
17033 if (dumpPackage == null) {
17034 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
17036 if (mCompatModePackages.getPackages().size() > 0) {
17037 boolean printed = false;
17038 for (Map.Entry<String, Integer> entry
17039 : mCompatModePackages.getPackages().entrySet()) {
17040 String pkg = entry.getKey();
17041 int mode = entry.getValue();
17042 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
17046 pw.println(" mScreenCompatPackages:");
17049 pw.print(" "); pw.print(pkg); pw.print(": ");
17050 pw.print(mode); pw.println();
17053 final int NI = mUidObservers.getRegisteredCallbackCount();
17054 boolean printed = false;
17055 for (int i=0; i<NI; i++) {
17056 final UidObserverRegistration reg = (UidObserverRegistration)
17057 mUidObservers.getRegisteredCallbackCookie(i);
17058 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
17060 pw.println(" mUidObservers:");
17063 pw.print(" "); UserHandle.formatUid(pw, reg.uid);
17064 pw.print(" "); pw.print(reg.pkg); pw.print(":");
17065 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
17068 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
17071 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
17074 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
17075 pw.print(" STATE");
17076 pw.print(" (cut="); pw.print(reg.cutpoint);
17080 if (reg.lastProcStates != null) {
17081 final int NJ = reg.lastProcStates.size();
17082 for (int j=0; j<NJ; j++) {
17083 pw.print(" Last ");
17084 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
17085 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
17090 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
17091 pw.println(" mDeviceIdleExceptIdleWhitelist="
17092 + Arrays.toString(mDeviceIdleExceptIdleWhitelist));
17093 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
17094 if (mPendingTempWhitelist.size() > 0) {
17095 pw.println(" mPendingTempWhitelist:");
17096 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
17097 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
17099 UserHandle.formatUid(pw, ptw.targetUid);
17101 TimeUtils.formatDuration(ptw.duration, pw);
17103 pw.println(ptw.tag);
17107 if (dumpPackage == null) {
17108 pw.println(" mWakefulness="
17109 + PowerManagerInternal.wakefulnessToString(mWakefulness));
17110 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
17111 pw.println(" mSleeping=" + mSleeping);
17112 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
17113 if (mRunningVoice != null) {
17114 pw.println(" mRunningVoice=" + mRunningVoice);
17115 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
17117 pw.println(" mVrController=" + mVrController);
17119 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17120 || mOrigWaitForDebugger) {
17121 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17122 || dumpPackage.equals(mOrigDebugApp)) {
17127 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
17128 + " mDebugTransient=" + mDebugTransient
17129 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
17132 if (mCurAppTimeTracker != null) {
17133 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
17135 if (mMemWatchProcesses.getMap().size() > 0) {
17136 pw.println(" Mem watch processes:");
17137 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
17138 = mMemWatchProcesses.getMap();
17139 for (int i=0; i<procs.size(); i++) {
17140 final String proc = procs.keyAt(i);
17141 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
17142 for (int j=0; j<uids.size(); j++) {
17147 StringBuilder sb = new StringBuilder();
17148 sb.append(" ").append(proc).append('/');
17149 UserHandle.formatUid(sb, uids.keyAt(j));
17150 Pair<Long, String> val = uids.valueAt(j);
17151 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
17152 if (val.second != null) {
17153 sb.append(", report to ").append(val.second);
17155 pw.println(sb.toString());
17158 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
17159 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
17160 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
17161 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
17163 if (mTrackAllocationApp != null) {
17164 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17169 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
17172 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17173 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17174 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
17179 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
17180 if (mProfilerInfo != null) {
17181 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
17182 mProfilerInfo.profileFd);
17183 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval +
17184 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
17185 " mStreamingOutput=" + mProfilerInfo.streamingOutput);
17186 pw.println(" mProfileType=" + mProfileType);
17190 if (mNativeDebuggingApp != null) {
17191 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17196 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
17199 if (mAllowAppSwitchUids.size() > 0) {
17200 boolean printed = false;
17201 for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
17202 ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
17203 for (int j = 0; j < types.size(); j++) {
17204 if (dumpPackage == null ||
17205 UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
17211 pw.println(" mAllowAppSwitchUids:");
17214 pw.print(" User ");
17215 pw.print(mAllowAppSwitchUids.keyAt(i));
17216 pw.print(": Type ");
17217 pw.print(types.keyAt(j));
17219 UserHandle.formatUid(pw, types.valueAt(j).intValue());
17225 if (dumpPackage == null) {
17226 if (mAlwaysFinishActivities) {
17227 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
17229 if (mController != null) {
17230 pw.println(" mController=" + mController
17231 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
17234 pw.println(" Total persistent processes: " + numPers);
17235 pw.println(" mProcessesReady=" + mProcessesReady
17236 + " mSystemReady=" + mSystemReady
17237 + " mBooted=" + mBooted
17238 + " mFactoryTest=" + mFactoryTest);
17239 pw.println(" mBooting=" + mBooting
17240 + " mCallFinishBooting=" + mCallFinishBooting
17241 + " mBootAnimationComplete=" + mBootAnimationComplete);
17242 pw.print(" mLastPowerCheckUptime=");
17243 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
17245 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
17246 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
17247 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
17248 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
17249 + " (" + mLruProcesses.size() + " total)"
17250 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
17251 + " mNumServiceProcs=" + mNumServiceProcs
17252 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
17253 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
17254 + " mLastMemoryLevel=" + mLastMemoryLevel
17255 + " mLastNumProcesses=" + mLastNumProcesses);
17256 long now = SystemClock.uptimeMillis();
17257 pw.print(" mLastIdleTime=");
17258 TimeUtils.formatDuration(now, mLastIdleTime, pw);
17259 pw.print(" mLowRamSinceLastIdle=");
17260 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
17263 pw.print(" mUidChangeDispatchCount=");
17264 pw.print(mUidChangeDispatchCount);
17267 pw.println(" Slow UID dispatches:");
17268 final int N = mUidObservers.beginBroadcast();
17269 for (int i = 0; i < N; i++) {
17270 UidObserverRegistration r =
17271 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
17273 pw.print(mUidObservers.getBroadcastItem(i).getClass().getTypeName());
17275 pw.print(r.mSlowDispatchCount);
17276 pw.print(" / Max ");
17277 pw.print(r.mMaxDispatchTime);
17280 mUidObservers.finishBroadcast();
17283 pw.println(" ServiceManager statistics:");
17284 ServiceManager.sStatLogger.dump(pw, " ");
17288 pw.println(" mForceBackgroundCheck=" + mForceBackgroundCheck);
17292 void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
17295 final int NP = mProcessNames.getMap().size();
17296 for (int ip=0; ip<NP; ip++) {
17297 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
17298 final int NA = procs.size();
17299 for (int ia = 0; ia<NA; ia++) {
17300 ProcessRecord r = procs.valueAt(ia);
17301 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17304 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS);
17305 if (r.persistent) {
17311 for (int i=0; i<mIsolatedProcesses.size(); i++) {
17312 ProcessRecord r = mIsolatedProcesses.valueAt(i);
17313 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17316 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS);
17319 for (int i=0; i<mActiveInstrumentation.size(); i++) {
17320 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
17321 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
17322 && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
17325 ai.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_INSTRUMENTATIONS);
17328 int whichAppId = getAppId(dumpPackage);
17329 for (int i=0; i<mActiveUids.size(); i++) {
17330 UidRecord uidRec = mActiveUids.valueAt(i);
17331 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
17334 uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
17337 for (int i=0; i<mValidateUids.size(); i++) {
17338 UidRecord uidRec = mValidateUids.valueAt(i);
17339 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
17342 uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
17345 if (mLruProcesses.size() > 0) {
17346 long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
17347 int total = mLruProcesses.size();
17348 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
17349 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
17350 proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
17351 writeProcessOomListToProto(proto, ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, this,
17352 mLruProcesses,false, dumpPackage);
17353 proto.end(lruToken);
17356 if (dumpPackage != null) {
17357 synchronized (mPidsSelfLocked) {
17358 for (int i=0; i<mPidsSelfLocked.size(); i++) {
17359 ProcessRecord r = mPidsSelfLocked.valueAt(i);
17360 if (!r.pkgList.containsKey(dumpPackage)) {
17363 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
17368 if (mImportantProcesses.size() > 0) {
17369 synchronized (mPidsSelfLocked) {
17370 for (int i=0; i<mImportantProcesses.size(); i++) {
17371 ImportanceToken it = mImportantProcesses.valueAt(i);
17372 ProcessRecord r = mPidsSelfLocked.get(it.pid);
17373 if (dumpPackage != null && (r == null
17374 || !r.pkgList.containsKey(dumpPackage))) {
17377 it.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
17382 for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
17383 ProcessRecord r = mPersistentStartingProcesses.get(i);
17384 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17387 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
17390 for (int i=0; i<mRemovedProcesses.size(); i++) {
17391 ProcessRecord r = mRemovedProcesses.get(i);
17392 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17395 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
17398 for (int i=0; i<mProcessesOnHold.size(); i++) {
17399 ProcessRecord r = mProcessesOnHold.get(i);
17400 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17403 r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
17406 writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS, dumpPackage);
17407 mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS, dumpPackage);
17409 if (dumpPackage == null) {
17410 mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
17411 getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION);
17412 proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
17415 if (mHomeProcess != null && (dumpPackage == null
17416 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
17417 mHomeProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC);
17420 if (mPreviousProcess != null && (dumpPackage == null
17421 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
17422 mPreviousProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC);
17423 proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
17426 if (mHeavyWeightProcess != null && (dumpPackage == null
17427 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
17428 mHeavyWeightProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
17431 for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
17432 String pkg = entry.getKey();
17433 int mode = entry.getValue();
17434 if (dumpPackage == null || dumpPackage.equals(pkg)) {
17435 long compatToken = proto.start(ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES);
17436 proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
17437 proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE, mode);
17438 proto.end(compatToken);
17442 final int NI = mUidObservers.getRegisteredCallbackCount();
17443 for (int i=0; i<NI; i++) {
17444 final UidObserverRegistration reg = (UidObserverRegistration)
17445 mUidObservers.getRegisteredCallbackCookie(i);
17446 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
17447 reg.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
17451 for (int v : mDeviceIdleWhitelist) {
17452 proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_WHITELIST, v);
17455 for (int v : mDeviceIdleTempWhitelist) {
17456 proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
17459 if (mPendingTempWhitelist.size() > 0) {
17460 for (int i=0; i < mPendingTempWhitelist.size(); i++) {
17461 mPendingTempWhitelist.valueAt(i).writeToProto(proto,
17462 ActivityManagerServiceDumpProcessesProto.PENDING_TEMP_WHITELIST);
17466 if (dumpPackage == null) {
17467 final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
17468 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
17469 PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
17470 for (SleepToken st : mStackSupervisor.mSleepTokens) {
17471 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
17473 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
17474 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
17475 proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
17476 proto.end(sleepToken);
17478 if (mRunningVoice != null) {
17479 final long vrToken = proto.start(ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
17480 proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION, mRunningVoice.toString());
17481 mVoiceWakeLock.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
17482 proto.end(vrToken);
17485 mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
17488 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17489 || mOrigWaitForDebugger) {
17490 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17491 || dumpPackage.equals(mOrigDebugApp)) {
17492 final long debugAppToken = proto.start(ActivityManagerServiceDumpProcessesProto.DEBUG);
17493 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
17494 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
17495 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
17496 proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
17497 proto.end(debugAppToken);
17501 if (mCurAppTimeTracker != null) {
17502 mCurAppTimeTracker.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
17505 if (mMemWatchProcesses.getMap().size() > 0) {
17506 final long token = proto.start(ActivityManagerServiceDumpProcessesProto.MEM_WATCH_PROCESSES);
17507 ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
17508 for (int i=0; i<procs.size(); i++) {
17509 final String proc = procs.keyAt(i);
17510 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
17511 final long ptoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.PROCS);
17512 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.NAME, proc);
17513 for (int j=0; j<uids.size(); j++) {
17514 final long utoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MEM_STATS);
17515 Pair<Long, String> val = uids.valueAt(j);
17516 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
17517 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
17518 DebugUtils.sizeValueToString(val.first, new StringBuilder()));
17519 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
17525 final long dtoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.DUMP);
17526 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
17527 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
17528 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
17529 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
17535 if (mTrackAllocationApp != null) {
17536 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17537 proto.write(ActivityManagerServiceDumpProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
17541 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17542 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17543 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
17544 final long token = proto.start(ActivityManagerServiceDumpProcessesProto.PROFILE);
17545 proto.write(ActivityManagerServiceDumpProcessesProto.Profile.APP_NAME, mProfileApp);
17546 mProfileProc.writeToProto(proto,ActivityManagerServiceDumpProcessesProto.Profile.PROC);
17547 if (mProfilerInfo != null) {
17548 mProfilerInfo.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Profile.INFO);
17549 proto.write(ActivityManagerServiceDumpProcessesProto.Profile.TYPE, mProfileType);
17555 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17556 proto.write(ActivityManagerServiceDumpProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
17559 if (dumpPackage == null) {
17560 proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
17561 if (mController != null) {
17562 final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER);
17563 proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mController.toString());
17564 proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
17567 proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
17568 proto.write(ActivityManagerServiceDumpProcessesProto.PROCESSES_READY, mProcessesReady);
17569 proto.write(ActivityManagerServiceDumpProcessesProto.SYSTEM_READY, mSystemReady);
17570 proto.write(ActivityManagerServiceDumpProcessesProto.BOOTED, mBooted);
17571 proto.write(ActivityManagerServiceDumpProcessesProto.FACTORY_TEST, mFactoryTest);
17572 proto.write(ActivityManagerServiceDumpProcessesProto.BOOTING, mBooting);
17573 proto.write(ActivityManagerServiceDumpProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
17574 proto.write(ActivityManagerServiceDumpProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
17575 proto.write(ActivityManagerServiceDumpProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
17576 mStackSupervisor.mGoingToSleep.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP);
17577 mStackSupervisor.mLaunchingActivity.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY);
17578 proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq);
17579 proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mLruSeq);
17580 proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
17581 proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
17582 proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
17583 proto.write(ActivityManagerServiceDumpProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
17584 proto.write(ActivityManagerServiceDumpProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
17585 proto.write(ActivityManagerServiceDumpProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
17586 long now = SystemClock.uptimeMillis();
17587 ProtoUtils.toDuration(proto, ActivityManagerServiceDumpProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
17588 proto.write(ActivityManagerServiceDumpProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
17593 void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
17594 if (mProcessesToGc.size() > 0) {
17595 long now = SystemClock.uptimeMillis();
17596 for (int i=0; i<mProcessesToGc.size(); i++) {
17597 ProcessRecord r = mProcessesToGc.get(i);
17598 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17601 final long token = proto.start(fieldId);
17602 r.writeToProto(proto, ProcessToGcProto.PROC);
17603 proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
17604 proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
17605 proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
17606 proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
17612 boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
17613 if (mProcessesToGc.size() > 0) {
17614 boolean printed = false;
17615 long now = SystemClock.uptimeMillis();
17616 for (int i=0; i<mProcessesToGc.size(); i++) {
17617 ProcessRecord proc = mProcessesToGc.get(i);
17618 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
17622 if (needSep) pw.println();
17624 pw.println(" Processes that are waiting to GC:");
17627 pw.print(" Process "); pw.println(proc);
17628 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
17629 pw.print(", last gced=");
17630 pw.print(now-proc.lastRequestedGc);
17631 pw.print(" ms ago, last lowMem=");
17632 pw.print(now-proc.lastLowMemory);
17633 pw.println(" ms ago");
17640 void printOomLevel(PrintWriter pw, String name, int adj) {
17644 if (adj < 10) pw.print(' ');
17646 if (adj > -10) pw.print(' ');
17652 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
17656 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17657 int opti, boolean dumpAll) {
17658 boolean needSep = false;
17660 if (mLruProcesses.size() > 0) {
17661 if (needSep) pw.println();
17663 pw.println(" OOM levels:");
17664 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
17665 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
17666 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
17667 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
17668 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
17669 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
17670 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
17671 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
17672 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
17673 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
17674 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
17675 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
17676 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
17677 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
17679 if (needSep) pw.println();
17680 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
17681 pw.print(" total, non-act at ");
17682 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
17683 pw.print(", non-svc at ");
17684 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
17686 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
17690 dumpProcessesToGc(pw, needSep, null);
17693 pw.println(" mHomeProcess: " + mHomeProcess);
17694 pw.println(" mPreviousProcess: " + mPreviousProcess);
17695 if (mHeavyWeightProcess != null) {
17696 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
17703 * There are three ways to call this:
17704 * - no provider specified: dump all the providers
17705 * - a flattened component name that matched an existing provider was specified as the
17706 * first arg: dump that one provider
17707 * - the first arg isn't the flattened component name of an existing provider:
17708 * dump all providers whose component contains the first arg as a substring
17710 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17711 int opti, boolean dumpAll) {
17712 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
17716 * Similar to the dumpProvider, but only dumps the first matching provider.
17717 * The provider is responsible for dumping as proto.
17719 protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
17721 return mProviderMap.dumpProviderProto(fd, pw, name, args);
17724 static class ItemMatcher {
17725 ArrayList<ComponentName> components;
17726 ArrayList<String> strings;
17727 ArrayList<Integer> objects;
17734 void build(String name) {
17735 ComponentName componentName = ComponentName.unflattenFromString(name);
17736 if (componentName != null) {
17737 if (components == null) {
17738 components = new ArrayList<ComponentName>();
17740 components.add(componentName);
17744 // Not a '/' separated full component name; maybe an object ID?
17746 objectId = Integer.parseInt(name, 16);
17747 if (objects == null) {
17748 objects = new ArrayList<Integer>();
17750 objects.add(objectId);
17752 } catch (RuntimeException e) {
17753 // Not an integer; just do string match.
17754 if (strings == null) {
17755 strings = new ArrayList<String>();
17763 int build(String[] args, int opti) {
17764 for (; opti<args.length; opti++) {
17765 String name = args[opti];
17766 if ("--".equals(name)) {
17774 boolean match(Object object, ComponentName comp) {
17778 if (components != null) {
17779 for (int i=0; i<components.size(); i++) {
17780 if (components.get(i).equals(comp)) {
17785 if (objects != null) {
17786 for (int i=0; i<objects.size(); i++) {
17787 if (System.identityHashCode(object) == objects.get(i)) {
17792 if (strings != null) {
17793 String flat = comp.flattenToString();
17794 for (int i=0; i<strings.size(); i++) {
17795 if (flat.contains(strings.get(i))) {
17805 * There are three things that cmd can be:
17806 * - a flattened component name that matches an existing activity
17807 * - the cmd arg isn't the flattened component name of an existing activity:
17808 * dump all activity whose component contains the cmd as a substring
17809 * - A hex number of the ActivityRecord object instance.
17811 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
17812 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
17814 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17815 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
17816 ArrayList<ActivityRecord> activities;
17818 synchronized (this) {
17819 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
17820 dumpFocusedStackOnly);
17823 if (activities.size() <= 0) {
17827 String[] newArgs = new String[args.length - opti];
17828 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
17830 TaskRecord lastTask = null;
17831 boolean needSep = false;
17832 for (int i=activities.size()-1; i>=0; i--) {
17833 ActivityRecord r = activities.get(i);
17838 synchronized (this) {
17839 final TaskRecord task = r.getTask();
17840 if (lastTask != task) {
17842 pw.print("TASK "); pw.print(lastTask.affinity);
17843 pw.print(" id="); pw.print(lastTask.taskId);
17844 pw.print(" userId="); pw.println(lastTask.userId);
17846 lastTask.dump(pw, " ");
17850 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
17856 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
17857 * there is a thread associated with the activity.
17859 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
17860 final ActivityRecord r, String[] args, boolean dumpAll) {
17861 String innerPrefix = prefix + " ";
17862 synchronized (this) {
17863 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
17864 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
17866 if (r.app != null) pw.println(r.app.pid);
17867 else pw.println("(not running)");
17869 r.dump(pw, innerPrefix);
17872 if (r.app != null && r.app.thread != null) {
17873 // flush anything that is already in the PrintWriter since the thread is going
17874 // to write to the file descriptor directly
17877 TransferPipe tp = new TransferPipe();
17879 r.app.thread.dumpActivity(tp.getWriteFd(),
17880 r.appToken, innerPrefix, args);
17885 } catch (IOException e) {
17886 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
17887 } catch (RemoteException e) {
17888 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
17893 void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
17894 if (mRegisteredReceivers.size() > 0) {
17895 Iterator it = mRegisteredReceivers.values().iterator();
17896 while (it.hasNext()) {
17897 ReceiverList r = (ReceiverList)it.next();
17898 r.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_LIST);
17901 mReceiverResolver.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
17902 for (BroadcastQueue q : mBroadcastQueues) {
17903 q.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
17905 for (int user=0; user<mStickyBroadcasts.size(); user++) {
17906 long token = proto.start(ActivityManagerServiceDumpBroadcastsProto.STICKY_BROADCASTS);
17907 proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
17908 for (Map.Entry<String, ArrayList<Intent>> ent
17909 : mStickyBroadcasts.valueAt(user).entrySet()) {
17910 long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
17911 proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
17912 for (Intent intent : ent.getValue()) {
17913 intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
17914 false, true, true, false);
17916 proto.end(actionToken);
17921 long handlerToken = proto.start(ActivityManagerServiceDumpBroadcastsProto.HANDLER);
17922 proto.write(ActivityManagerServiceDumpBroadcastsProto.MainHandler.HANDLER, mHandler.toString());
17923 mHandler.getLooper().writeToProto(proto,
17924 ActivityManagerServiceDumpBroadcastsProto.MainHandler.LOOPER);
17925 proto.end(handlerToken);
17928 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17929 int opti, boolean dumpAll, String dumpPackage) {
17930 boolean needSep = false;
17931 boolean onlyHistory = false;
17932 boolean printedAnything = false;
17934 if ("history".equals(dumpPackage)) {
17935 if (opti < args.length && "-s".equals(args[opti])) {
17938 onlyHistory = true;
17939 dumpPackage = null;
17942 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
17943 if (!onlyHistory && dumpAll) {
17944 if (mRegisteredReceivers.size() > 0) {
17945 boolean printed = false;
17946 Iterator it = mRegisteredReceivers.values().iterator();
17947 while (it.hasNext()) {
17948 ReceiverList r = (ReceiverList)it.next();
17949 if (dumpPackage != null && (r.app == null ||
17950 !dumpPackage.equals(r.app.info.packageName))) {
17954 pw.println(" Registered Receivers:");
17957 printedAnything = true;
17959 pw.print(" * "); pw.println(r);
17964 if (mReceiverResolver.dump(pw, needSep ?
17965 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
17966 " ", dumpPackage, false, false)) {
17968 printedAnything = true;
17972 for (BroadcastQueue q : mBroadcastQueues) {
17973 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17974 printedAnything |= needSep;
17979 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17980 for (int user=0; user<mStickyBroadcasts.size(); user++) {
17985 printedAnything = true;
17986 pw.print(" Sticky broadcasts for user ");
17987 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
17988 StringBuilder sb = new StringBuilder(128);
17989 for (Map.Entry<String, ArrayList<Intent>> ent
17990 : mStickyBroadcasts.valueAt(user).entrySet()) {
17991 pw.print(" * Sticky action "); pw.print(ent.getKey());
17994 ArrayList<Intent> intents = ent.getValue();
17995 final int N = intents.size();
17996 for (int i=0; i<N; i++) {
17998 sb.append(" Intent: ");
17999 intents.get(i).toShortString(sb, false, true, false, false);
18000 pw.println(sb.toString());
18001 Bundle bundle = intents.get(i).getExtras();
18002 if (bundle != null) {
18004 pw.println(bundle.toString());
18014 if (!onlyHistory && dumpAll) {
18016 for (BroadcastQueue queue : mBroadcastQueues) {
18017 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
18018 + queue.mBroadcastsScheduled);
18020 pw.println(" mHandler:");
18021 mHandler.dump(new PrintWriterPrinter(pw), " ");
18023 printedAnything = true;
18026 if (!printedAnything) {
18027 pw.println(" (nothing)");
18031 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18032 int opti, boolean dumpAll, String dumpPackage) {
18033 if (mCurBroadcastStats == null) {
18037 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
18038 final long now = SystemClock.elapsedRealtime();
18039 if (mLastBroadcastStats != null) {
18040 pw.print(" Last stats (from ");
18041 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
18043 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
18045 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
18046 - mLastBroadcastStats.mStartUptime, pw);
18047 pw.println(" uptime):");
18048 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
18049 pw.println(" (nothing)");
18053 pw.print(" Current stats (from ");
18054 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
18055 pw.print(" to now, ");
18056 TimeUtils.formatDuration(SystemClock.uptimeMillis()
18057 - mCurBroadcastStats.mStartUptime, pw);
18058 pw.println(" uptime):");
18059 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
18060 pw.println(" (nothing)");
18064 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18065 int opti, boolean fullCheckin, String dumpPackage) {
18066 if (mCurBroadcastStats == null) {
18070 if (mLastBroadcastStats != null) {
18071 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
18073 mLastBroadcastStats = null;
18077 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
18079 mCurBroadcastStats = null;
18083 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18084 int opti, boolean dumpAll, String dumpPackage) {
18086 boolean printedAnything = false;
18088 ItemMatcher matcher = new ItemMatcher();
18089 matcher.build(args, opti);
18091 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
18093 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
18094 printedAnything |= needSep;
18096 if (mLaunchingProviders.size() > 0) {
18097 boolean printed = false;
18098 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
18099 ContentProviderRecord r = mLaunchingProviders.get(i);
18100 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
18104 if (needSep) pw.println();
18106 pw.println(" Launching content providers:");
18108 printedAnything = true;
18110 pw.print(" Launching #"); pw.print(i); pw.print(": ");
18115 if (!printedAnything) {
18116 pw.println(" (nothing)");
18121 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18122 int opti, boolean dumpAll, String dumpPackage) {
18123 boolean needSep = false;
18124 boolean printedAnything = false;
18126 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
18128 if (mGrantedUriPermissions.size() > 0) {
18129 boolean printed = false;
18131 if (dumpPackage != null) {
18133 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
18134 MATCH_ANY_USER, 0);
18135 } catch (NameNotFoundException e) {
18139 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
18140 int uid = mGrantedUriPermissions.keyAt(i);
18141 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
18144 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
18146 if (needSep) pw.println();
18148 pw.println(" Granted Uri Permissions:");
18150 printedAnything = true;
18152 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
18153 for (UriPermission perm : perms.values()) {
18154 pw.print(" "); pw.println(perm);
18156 perm.dump(pw, " ");
18162 if (!printedAnything) {
18163 pw.println(" (nothing)");
18167 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18168 int opti, boolean dumpAll, String dumpPackage) {
18169 boolean printed = false;
18171 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
18173 if (mIntentSenderRecords.size() > 0) {
18174 // Organize these by package name, so they are easier to read.
18175 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
18176 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
18177 final Iterator<WeakReference<PendingIntentRecord>> it
18178 = mIntentSenderRecords.values().iterator();
18179 while (it.hasNext()) {
18180 WeakReference<PendingIntentRecord> ref = it.next();
18181 PendingIntentRecord rec = ref != null ? ref.get() : null;
18186 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
18189 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
18190 if (list == null) {
18191 list = new ArrayList<>();
18192 byPackage.put(rec.key.packageName, list);
18196 for (int i = 0; i < byPackage.size(); i++) {
18197 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
18199 pw.print(" * "); pw.print(byPackage.keyAt(i));
18200 pw.print(": "); pw.print(intents.size()); pw.println(" items");
18201 for (int j = 0; j < intents.size(); j++) {
18202 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
18204 intents.get(j).dump(pw, " ");
18208 if (weakRefs.size() > 0) {
18210 pw.println(" * WEAK REFS:");
18211 for (int i = 0; i < weakRefs.size(); i++) {
18212 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
18218 pw.println(" (nothing)");
18222 private static final int dumpProcessList(PrintWriter pw,
18223 ActivityManagerService service, List list,
18224 String prefix, String normalLabel, String persistentLabel,
18225 String dumpPackage) {
18227 final int N = list.size()-1;
18228 for (int i=N; i>=0; i--) {
18229 ProcessRecord r = (ProcessRecord)list.get(i);
18230 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
18233 pw.println(String.format("%s%s #%2d: %s",
18234 prefix, (r.persistent ? persistentLabel : normalLabel),
18236 if (r.persistent) {
18243 private static final ArrayList<Pair<ProcessRecord, Integer>>
18244 sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
18245 ArrayList<Pair<ProcessRecord, Integer>> list
18246 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
18247 for (int i=0; i<origList.size(); i++) {
18248 ProcessRecord r = origList.get(i);
18249 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
18252 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
18255 Comparator<Pair<ProcessRecord, Integer>> comparator
18256 = new Comparator<Pair<ProcessRecord, Integer>>() {
18258 public int compare(Pair<ProcessRecord, Integer> object1,
18259 Pair<ProcessRecord, Integer> object2) {
18260 if (object1.first.setAdj != object2.first.setAdj) {
18261 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
18263 if (object1.first.setProcState != object2.first.setProcState) {
18264 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
18266 if (object1.second.intValue() != object2.second.intValue()) {
18267 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
18273 Collections.sort(list, comparator);
18277 private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
18278 ActivityManagerService service, List<ProcessRecord> origList,
18279 boolean inclDetails, String dumpPackage) {
18280 ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
18281 if (list.isEmpty()) return false;
18283 final long curUptime = SystemClock.uptimeMillis();
18285 for (int i = list.size() - 1; i >= 0; i--) {
18286 ProcessRecord r = list.get(i).first;
18287 long token = proto.start(fieldId);
18288 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
18289 proto.write(ProcessOomProto.PERSISTENT, r.persistent);
18290 proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
18291 proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
18292 int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
18293 switch (r.setSchedGroup) {
18294 case ProcessList.SCHED_GROUP_BACKGROUND:
18295 schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
18297 case ProcessList.SCHED_GROUP_DEFAULT:
18298 schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
18300 case ProcessList.SCHED_GROUP_TOP_APP:
18301 schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
18303 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
18304 schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
18307 if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
18308 proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
18310 if (r.foregroundActivities) {
18311 proto.write(ProcessOomProto.ACTIVITIES, true);
18312 } else if (r.foregroundServices) {
18313 proto.write(ProcessOomProto.SERVICES, true);
18315 proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
18316 proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
18317 r.writeToProto(proto, ProcessOomProto.PROC);
18318 proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
18319 if (r.adjSource != null || r.adjTarget != null) {
18320 if (r.adjTarget instanceof ComponentName) {
18321 ComponentName cn = (ComponentName) r.adjTarget;
18322 cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
18323 } else if (r.adjTarget != null) {
18324 proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
18326 if (r.adjSource instanceof ProcessRecord) {
18327 ProcessRecord p = (ProcessRecord) r.adjSource;
18328 p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
18329 } else if (r.adjSource != null) {
18330 proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
18334 long detailToken = proto.start(ProcessOomProto.DETAIL);
18335 proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
18336 proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
18337 proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
18338 proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
18339 proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
18340 proto.write(ProcessOomProto.Detail.CURRENT_STATE,
18341 ProcessList.makeProcStateProtoEnum(r.curProcState));
18342 proto.write(ProcessOomProto.Detail.SET_STATE,
18343 ProcessList.makeProcStateProtoEnum(r.setProcState));
18344 proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
18345 r.lastPss*1024, new StringBuilder()));
18346 proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
18347 r.lastSwapPss*1024, new StringBuilder()));
18348 proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
18349 r.lastCachedPss*1024, new StringBuilder()));
18350 proto.write(ProcessOomProto.Detail.CACHED, r.cached);
18351 proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
18352 proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
18354 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18355 if (r.lastCpuTime != 0) {
18356 long uptimeSince = curUptime - service.mLastPowerCheckUptime;
18357 long timeUsed = r.curCpuTime - r.lastCpuTime;
18358 long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
18359 proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
18360 proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
18361 proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
18362 (100.0*timeUsed)/uptimeSince);
18363 proto.end(cpuTimeToken);
18366 proto.end(detailToken);
18374 private static final boolean dumpProcessOomList(PrintWriter pw,
18375 ActivityManagerService service, List<ProcessRecord> origList,
18376 String prefix, String normalLabel, String persistentLabel,
18377 boolean inclDetails, String dumpPackage) {
18379 ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
18380 if (list.isEmpty()) return false;
18382 final long curUptime = SystemClock.uptimeMillis();
18383 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
18385 for (int i=list.size()-1; i>=0; i--) {
18386 ProcessRecord r = list.get(i).first;
18387 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
18389 switch (r.setSchedGroup) {
18390 case ProcessList.SCHED_GROUP_BACKGROUND:
18393 case ProcessList.SCHED_GROUP_DEFAULT:
18396 case ProcessList.SCHED_GROUP_TOP_APP:
18399 case ProcessList.SCHED_GROUP_RESTRICTED:
18407 if (r.foregroundActivities) {
18409 } else if (r.foregroundServices) {
18414 String procState = ProcessList.makeProcStateString(r.curProcState);
18416 pw.print(r.persistent ? persistentLabel : normalLabel);
18418 int num = (origList.size()-1)-list.get(i).second;
18419 if (num < 10) pw.print(' ');
18424 pw.print(schedGroup);
18426 pw.print(foreground);
18428 pw.print(procState);
18430 if (r.trimMemoryLevel < 10) pw.print(' ');
18431 pw.print(r.trimMemoryLevel);
18433 pw.print(r.toShortString());
18435 pw.print(r.adjType);
18437 if (r.adjSource != null || r.adjTarget != null) {
18440 if (r.adjTarget instanceof ComponentName) {
18441 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
18442 } else if (r.adjTarget != null) {
18443 pw.print(r.adjTarget.toString());
18445 pw.print("{null}");
18448 if (r.adjSource instanceof ProcessRecord) {
18450 pw.print(((ProcessRecord)r.adjSource).toShortString());
18452 } else if (r.adjSource != null) {
18453 pw.println(r.adjSource.toString());
18455 pw.println("{null}");
18461 pw.print("oom: max="); pw.print(r.maxAdj);
18462 pw.print(" curRaw="); pw.print(r.curRawAdj);
18463 pw.print(" setRaw="); pw.print(r.setRawAdj);
18464 pw.print(" cur="); pw.print(r.curAdj);
18465 pw.print(" set="); pw.println(r.setAdj);
18468 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
18469 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
18470 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
18471 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
18472 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
18476 pw.print("cached="); pw.print(r.cached);
18477 pw.print(" empty="); pw.print(r.empty);
18478 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
18480 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18481 if (r.lastCpuTime != 0) {
18482 long timeUsed = r.curCpuTime - r.lastCpuTime;
18485 pw.print("run cpu over ");
18486 TimeUtils.formatDuration(uptimeSince, pw);
18487 pw.print(" used ");
18488 TimeUtils.formatDuration(timeUsed, pw);
18490 pw.print((timeUsed*100)/uptimeSince);
18499 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
18501 ArrayList<ProcessRecord> procs;
18502 synchronized (this) {
18503 if (args != null && args.length > start
18504 && args[start].charAt(0) != '-') {
18505 procs = new ArrayList<ProcessRecord>();
18508 pid = Integer.parseInt(args[start]);
18509 } catch (NumberFormatException e) {
18511 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18512 ProcessRecord proc = mLruProcesses.get(i);
18513 if (proc.pid > 0 && proc.pid == pid) {
18515 } else if (allPkgs && proc.pkgList != null
18516 && proc.pkgList.containsKey(args[start])) {
18518 } else if (proc.processName.equals(args[start])) {
18522 if (procs.size() <= 0) {
18526 procs = new ArrayList<ProcessRecord>(mLruProcesses);
18532 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
18533 PrintWriter pw, String[] args) {
18534 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18535 if (procs == null) {
18536 pw.println("No process found for: " + args[0]);
18540 long uptime = SystemClock.uptimeMillis();
18541 long realtime = SystemClock.elapsedRealtime();
18542 pw.println("Applications Graphics Acceleration Info:");
18543 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18545 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18546 ProcessRecord r = procs.get(i);
18547 if (r.thread != null) {
18548 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
18551 TransferPipe tp = new TransferPipe();
18553 r.thread.dumpGfxInfo(tp.getWriteFd(), args);
18558 } catch (IOException e) {
18559 pw.println("Failure while dumping the app: " + r);
18561 } catch (RemoteException e) {
18562 pw.println("Got a RemoteException while dumping the app " + r);
18569 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
18570 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18571 if (procs == null) {
18572 pw.println("No process found for: " + args[0]);
18576 pw.println("Applications Database Info:");
18578 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18579 ProcessRecord r = procs.get(i);
18580 if (r.thread != null) {
18581 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
18584 TransferPipe tp = new TransferPipe();
18586 r.thread.dumpDbInfo(tp.getWriteFd(), args);
18591 } catch (IOException e) {
18592 pw.println("Failure while dumping the app: " + r);
18594 } catch (RemoteException e) {
18595 pw.println("Got a RemoteException while dumping the app " + r);
18602 final static class MemItem {
18603 final boolean isProc;
18604 final String label;
18605 final String shortLabel;
18607 final long swapPss;
18609 final boolean hasActivities;
18610 ArrayList<MemItem> subitems;
18612 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
18613 boolean _hasActivities) {
18616 shortLabel = _shortLabel;
18618 swapPss = _swapPss;
18620 hasActivities = _hasActivities;
18623 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
18626 shortLabel = _shortLabel;
18628 swapPss = _swapPss;
18630 hasActivities = false;
18634 private static void sortMemItems(List<MemItem> items) {
18635 Collections.sort(items, new Comparator<MemItem>() {
18637 public int compare(MemItem lhs, MemItem rhs) {
18638 if (lhs.pss < rhs.pss) {
18640 } else if (lhs.pss > rhs.pss) {
18648 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
18649 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
18650 if (sort && !isCompact) {
18651 sortMemItems(items);
18654 for (int i=0; i<items.size(); i++) {
18655 MemItem mi = items.get(i);
18658 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
18659 mi.label, stringifyKBSize(mi.swapPss));
18661 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
18663 } else if (mi.isProc) {
18664 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
18665 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
18666 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
18667 pw.println(mi.hasActivities ? ",a" : ",e");
18669 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
18670 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
18672 if (mi.subitems != null) {
18673 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
18674 true, isCompact, dumpSwapPss);
18679 static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
18680 ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
18682 sortMemItems(items);
18685 for (int i=0; i<items.size(); i++) {
18686 MemItem mi = items.get(i);
18687 final long token = proto.start(fieldId);
18689 proto.write(MemInfoDumpProto.MemItem.TAG, tag);
18690 proto.write(MemInfoDumpProto.MemItem.LABEL, mi.shortLabel);
18691 proto.write(MemInfoDumpProto.MemItem.IS_PROC, mi.isProc);
18692 proto.write(MemInfoDumpProto.MemItem.ID, mi.id);
18693 proto.write(MemInfoDumpProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
18694 proto.write(MemInfoDumpProto.MemItem.PSS_KB, mi.pss);
18696 proto.write(MemInfoDumpProto.MemItem.SWAP_PSS_KB, mi.swapPss);
18698 if (mi.subitems != null) {
18699 dumpMemItems(proto, MemInfoDumpProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
18700 true, dumpSwapPss);
18706 // These are in KB.
18707 static final long[] DUMP_MEM_BUCKETS = new long[] {
18708 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
18709 120*1024, 160*1024, 200*1024,
18710 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
18711 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
18714 static final void appendMemBucket(StringBuilder out, long memKB, String label,
18715 boolean stackLike) {
18716 int start = label.lastIndexOf('.');
18717 if (start >= 0) start++;
18719 int end = label.length();
18720 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
18721 if (DUMP_MEM_BUCKETS[i] >= memKB) {
18722 long bucket = DUMP_MEM_BUCKETS[i]/1024;
18723 out.append(bucket);
18724 out.append(stackLike ? "MB." : "MB ");
18725 out.append(label, start, end);
18729 out.append(memKB/1024);
18730 out.append(stackLike ? "MB." : "MB ");
18731 out.append(label, start, end);
18734 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
18735 ProcessList.NATIVE_ADJ,
18736 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
18737 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
18738 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
18739 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
18740 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
18741 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
18743 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
18745 "System", "Persistent", "Persistent Service", "Foreground",
18746 "Visible", "Perceptible",
18747 "Heavy Weight", "Backup",
18748 "A Services", "Home",
18749 "Previous", "B Services", "Cached"
18751 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
18753 "sys", "pers", "persvc", "fore",
18756 "servicea", "home",
18757 "prev", "serviceb", "cached"
18760 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
18761 long realtime, boolean isCheckinRequest, boolean isCompact) {
18763 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
18765 if (isCheckinRequest || isCompact) {
18766 // short checkin version
18767 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
18769 pw.println("Applications Memory Usage (in Kilobytes):");
18770 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18774 private static final int KSM_SHARED = 0;
18775 private static final int KSM_SHARING = 1;
18776 private static final int KSM_UNSHARED = 2;
18777 private static final int KSM_VOLATILE = 3;
18779 private final long[] getKsmInfo() {
18780 long[] longOut = new long[4];
18781 final int[] SINGLE_LONG_FORMAT = new int[] {
18782 PROC_SPACE_TERM| PROC_OUT_LONG
18784 long[] longTmp = new long[1];
18785 readProcFile("/sys/kernel/mm/ksm/pages_shared",
18786 SINGLE_LONG_FORMAT, null, longTmp, null);
18787 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18789 readProcFile("/sys/kernel/mm/ksm/pages_sharing",
18790 SINGLE_LONG_FORMAT, null, longTmp, null);
18791 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18793 readProcFile("/sys/kernel/mm/ksm/pages_unshared",
18794 SINGLE_LONG_FORMAT, null, longTmp, null);
18795 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18797 readProcFile("/sys/kernel/mm/ksm/pages_volatile",
18798 SINGLE_LONG_FORMAT, null, longTmp, null);
18799 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18803 private static String stringifySize(long size, int order) {
18804 Locale locale = Locale.US;
18807 return String.format(locale, "%,13d", size);
18809 return String.format(locale, "%,9dK", size / 1024);
18811 return String.format(locale, "%,5dM", size / 1024 / 1024);
18812 case 1024 * 1024 * 1024:
18813 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
18815 throw new IllegalArgumentException("Invalid size order");
18819 private static String stringifyKBSize(long size) {
18820 return stringifySize(size * 1024, 1024);
18823 // Update this version number if you change the 'compact' format.
18824 private static final int MEMINFO_COMPACT_VERSION = 1;
18826 private static class MemoryUsageDumpOptions {
18827 boolean dumpDetails;
18828 boolean dumpFullDetails;
18829 boolean dumpDalvik;
18830 boolean dumpSummaryOnly;
18831 boolean dumpUnreachable;
18836 boolean isCheckinRequest;
18837 boolean dumpSwapPss;
18841 final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18842 String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
18843 MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
18844 opts.dumpDetails = false;
18845 opts.dumpFullDetails = false;
18846 opts.dumpDalvik = false;
18847 opts.dumpSummaryOnly = false;
18848 opts.dumpUnreachable = false;
18849 opts.oomOnly = false;
18850 opts.isCompact = false;
18851 opts.localOnly = false;
18852 opts.packages = false;
18853 opts.isCheckinRequest = false;
18854 opts.dumpSwapPss = false;
18855 opts.dumpProto = asProto;
18858 while (opti < args.length) {
18859 String opt = args[opti];
18860 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18864 if ("-a".equals(opt)) {
18865 opts.dumpDetails = true;
18866 opts.dumpFullDetails = true;
18867 opts.dumpDalvik = true;
18868 opts.dumpSwapPss = true;
18869 } else if ("-d".equals(opt)) {
18870 opts.dumpDalvik = true;
18871 } else if ("-c".equals(opt)) {
18872 opts.isCompact = true;
18873 } else if ("-s".equals(opt)) {
18874 opts.dumpDetails = true;
18875 opts.dumpSummaryOnly = true;
18876 } else if ("-S".equals(opt)) {
18877 opts.dumpSwapPss = true;
18878 } else if ("--unreachable".equals(opt)) {
18879 opts.dumpUnreachable = true;
18880 } else if ("--oom".equals(opt)) {
18881 opts.oomOnly = true;
18882 } else if ("--local".equals(opt)) {
18883 opts.localOnly = true;
18884 } else if ("--package".equals(opt)) {
18885 opts.packages = true;
18886 } else if ("--checkin".equals(opt)) {
18887 opts.isCheckinRequest = true;
18888 } else if ("--proto".equals(opt)) {
18889 opts.dumpProto = true;
18891 } else if ("-h".equals(opt)) {
18892 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
18893 pw.println(" -a: include all available information for each process.");
18894 pw.println(" -d: include dalvik details.");
18895 pw.println(" -c: dump in a compact machine-parseable representation.");
18896 pw.println(" -s: dump only summary of application memory usage.");
18897 pw.println(" -S: dump also SwapPss.");
18898 pw.println(" --oom: only show processes organized by oom adj.");
18899 pw.println(" --local: only collect details locally, don't call process.");
18900 pw.println(" --package: interpret process arg as package, dumping all");
18901 pw.println(" processes that have loaded that package.");
18902 pw.println(" --checkin: dump data for a checkin");
18903 pw.println(" --proto: dump data to proto");
18904 pw.println("If [process] is specified it can be the name or ");
18905 pw.println("pid of a specific process to dump.");
18908 pw.println("Unknown argument: " + opt + "; use -h for help");
18912 String[] innerArgs = new String[args.length-opti];
18913 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18915 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18916 if (opts.dumpProto) {
18917 dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18919 dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
18923 private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18924 MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18925 ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
18926 long uptime = SystemClock.uptimeMillis();
18927 long realtime = SystemClock.elapsedRealtime();
18928 final long[] tmpLong = new long[1];
18930 if (procs == null) {
18931 // No Java processes. Maybe they want to print a native process.
18932 String proc = "N/A";
18933 if (innerArgs.length > 0) {
18934 proc = innerArgs[0];
18935 if (proc.charAt(0) != '-') {
18936 ArrayList<ProcessCpuTracker.Stats> nativeProcs
18937 = new ArrayList<ProcessCpuTracker.Stats>();
18938 updateCpuStatsNow();
18941 findPid = Integer.parseInt(innerArgs[0]);
18942 } catch (NumberFormatException e) {
18944 synchronized (mProcessCpuTracker) {
18945 final int N = mProcessCpuTracker.countStats();
18946 for (int i=0; i<N; i++) {
18947 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18948 if (st.pid == findPid || (st.baseName != null
18949 && st.baseName.equals(innerArgs[0]))) {
18950 nativeProcs.add(st);
18954 if (nativeProcs.size() > 0) {
18955 dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
18956 opts.isCheckinRequest, opts.isCompact);
18957 Debug.MemoryInfo mi = null;
18958 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18959 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18960 final int pid = r.pid;
18961 if (!opts.isCheckinRequest && opts.dumpDetails) {
18962 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
18965 mi = new Debug.MemoryInfo();
18967 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18968 Debug.getMemoryInfo(pid, mi);
18970 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18971 mi.dalvikPrivateDirty = (int)tmpLong[0];
18973 ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
18974 opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18975 pid, r.baseName, 0, 0, 0, 0, 0, 0);
18976 if (opts.isCheckinRequest) {
18984 pw.println("No process found for: " + proc);
18988 if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18989 opts.dumpDetails = true;
18992 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
18994 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18995 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18996 long nativePss = 0;
18997 long nativeSwapPss = 0;
18998 long dalvikPss = 0;
18999 long dalvikSwapPss = 0;
19000 long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19002 long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19005 long otherSwapPss = 0;
19006 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19007 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19009 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19010 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19011 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
19012 new ArrayList[DUMP_MEM_OOM_LABEL.length];
19015 long totalSwapPss = 0;
19016 long cachedPss = 0;
19017 long cachedSwapPss = 0;
19018 boolean hasSwapPss = false;
19020 Debug.MemoryInfo mi = null;
19021 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
19022 final ProcessRecord r = procs.get(i);
19023 final IApplicationThread thread;
19026 final boolean hasActivities;
19027 synchronized (this) {
19030 oomAdj = r.getSetAdjWithServices();
19031 hasActivities = r.activities.size() > 0;
19033 if (thread != null) {
19034 if (!opts.isCheckinRequest && opts.dumpDetails) {
19035 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
19038 mi = new Debug.MemoryInfo();
19040 final int reportType;
19041 final long startTime;
19042 final long endTime;
19043 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19044 reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
19045 startTime = SystemClock.currentThreadTimeMillis();
19046 Debug.getMemoryInfo(pid, mi);
19047 endTime = SystemClock.currentThreadTimeMillis();
19048 hasSwapPss = mi.hasSwappedOutPss;
19050 reportType = ProcessStats.ADD_PSS_EXTERNAL;
19051 startTime = SystemClock.currentThreadTimeMillis();
19052 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
19053 endTime = SystemClock.currentThreadTimeMillis();
19054 mi.dalvikPrivateDirty = (int)tmpLong[0];
19056 if (opts.dumpDetails) {
19057 if (opts.localOnly) {
19058 ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
19059 opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
19060 if (opts.isCheckinRequest) {
19066 TransferPipe tp = new TransferPipe();
19068 thread.dumpMemInfo(tp.getWriteFd(),
19069 mi, opts.isCheckinRequest, opts.dumpFullDetails,
19070 opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
19071 tp.go(fd, opts.dumpUnreachable ? 30000 : 5000);
19075 } catch (IOException e) {
19076 if (!opts.isCheckinRequest) {
19077 pw.println("Got IoException! " + e);
19080 } catch (RemoteException e) {
19081 if (!opts.isCheckinRequest) {
19082 pw.println("Got RemoteException! " + e);
19089 final long myTotalPss = mi.getTotalPss();
19090 final long myTotalUss = mi.getTotalUss();
19091 final long myTotalRss = mi.getTotalRss();
19092 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19094 synchronized (this) {
19095 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
19096 // Record this for posterity if the process has been stable.
19097 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
19098 reportType, endTime-startTime, r.pkgList);
19102 if (!opts.isCheckinRequest && mi != null) {
19103 totalPss += myTotalPss;
19104 totalSwapPss += myTotalSwapPss;
19105 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19106 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19107 myTotalSwapPss, pid, hasActivities);
19108 procMems.add(pssItem);
19109 procMemsMap.put(pid, pssItem);
19111 nativePss += mi.nativePss;
19112 nativeSwapPss += mi.nativeSwappedOutPss;
19113 dalvikPss += mi.dalvikPss;
19114 dalvikSwapPss += mi.dalvikSwappedOutPss;
19115 for (int j=0; j<dalvikSubitemPss.length; j++) {
19116 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19117 dalvikSubitemSwapPss[j] +=
19118 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19120 otherPss += mi.otherPss;
19121 otherSwapPss += mi.otherSwappedOutPss;
19122 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19123 long mem = mi.getOtherPss(j);
19126 mem = mi.getOtherSwappedOutPss(j);
19127 miscSwapPss[j] += mem;
19128 otherSwapPss -= mem;
19131 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19132 cachedPss += myTotalPss;
19133 cachedSwapPss += myTotalSwapPss;
19136 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19137 if (oomIndex == (oomPss.length - 1)
19138 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19139 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19140 oomPss[oomIndex] += myTotalPss;
19141 oomSwapPss[oomIndex] += myTotalSwapPss;
19142 if (oomProcs[oomIndex] == null) {
19143 oomProcs[oomIndex] = new ArrayList<MemItem>();
19145 oomProcs[oomIndex].add(pssItem);
19153 long nativeProcTotalPss = 0;
19155 if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
19156 // If we are showing aggregations, also look for native processes to
19157 // include so that our aggregations are more accurate.
19158 updateCpuStatsNow();
19160 synchronized (mProcessCpuTracker) {
19161 final int N = mProcessCpuTracker.countStats();
19162 for (int i=0; i<N; i++) {
19163 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19164 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19166 mi = new Debug.MemoryInfo();
19168 if (!brief && !opts.oomOnly) {
19169 Debug.getMemoryInfo(st.pid, mi);
19171 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19172 mi.nativePrivateDirty = (int)tmpLong[0];
19175 final long myTotalPss = mi.getTotalPss();
19176 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19177 totalPss += myTotalPss;
19178 totalSwapPss += myTotalSwapPss;
19179 nativeProcTotalPss += myTotalPss;
19181 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19182 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19183 procMems.add(pssItem);
19185 nativePss += mi.nativePss;
19186 nativeSwapPss += mi.nativeSwappedOutPss;
19187 dalvikPss += mi.dalvikPss;
19188 dalvikSwapPss += mi.dalvikSwappedOutPss;
19189 for (int j=0; j<dalvikSubitemPss.length; j++) {
19190 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19191 dalvikSubitemSwapPss[j] +=
19192 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19194 otherPss += mi.otherPss;
19195 otherSwapPss += mi.otherSwappedOutPss;
19196 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19197 long mem = mi.getOtherPss(j);
19200 mem = mi.getOtherSwappedOutPss(j);
19201 miscSwapPss[j] += mem;
19202 otherSwapPss -= mem;
19204 oomPss[0] += myTotalPss;
19205 oomSwapPss[0] += myTotalSwapPss;
19206 if (oomProcs[0] == null) {
19207 oomProcs[0] = new ArrayList<MemItem>();
19209 oomProcs[0].add(pssItem);
19214 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19216 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19217 final int dalvikId = -2;
19218 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19219 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19220 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19221 String label = Debug.MemoryInfo.getOtherLabel(j);
19222 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19224 if (dalvikSubitemPss.length > 0) {
19225 // Add dalvik subitems.
19226 for (MemItem memItem : catMems) {
19227 int memItemStart = 0, memItemEnd = 0;
19228 if (memItem.id == dalvikId) {
19229 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19230 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19231 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19232 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19233 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19234 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19235 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19236 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19237 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19238 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19239 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19241 continue; // No subitems, continue.
19243 memItem.subitems = new ArrayList<MemItem>();
19244 for (int j=memItemStart; j<=memItemEnd; j++) {
19245 final String name = Debug.MemoryInfo.getOtherLabel(
19246 Debug.MemoryInfo.NUM_OTHER_STATS + j);
19247 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19248 dalvikSubitemSwapPss[j], j));
19253 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19254 for (int j=0; j<oomPss.length; j++) {
19255 if (oomPss[j] != 0) {
19256 String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19257 : DUMP_MEM_OOM_LABEL[j];
19258 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19259 DUMP_MEM_OOM_ADJ[j]);
19260 item.subitems = oomProcs[j];
19265 opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19266 if (!brief && !opts.oomOnly && !opts.isCompact) {
19268 pw.println("Total PSS by process:");
19269 dumpMemItems(pw, " ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
19272 if (!opts.isCompact) {
19273 pw.println("Total PSS by OOM adjustment:");
19275 dumpMemItems(pw, " ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
19276 if (!brief && !opts.oomOnly) {
19277 PrintWriter out = categoryPw != null ? categoryPw : pw;
19278 if (!opts.isCompact) {
19280 out.println("Total PSS by category:");
19282 dumpMemItems(out, " ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
19284 if (!opts.isCompact) {
19287 MemInfoReader memInfo = new MemInfoReader();
19288 memInfo.readMemInfo();
19289 if (nativeProcTotalPss > 0) {
19290 synchronized (this) {
19291 final long cachedKb = memInfo.getCachedSizeKb();
19292 final long freeKb = memInfo.getFreeSizeKb();
19293 final long zramKb = memInfo.getZramTotalSizeKb();
19294 final long kernelKb = memInfo.getKernelUsedSizeKb();
19295 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19296 kernelKb*1024, nativeProcTotalPss*1024);
19297 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19298 nativeProcTotalPss);
19302 if (!opts.isCompact) {
19303 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
19304 pw.print(" (status ");
19305 switch (mLastMemoryLevel) {
19306 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
19307 pw.println("normal)");
19309 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
19310 pw.println("moderate)");
19312 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19313 pw.println("low)");
19315 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19316 pw.println("critical)");
19319 pw.print(mLastMemoryLevel);
19323 pw.print(" Free RAM: ");
19324 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19325 + memInfo.getFreeSizeKb()));
19327 pw.print(stringifyKBSize(cachedPss));
19328 pw.print(" cached pss + ");
19329 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
19330 pw.print(" cached kernel + ");
19331 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
19332 pw.println(" free)");
19334 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
19335 pw.print(cachedPss + memInfo.getCachedSizeKb()
19336 + memInfo.getFreeSizeKb()); pw.print(",");
19337 pw.println(totalPss - cachedPss);
19340 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19341 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19342 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19343 if (!opts.isCompact) {
19344 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
19345 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
19346 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
19347 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
19348 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
19350 pw.print("lostram,"); pw.println(lostRAM);
19353 if (memInfo.getZramTotalSizeKb() != 0) {
19354 if (!opts.isCompact) {
19355 pw.print(" ZRAM: ");
19356 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
19357 pw.print(" physical used for ");
19358 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
19359 - memInfo.getSwapFreeSizeKb()));
19360 pw.print(" in swap (");
19361 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
19362 pw.println(" total swap)");
19364 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
19365 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
19366 pw.println(memInfo.getSwapFreeSizeKb());
19369 final long[] ksm = getKsmInfo();
19370 if (!opts.isCompact) {
19371 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19372 || ksm[KSM_VOLATILE] != 0) {
19373 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
19374 pw.print(" saved from shared ");
19375 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
19376 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
19377 pw.print(" unshared; ");
19378 pw.print(stringifyKBSize(
19379 ksm[KSM_VOLATILE])); pw.println(" volatile");
19381 pw.print(" Tuning: ");
19382 pw.print(ActivityManager.staticGetMemoryClass());
19383 pw.print(" (large ");
19384 pw.print(ActivityManager.staticGetLargeMemoryClass());
19385 pw.print("), oom ");
19386 pw.print(stringifySize(
19387 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
19388 pw.print(", restore limit ");
19389 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
19390 if (ActivityManager.isLowRamDeviceStatic()) {
19391 pw.print(" (low-ram)");
19393 if (ActivityManager.isHighEndGfx()) {
19394 pw.print(" (high-end-gfx)");
19398 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
19399 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
19400 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
19401 pw.print("tuning,");
19402 pw.print(ActivityManager.staticGetMemoryClass());
19404 pw.print(ActivityManager.staticGetLargeMemoryClass());
19406 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
19407 if (ActivityManager.isLowRamDeviceStatic()) {
19408 pw.print(",low-ram");
19410 if (ActivityManager.isHighEndGfx()) {
19411 pw.print(",high-end-gfx");
19419 private final void dumpApplicationMemoryUsage(FileDescriptor fd,
19420 MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
19421 ArrayList<ProcessRecord> procs) {
19422 final long uptimeMs = SystemClock.uptimeMillis();
19423 final long realtimeMs = SystemClock.elapsedRealtime();
19424 final long[] tmpLong = new long[1];
19426 if (procs == null) {
19427 // No Java processes. Maybe they want to print a native process.
19428 String proc = "N/A";
19429 if (innerArgs.length > 0) {
19430 proc = innerArgs[0];
19431 if (proc.charAt(0) != '-') {
19432 ArrayList<ProcessCpuTracker.Stats> nativeProcs
19433 = new ArrayList<ProcessCpuTracker.Stats>();
19434 updateCpuStatsNow();
19437 findPid = Integer.parseInt(innerArgs[0]);
19438 } catch (NumberFormatException e) {
19440 synchronized (mProcessCpuTracker) {
19441 final int N = mProcessCpuTracker.countStats();
19442 for (int i=0; i<N; i++) {
19443 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19444 if (st.pid == findPid || (st.baseName != null
19445 && st.baseName.equals(innerArgs[0]))) {
19446 nativeProcs.add(st);
19450 if (nativeProcs.size() > 0) {
19451 ProtoOutputStream proto = new ProtoOutputStream(fd);
19453 proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19454 proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19455 Debug.MemoryInfo mi = null;
19456 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
19457 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
19458 final int pid = r.pid;
19459 final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES);
19461 proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19462 proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName);
19465 mi = new Debug.MemoryInfo();
19467 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19468 Debug.getMemoryInfo(pid, mi);
19470 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
19471 mi.dalvikPrivateDirty = (int)tmpLong[0];
19473 ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19474 opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19484 Log.d(TAG, "No process found for: " + innerArgs[0]);
19488 if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
19489 opts.dumpDetails = true;
19492 ProtoOutputStream proto = new ProtoOutputStream(fd);
19494 proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19495 proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19497 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
19498 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
19499 long nativePss = 0;
19500 long nativeSwapPss = 0;
19501 long dalvikPss = 0;
19502 long dalvikSwapPss = 0;
19503 long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19505 long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19508 long otherSwapPss = 0;
19509 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19510 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19512 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19513 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19514 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
19515 new ArrayList[DUMP_MEM_OOM_LABEL.length];
19518 long totalSwapPss = 0;
19519 long cachedPss = 0;
19520 long cachedSwapPss = 0;
19521 boolean hasSwapPss = false;
19523 Debug.MemoryInfo mi = null;
19524 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
19525 final ProcessRecord r = procs.get(i);
19526 final IApplicationThread thread;
19529 final boolean hasActivities;
19530 synchronized (this) {
19533 oomAdj = r.getSetAdjWithServices();
19534 hasActivities = r.activities.size() > 0;
19536 if (thread == null) {
19540 mi = new Debug.MemoryInfo();
19542 final int reportType;
19543 final long startTime;
19544 final long endTime;
19545 if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19546 reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
19547 startTime = SystemClock.currentThreadTimeMillis();
19548 Debug.getMemoryInfo(pid, mi);
19549 endTime = SystemClock.currentThreadTimeMillis();
19550 hasSwapPss = mi.hasSwappedOutPss;
19552 reportType = ProcessStats.ADD_PSS_EXTERNAL;
19553 startTime = SystemClock.currentThreadTimeMillis();
19554 mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
19555 endTime = SystemClock.currentThreadTimeMillis();
19556 mi.dalvikPrivateDirty = (int) tmpLong[0];
19558 if (opts.dumpDetails) {
19559 if (opts.localOnly) {
19560 final long aToken = proto.start(MemInfoDumpProto.APP_PROCESSES);
19561 final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
19562 proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19563 proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.processName);
19564 ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19565 opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19570 ByteTransferPipe tp = new ByteTransferPipe();
19572 thread.dumpMemInfoProto(tp.getWriteFd(),
19573 mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
19574 opts.dumpUnreachable, innerArgs);
19575 proto.write(MemInfoDumpProto.APP_PROCESSES, tp.get());
19579 } catch (IOException e) {
19580 Log.e(TAG, "Got IOException!", e);
19581 } catch (RemoteException e) {
19582 Log.e(TAG, "Got RemoteException!", e);
19587 final long myTotalPss = mi.getTotalPss();
19588 final long myTotalUss = mi.getTotalUss();
19589 final long myTotalRss = mi.getTotalRss();
19590 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19592 synchronized (this) {
19593 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
19594 // Record this for posterity if the process has been stable.
19595 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
19596 reportType, endTime-startTime, r.pkgList);
19600 if (!opts.isCheckinRequest && mi != null) {
19601 totalPss += myTotalPss;
19602 totalSwapPss += myTotalSwapPss;
19603 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19604 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19605 myTotalSwapPss, pid, hasActivities);
19606 procMems.add(pssItem);
19607 procMemsMap.put(pid, pssItem);
19609 nativePss += mi.nativePss;
19610 nativeSwapPss += mi.nativeSwappedOutPss;
19611 dalvikPss += mi.dalvikPss;
19612 dalvikSwapPss += mi.dalvikSwappedOutPss;
19613 for (int j=0; j<dalvikSubitemPss.length; j++) {
19614 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19615 dalvikSubitemSwapPss[j] +=
19616 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19618 otherPss += mi.otherPss;
19619 otherSwapPss += mi.otherSwappedOutPss;
19620 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19621 long mem = mi.getOtherPss(j);
19624 mem = mi.getOtherSwappedOutPss(j);
19625 miscSwapPss[j] += mem;
19626 otherSwapPss -= mem;
19629 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19630 cachedPss += myTotalPss;
19631 cachedSwapPss += myTotalSwapPss;
19634 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19635 if (oomIndex == (oomPss.length - 1)
19636 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19637 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19638 oomPss[oomIndex] += myTotalPss;
19639 oomSwapPss[oomIndex] += myTotalSwapPss;
19640 if (oomProcs[oomIndex] == null) {
19641 oomProcs[oomIndex] = new ArrayList<MemItem>();
19643 oomProcs[oomIndex].add(pssItem);
19650 long nativeProcTotalPss = 0;
19652 if (procs.size() > 1 && !opts.packages) {
19653 // If we are showing aggregations, also look for native processes to
19654 // include so that our aggregations are more accurate.
19655 updateCpuStatsNow();
19657 synchronized (mProcessCpuTracker) {
19658 final int N = mProcessCpuTracker.countStats();
19659 for (int i=0; i<N; i++) {
19660 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19661 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19663 mi = new Debug.MemoryInfo();
19665 if (!brief && !opts.oomOnly) {
19666 Debug.getMemoryInfo(st.pid, mi);
19668 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19669 mi.nativePrivateDirty = (int)tmpLong[0];
19672 final long myTotalPss = mi.getTotalPss();
19673 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19674 totalPss += myTotalPss;
19675 nativeProcTotalPss += myTotalPss;
19677 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19678 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19679 procMems.add(pssItem);
19681 nativePss += mi.nativePss;
19682 nativeSwapPss += mi.nativeSwappedOutPss;
19683 dalvikPss += mi.dalvikPss;
19684 dalvikSwapPss += mi.dalvikSwappedOutPss;
19685 for (int j=0; j<dalvikSubitemPss.length; j++) {
19686 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19687 dalvikSubitemSwapPss[j] +=
19688 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19690 otherPss += mi.otherPss;
19691 otherSwapPss += mi.otherSwappedOutPss;
19692 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19693 long mem = mi.getOtherPss(j);
19696 mem = mi.getOtherSwappedOutPss(j);
19697 miscSwapPss[j] += mem;
19698 otherSwapPss -= mem;
19700 oomPss[0] += myTotalPss;
19701 oomSwapPss[0] += myTotalSwapPss;
19702 if (oomProcs[0] == null) {
19703 oomProcs[0] = new ArrayList<MemItem>();
19705 oomProcs[0].add(pssItem);
19710 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19712 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19713 final int dalvikId = -2;
19714 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19715 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19716 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19717 String label = Debug.MemoryInfo.getOtherLabel(j);
19718 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19720 if (dalvikSubitemPss.length > 0) {
19721 // Add dalvik subitems.
19722 for (MemItem memItem : catMems) {
19723 int memItemStart = 0, memItemEnd = 0;
19724 if (memItem.id == dalvikId) {
19725 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19726 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19727 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19728 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19729 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19730 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19731 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19732 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19733 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19734 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19735 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19737 continue; // No subitems, continue.
19739 memItem.subitems = new ArrayList<MemItem>();
19740 for (int j=memItemStart; j<=memItemEnd; j++) {
19741 final String name = Debug.MemoryInfo.getOtherLabel(
19742 Debug.MemoryInfo.NUM_OTHER_STATS + j);
19743 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19744 dalvikSubitemSwapPss[j], j));
19749 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19750 for (int j=0; j<oomPss.length; j++) {
19751 if (oomPss[j] != 0) {
19752 String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19753 : DUMP_MEM_OOM_LABEL[j];
19754 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19755 DUMP_MEM_OOM_ADJ[j]);
19756 item.subitems = oomProcs[j];
19761 opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19762 if (!opts.oomOnly) {
19763 dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_PROCESS, "proc",
19764 procMems, true, opts.dumpSwapPss);
19766 dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
19767 oomMems, false, opts.dumpSwapPss);
19768 if (!brief && !opts.oomOnly) {
19769 dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_CATEGORY, "cat",
19770 catMems, true, opts.dumpSwapPss);
19772 MemInfoReader memInfo = new MemInfoReader();
19773 memInfo.readMemInfo();
19774 if (nativeProcTotalPss > 0) {
19775 synchronized (this) {
19776 final long cachedKb = memInfo.getCachedSizeKb();
19777 final long freeKb = memInfo.getFreeSizeKb();
19778 final long zramKb = memInfo.getZramTotalSizeKb();
19779 final long kernelKb = memInfo.getKernelUsedSizeKb();
19780 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19781 kernelKb*1024, nativeProcTotalPss*1024);
19782 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19783 nativeProcTotalPss);
19787 proto.write(MemInfoDumpProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
19788 proto.write(MemInfoDumpProto.STATUS, mLastMemoryLevel);
19789 proto.write(MemInfoDumpProto.CACHED_PSS_KB, cachedPss);
19790 proto.write(MemInfoDumpProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
19791 proto.write(MemInfoDumpProto.FREE_KB, memInfo.getFreeSizeKb());
19793 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19794 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19795 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19796 proto.write(MemInfoDumpProto.USED_PSS_KB, totalPss - cachedPss);
19797 proto.write(MemInfoDumpProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
19798 proto.write(MemInfoDumpProto.LOST_RAM_KB, lostRAM);
19800 if (memInfo.getZramTotalSizeKb() != 0) {
19801 proto.write(MemInfoDumpProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
19802 proto.write(MemInfoDumpProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
19803 memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
19804 proto.write(MemInfoDumpProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
19806 final long[] ksm = getKsmInfo();
19807 proto.write(MemInfoDumpProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
19808 proto.write(MemInfoDumpProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
19809 proto.write(MemInfoDumpProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
19810 proto.write(MemInfoDumpProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
19812 proto.write(MemInfoDumpProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
19813 proto.write(MemInfoDumpProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
19814 proto.write(MemInfoDumpProto.OOM_KB,
19815 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
19816 proto.write(MemInfoDumpProto.RESTORE_LIMIT_KB,
19817 mProcessList.getCachedRestoreThresholdKb());
19819 proto.write(MemInfoDumpProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
19820 proto.write(MemInfoDumpProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
19827 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
19828 long memtrack, String name) {
19830 sb.append(ProcessList.makeOomAdjString(oomAdj));
19832 sb.append(ProcessList.makeProcStateString(procState));
19834 ProcessList.appendRamKb(sb, pss);
19837 if (memtrack > 0) {
19839 sb.append(stringifyKBSize(memtrack));
19840 sb.append(" memtrack)");
19844 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
19845 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
19846 sb.append(" (pid ");
19849 sb.append(mi.adjType);
19851 if (mi.adjReason != null) {
19853 sb.append(mi.adjReason);
19858 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
19859 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
19860 for (int i=0, N=memInfos.size(); i<N; i++) {
19861 ProcessMemInfo mi = memInfos.get(i);
19862 infoMap.put(mi.pid, mi);
19864 updateCpuStatsNow();
19865 long[] memtrackTmp = new long[1];
19866 final List<ProcessCpuTracker.Stats> stats;
19867 // Get a list of Stats that have vsize > 0
19868 synchronized (mProcessCpuTracker) {
19869 stats = mProcessCpuTracker.getStats((st) -> {
19870 return st.vsize > 0;
19873 final int statsCount = stats.size();
19874 for (int i = 0; i < statsCount; i++) {
19875 ProcessCpuTracker.Stats st = stats.get(i);
19876 long pss = Debug.getPss(st.pid, null, memtrackTmp);
19878 if (infoMap.indexOfKey(st.pid) < 0) {
19879 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19880 ProcessList.NATIVE_ADJ, -1, "native", null);
19882 mi.memtrack = memtrackTmp[0];
19889 long totalMemtrack = 0;
19890 for (int i=0, N=memInfos.size(); i<N; i++) {
19891 ProcessMemInfo mi = memInfos.get(i);
19893 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19894 mi.memtrack = memtrackTmp[0];
19896 totalPss += mi.pss;
19897 totalMemtrack += mi.memtrack;
19899 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
19900 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
19901 if (lhs.oomAdj != rhs.oomAdj) {
19902 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
19904 if (lhs.pss != rhs.pss) {
19905 return lhs.pss < rhs.pss ? 1 : -1;
19911 StringBuilder tag = new StringBuilder(128);
19912 StringBuilder stack = new StringBuilder(128);
19913 tag.append("Low on memory -- ");
19914 appendMemBucket(tag, totalPss, "total", false);
19915 appendMemBucket(stack, totalPss, "total", true);
19917 StringBuilder fullNativeBuilder = new StringBuilder(1024);
19918 StringBuilder shortNativeBuilder = new StringBuilder(1024);
19919 StringBuilder fullJavaBuilder = new StringBuilder(1024);
19921 boolean firstLine = true;
19922 int lastOomAdj = Integer.MIN_VALUE;
19923 long extraNativeRam = 0;
19924 long extraNativeMemtrack = 0;
19925 long cachedPss = 0;
19926 for (int i=0, N=memInfos.size(); i<N; i++) {
19927 ProcessMemInfo mi = memInfos.get(i);
19929 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19930 cachedPss += mi.pss;
19933 if (mi.oomAdj != ProcessList.NATIVE_ADJ
19934 && (mi.oomAdj < ProcessList.SERVICE_ADJ
19935 || mi.oomAdj == ProcessList.HOME_APP_ADJ
19936 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
19937 if (lastOomAdj != mi.oomAdj) {
19938 lastOomAdj = mi.oomAdj;
19939 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19942 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19947 stack.append("\n\t at ");
19955 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19956 appendMemBucket(tag, mi.pss, mi.name, false);
19958 appendMemBucket(stack, mi.pss, mi.name, true);
19959 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
19960 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
19962 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
19963 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
19964 stack.append(DUMP_MEM_OOM_LABEL[k]);
19966 stack.append(DUMP_MEM_OOM_ADJ[k]);
19973 appendMemInfo(fullNativeBuilder, mi);
19974 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
19975 // The short form only has native processes that are >= 512K.
19976 if (mi.pss >= 512) {
19977 appendMemInfo(shortNativeBuilder, mi);
19979 extraNativeRam += mi.pss;
19980 extraNativeMemtrack += mi.memtrack;
19983 // Short form has all other details, but if we have collected RAM
19984 // from smaller native processes let's dump a summary of that.
19985 if (extraNativeRam > 0) {
19986 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
19987 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
19988 shortNativeBuilder.append('\n');
19989 extraNativeRam = 0;
19991 appendMemInfo(fullJavaBuilder, mi);
19995 fullJavaBuilder.append(" ");
19996 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
19997 fullJavaBuilder.append(": TOTAL");
19998 if (totalMemtrack > 0) {
19999 fullJavaBuilder.append(" (");
20000 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
20001 fullJavaBuilder.append(" memtrack)");
20004 fullJavaBuilder.append("\n");
20006 MemInfoReader memInfo = new MemInfoReader();
20007 memInfo.readMemInfo();
20008 final long[] infos = memInfo.getRawInfo();
20010 StringBuilder memInfoBuilder = new StringBuilder(1024);
20011 Debug.getMemInfo(infos);
20012 memInfoBuilder.append(" MemInfo: ");
20013 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
20014 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
20015 memInfoBuilder.append(stringifyKBSize(
20016 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
20017 memInfoBuilder.append(stringifyKBSize(
20018 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
20019 memInfoBuilder.append(stringifyKBSize(
20020 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
20021 memInfoBuilder.append(" ");
20022 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
20023 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
20024 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
20025 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
20026 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
20027 memInfoBuilder.append(" ZRAM: ");
20028 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
20029 memInfoBuilder.append(" RAM, ");
20030 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
20031 memInfoBuilder.append(" swap total, ");
20032 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
20033 memInfoBuilder.append(" swap free\n");
20035 final long[] ksm = getKsmInfo();
20036 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
20037 || ksm[KSM_VOLATILE] != 0) {
20038 memInfoBuilder.append(" KSM: ");
20039 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
20040 memInfoBuilder.append(" saved from shared ");
20041 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
20042 memInfoBuilder.append("\n ");
20043 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
20044 memInfoBuilder.append(" unshared; ");
20045 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
20046 memInfoBuilder.append(" volatile\n");
20048 memInfoBuilder.append(" Free RAM: ");
20049 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
20050 + memInfo.getFreeSizeKb()));
20051 memInfoBuilder.append("\n");
20052 memInfoBuilder.append(" Used RAM: ");
20053 memInfoBuilder.append(stringifyKBSize(
20054 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
20055 memInfoBuilder.append("\n");
20056 memInfoBuilder.append(" Lost RAM: ");
20057 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
20058 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
20059 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
20060 memInfoBuilder.append("\n");
20061 Slog.i(TAG, "Low on memory:");
20062 Slog.i(TAG, shortNativeBuilder.toString());
20063 Slog.i(TAG, fullJavaBuilder.toString());
20064 Slog.i(TAG, memInfoBuilder.toString());
20066 StringBuilder dropBuilder = new StringBuilder(1024);
20068 StringWriter oomSw = new StringWriter();
20069 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
20070 StringWriter catSw = new StringWriter();
20071 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
20072 String[] emptyArgs = new String[] { };
20073 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
20075 String oomString = oomSw.toString();
20077 dropBuilder.append("Low on memory:");
20078 dropBuilder.append(stack);
20079 dropBuilder.append('\n');
20080 dropBuilder.append(fullNativeBuilder);
20081 dropBuilder.append(fullJavaBuilder);
20082 dropBuilder.append('\n');
20083 dropBuilder.append(memInfoBuilder);
20084 dropBuilder.append('\n');
20086 dropBuilder.append(oomString);
20087 dropBuilder.append('\n');
20089 StringWriter catSw = new StringWriter();
20090 synchronized (ActivityManagerService.this) {
20091 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
20092 String[] emptyArgs = new String[] { };
20094 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
20096 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
20097 false, null).dumpLocked();
20099 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
20102 dropBuilder.append(catSw.toString());
20103 StatsLog.write(StatsLog.LOW_MEM_REPORTED);
20104 addErrorToDropBox("lowmem", null, "system_server", null,
20105 null, tag.toString(), dropBuilder.toString(), null, null);
20106 //Slog.i(TAG, "Sent to dropbox:");
20107 //Slog.i(TAG, dropBuilder.toString());
20108 synchronized (ActivityManagerService.this) {
20109 long now = SystemClock.uptimeMillis();
20110 if (mLastMemUsageReportTime < now) {
20111 mLastMemUsageReportTime = now;
20117 * Searches array of arguments for the specified string
20118 * @param args array of argument strings
20119 * @param value value to search for
20120 * @return true if the value is contained in the array
20122 private static boolean scanArgs(String[] args, String value) {
20123 if (args != null) {
20124 for (String arg : args) {
20125 if (value.equals(arg)) {
20133 private final boolean removeDyingProviderLocked(ProcessRecord proc,
20134 ContentProviderRecord cpr, boolean always) {
20135 final boolean inLaunching = mLaunchingProviders.contains(cpr);
20137 if (!inLaunching || always) {
20138 synchronized (cpr) {
20139 cpr.launchingApp = null;
20142 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
20143 String names[] = cpr.info.authority.split(";");
20144 for (int j = 0; j < names.length; j++) {
20145 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
20149 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
20150 ContentProviderConnection conn = cpr.connections.get(i);
20151 if (conn.waiting) {
20152 // If this connection is waiting for the provider, then we don't
20153 // need to mess with its process unless we are always removing
20154 // or for some reason the provider is not currently launching.
20155 if (inLaunching && !always) {
20159 ProcessRecord capp = conn.client;
20161 if (conn.stableCount > 0) {
20162 if (!capp.persistent && capp.thread != null
20164 && capp.pid != MY_PID) {
20165 capp.kill("depends on provider "
20166 + cpr.name.flattenToShortString()
20167 + " in dying proc " + (proc != null ? proc.processName : "??")
20168 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
20170 } else if (capp.thread != null && conn.provider.provider != null) {
20172 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
20173 } catch (RemoteException e) {
20175 // In the protocol here, we don't expect the client to correctly
20176 // clean up this connection, we'll just remove it.
20177 cpr.connections.remove(i);
20178 if (conn.client.conProviders.remove(conn)) {
20179 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
20184 if (inLaunching && always) {
20185 mLaunchingProviders.remove(cpr);
20187 return inLaunching;
20191 * Main code for cleaning up a process when it has gone away. This is
20192 * called both as a result of the process dying, or directly when stopping
20193 * a process when running in single process mode.
20195 * @return Returns true if the given process has been restarted, so the
20196 * app that was passed in must remain on the process lists.
20199 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
20200 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
20202 removeLruProcessLocked(app);
20203 ProcessList.remove(app.pid);
20206 mProcessesToGc.remove(app);
20207 mPendingPssProcesses.remove(app);
20208 ProcessList.abortNextPssTime(app.procStateMemTracker);
20210 // Dismiss any open dialogs.
20211 if (app.crashDialog != null && !app.forceCrashReport) {
20212 app.crashDialog.dismiss();
20213 app.crashDialog = null;
20215 if (app.anrDialog != null) {
20216 app.anrDialog.dismiss();
20217 app.anrDialog = null;
20219 if (app.waitDialog != null) {
20220 app.waitDialog.dismiss();
20221 app.waitDialog = null;
20224 app.crashing = false;
20225 app.notResponding = false;
20227 app.resetPackageList(mProcessStats);
20228 app.unlinkDeathRecipient();
20229 app.makeInactive(mProcessStats);
20230 app.waitingToKill = null;
20231 app.forcingToImportant = null;
20232 updateProcessForegroundLocked(app, false, false);
20233 app.foregroundActivities = false;
20234 app.hasShownUi = false;
20235 app.treatLikeActivity = false;
20236 app.hasAboveClient = false;
20237 app.hasClientActivities = false;
20239 mServices.killServicesLocked(app, allowRestart);
20241 boolean restart = false;
20243 // Remove published content providers.
20244 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
20245 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
20246 final boolean always = app.bad || !allowRestart;
20247 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
20248 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
20249 // We left the provider in the launching list, need to
20254 cpr.provider = null;
20257 app.pubProviders.clear();
20259 // Take care of any launching providers waiting for this process.
20260 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
20264 // Unregister from connected content providers.
20265 if (!app.conProviders.isEmpty()) {
20266 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
20267 ContentProviderConnection conn = app.conProviders.get(i);
20268 conn.provider.connections.remove(conn);
20269 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
20270 conn.provider.name);
20272 app.conProviders.clear();
20275 // At this point there may be remaining entries in mLaunchingProviders
20276 // where we were the only one waiting, so they are no longer of use.
20277 // Look for these and clean up if found.
20278 // XXX Commented out for now. Trying to figure out a way to reproduce
20279 // the actual situation to identify what is actually going on.
20281 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20282 ContentProviderRecord cpr = mLaunchingProviders.get(i);
20283 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
20284 synchronized (cpr) {
20285 cpr.launchingApp = null;
20292 skipCurrentReceiverLocked(app);
20294 // Unregister any receivers.
20295 for (int i = app.receivers.size() - 1; i >= 0; i--) {
20296 removeReceiverLocked(app.receivers.valueAt(i));
20298 app.receivers.clear();
20300 // If the app is undergoing backup, tell the backup manager about it
20301 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
20302 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
20303 + mBackupTarget.appInfo + " died during backup");
20304 mHandler.post(new Runnable() {
20308 IBackupManager bm = IBackupManager.Stub.asInterface(
20309 ServiceManager.getService(Context.BACKUP_SERVICE));
20310 bm.agentDisconnected(app.info.packageName);
20311 } catch (RemoteException e) {
20312 // can't happen; backup manager is local
20318 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
20319 ProcessChangeItem item = mPendingProcessChanges.get(i);
20320 if (app.pid > 0 && item.pid == app.pid) {
20321 mPendingProcessChanges.remove(i);
20322 mAvailProcessChanges.add(item);
20325 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
20326 null).sendToTarget();
20328 // If the caller is restarting this app, then leave it in its
20329 // current lists and let the caller take care of it.
20334 if (!app.persistent || app.isolated) {
20335 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
20336 "Removing non-persistent process during cleanup: " + app);
20337 if (!replacingPid) {
20338 removeProcessNameLocked(app.processName, app.uid, app);
20340 if (mHeavyWeightProcess == app) {
20341 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
20342 mHeavyWeightProcess.userId, 0));
20343 mHeavyWeightProcess = null;
20345 } else if (!app.removed) {
20346 // This app is persistent, so we need to keep its record around.
20347 // If it is not already on the pending app list, add it there
20348 // and start a new process for it.
20349 if (mPersistentStartingProcesses.indexOf(app) < 0) {
20350 mPersistentStartingProcesses.add(app);
20354 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
20355 TAG_CLEANUP, "Clean-up removing on hold: " + app);
20356 mProcessesOnHold.remove(app);
20358 if (app == mHomeProcess) {
20359 mHomeProcess = null;
20361 if (app == mPreviousProcess) {
20362 mPreviousProcess = null;
20365 if (restart && !app.isolated) {
20366 // We have components that still need to be running in the
20367 // process, so re-launch it.
20369 ProcessList.remove(app.pid);
20371 addProcessNameLocked(app);
20372 app.pendingStart = false;
20373 startProcessLocked(app, "restart", app.processName);
20375 } else if (app.pid > 0 && app.pid != MY_PID) {
20378 synchronized (mPidsSelfLocked) {
20379 mPidsSelfLocked.remove(app.pid);
20380 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
20382 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
20383 if (app.isolated) {
20384 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
20391 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
20392 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20393 ContentProviderRecord cpr = mLaunchingProviders.get(i);
20394 if (cpr.launchingApp == app) {
20401 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
20402 // Look through the content providers we are waiting to have launched,
20403 // and if any run in this process then either schedule a restart of
20404 // the process or kill the client waiting for it if this process has
20406 boolean restart = false;
20407 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20408 ContentProviderRecord cpr = mLaunchingProviders.get(i);
20409 if (cpr.launchingApp == app) {
20410 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
20413 removeDyingProviderLocked(app, cpr, true);
20420 // =========================================================
20422 // =========================================================
20425 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
20426 enforceNotIsolatedCaller("getServices");
20428 final int callingUid = Binder.getCallingUid();
20429 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
20430 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
20431 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
20433 synchronized (this) {
20434 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
20435 allowed, canInteractAcrossUsers);
20440 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
20441 enforceNotIsolatedCaller("getRunningServiceControlPanel");
20442 synchronized (this) {
20443 return mServices.getRunningServiceControlPanelLocked(name);
20448 public ComponentName startService(IApplicationThread caller, Intent service,
20449 String resolvedType, boolean requireForeground, String callingPackage, int userId)
20450 throws TransactionTooLargeException {
20451 enforceNotIsolatedCaller("startService");
20452 // Refuse possible leaked file descriptors
20453 if (service != null && service.hasFileDescriptors() == true) {
20454 throw new IllegalArgumentException("File descriptors passed in Intent");
20457 if (callingPackage == null) {
20458 throw new IllegalArgumentException("callingPackage cannot be null");
20461 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20462 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
20463 synchronized(this) {
20464 final int callingPid = Binder.getCallingPid();
20465 final int callingUid = Binder.getCallingUid();
20466 final long origId = Binder.clearCallingIdentity();
20469 res = mServices.startServiceLocked(caller, service,
20470 resolvedType, callingPid, callingUid,
20471 requireForeground, callingPackage, userId);
20473 Binder.restoreCallingIdentity(origId);
20479 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
20480 boolean fgRequired, String callingPackage, int userId)
20481 throws TransactionTooLargeException {
20482 synchronized(this) {
20483 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20484 "startServiceInPackage: " + service + " type=" + resolvedType);
20485 final long origId = Binder.clearCallingIdentity();
20488 res = mServices.startServiceLocked(null, service,
20489 resolvedType, -1, uid, fgRequired, callingPackage, userId);
20491 Binder.restoreCallingIdentity(origId);
20498 public int stopService(IApplicationThread caller, Intent service,
20499 String resolvedType, int userId) {
20500 enforceNotIsolatedCaller("stopService");
20501 // Refuse possible leaked file descriptors
20502 if (service != null && service.hasFileDescriptors() == true) {
20503 throw new IllegalArgumentException("File descriptors passed in Intent");
20506 synchronized(this) {
20507 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
20512 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
20513 enforceNotIsolatedCaller("peekService");
20514 // Refuse possible leaked file descriptors
20515 if (service != null && service.hasFileDescriptors() == true) {
20516 throw new IllegalArgumentException("File descriptors passed in Intent");
20519 if (callingPackage == null) {
20520 throw new IllegalArgumentException("callingPackage cannot be null");
20523 synchronized(this) {
20524 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
20529 public boolean stopServiceToken(ComponentName className, IBinder token,
20531 synchronized(this) {
20532 return mServices.stopServiceTokenLocked(className, token, startId);
20537 public void setServiceForeground(ComponentName className, IBinder token,
20538 int id, Notification notification, int flags) {
20539 synchronized(this) {
20540 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
20545 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
20546 boolean requireFull, String name, String callerPackage) {
20547 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
20548 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
20551 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
20552 String className, int flags) {
20553 boolean result = false;
20554 // For apps that don't have pre-defined UIDs, check for permission
20555 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
20556 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20557 if (ActivityManager.checkUidPermission(
20558 INTERACT_ACROSS_USERS,
20559 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
20560 ComponentName comp = new ComponentName(aInfo.packageName, className);
20561 String msg = "Permission Denial: Component " + comp.flattenToShortString()
20562 + " requests FLAG_SINGLE_USER, but app does not hold "
20563 + INTERACT_ACROSS_USERS;
20565 throw new SecurityException(msg);
20567 // Permission passed
20570 } else if ("system".equals(componentProcessName)) {
20572 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20573 // Phone app and persistent apps are allowed to export singleuser providers.
20574 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
20575 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
20577 if (DEBUG_MU) Slog.v(TAG_MU,
20578 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
20579 + Integer.toHexString(flags) + ") = " + result);
20584 * Checks to see if the caller is in the same app as the singleton
20585 * component, or the component is in a special app. It allows special apps
20586 * to export singleton components but prevents exporting singleton
20587 * components for regular apps.
20589 boolean isValidSingletonCall(int callingUid, int componentUid) {
20590 int componentAppId = UserHandle.getAppId(componentUid);
20591 return UserHandle.isSameApp(callingUid, componentUid)
20592 || componentAppId == SYSTEM_UID
20593 || componentAppId == PHONE_UID
20594 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
20595 == PackageManager.PERMISSION_GRANTED;
20598 public int bindService(IApplicationThread caller, IBinder token, Intent service,
20599 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
20600 int userId) throws TransactionTooLargeException {
20601 enforceNotIsolatedCaller("bindService");
20603 // Refuse possible leaked file descriptors
20604 if (service != null && service.hasFileDescriptors() == true) {
20605 throw new IllegalArgumentException("File descriptors passed in Intent");
20608 if (callingPackage == null) {
20609 throw new IllegalArgumentException("callingPackage cannot be null");
20612 synchronized(this) {
20613 return mServices.bindServiceLocked(caller, token, service,
20614 resolvedType, connection, flags, callingPackage, userId);
20618 public boolean unbindService(IServiceConnection connection) {
20619 synchronized (this) {
20620 return mServices.unbindServiceLocked(connection);
20624 public void publishService(IBinder token, Intent intent, IBinder service) {
20625 // Refuse possible leaked file descriptors
20626 if (intent != null && intent.hasFileDescriptors() == true) {
20627 throw new IllegalArgumentException("File descriptors passed in Intent");
20630 synchronized(this) {
20631 if (!(token instanceof ServiceRecord)) {
20632 throw new IllegalArgumentException("Invalid service token");
20634 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
20638 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
20639 // Refuse possible leaked file descriptors
20640 if (intent != null && intent.hasFileDescriptors() == true) {
20641 throw new IllegalArgumentException("File descriptors passed in Intent");
20644 synchronized(this) {
20645 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
20649 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
20650 synchronized(this) {
20651 if (!(token instanceof ServiceRecord)) {
20652 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
20653 throw new IllegalArgumentException("Invalid service token");
20655 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
20659 // =========================================================
20660 // BACKUP AND RESTORE
20661 // =========================================================
20663 // Cause the target app to be launched if necessary and its backup agent
20664 // instantiated. The backup agent will invoke backupAgentCreated() on the
20665 // activity manager to announce its creation.
20666 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
20667 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
20668 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
20670 IPackageManager pm = AppGlobals.getPackageManager();
20671 ApplicationInfo app = null;
20673 app = pm.getApplicationInfo(packageName, STOCK_PM_FLAGS, userId);
20674 } catch (RemoteException e) {
20675 // can't happen; package manager is process-local
20678 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
20685 synchronized(this) {
20686 // !!! TODO: currently no check here that we're already bound
20687 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
20688 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20689 synchronized (stats) {
20690 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
20693 // Backup agent is now in use, its package can't be stopped.
20695 AppGlobals.getPackageManager().setPackageStoppedState(
20696 app.packageName, false, UserHandle.getUserId(app.uid));
20697 } catch (RemoteException e) {
20698 } catch (IllegalArgumentException e) {
20699 Slog.w(TAG, "Failed trying to unstop package "
20700 + app.packageName + ": " + e);
20703 BackupRecord r = new BackupRecord(ss, app, backupMode);
20704 ComponentName hostingName =
20705 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
20706 ? new ComponentName(app.packageName, app.backupAgentName)
20707 : new ComponentName("android", "FullBackupAgent");
20708 // startProcessLocked() returns existing proc's record if it's already running
20709 ProcessRecord proc = startProcessLocked(app.processName, app,
20710 false, 0, "backup", hostingName, false, false, false);
20711 if (proc == null) {
20712 Slog.e(TAG, "Unable to start backup agent process " + r);
20716 // If the app is a regular app (uid >= 10000) and not the system server or phone
20717 // process, etc, then mark it as being in full backup so that certain calls to the
20718 // process can be blocked. This is not reset to false anywhere because we kill the
20719 // process after the full backup is done and the ProcessRecord will vaporize anyway.
20720 if (UserHandle.isApp(app.uid) &&
20721 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
20722 proc.inFullBackup = true;
20725 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20726 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
20728 mBackupAppName = app.packageName;
20730 // Try not to kill the process during backup
20731 updateOomAdjLocked(proc, true);
20733 // If the process is already attached, schedule the creation of the backup agent now.
20734 // If it is not yet live, this will be done when it attaches to the framework.
20735 if (proc.thread != null) {
20736 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
20738 proc.thread.scheduleCreateBackupAgent(app,
20739 compatibilityInfoForPackageLocked(app), backupMode);
20740 } catch (RemoteException e) {
20741 // Will time out on the backup manager side
20744 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
20746 // Invariants: at this point, the target app process exists and the application
20747 // is either already running or in the process of coming up. mBackupTarget and
20748 // mBackupAppName describe the app, so that when it binds back to the AM we
20749 // know that it's scheduled for a backup-agent operation.
20752 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20753 if (oldBackupUid != -1) {
20754 js.removeBackingUpUid(oldBackupUid);
20756 if (newBackupUid != -1) {
20757 js.addBackingUpUid(newBackupUid);
20764 public void clearPendingBackup() {
20765 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
20766 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
20768 synchronized (this) {
20769 mBackupTarget = null;
20770 mBackupAppName = null;
20773 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20774 js.clearAllBackingUpUids();
20777 // A backup agent has just come up
20778 public void backupAgentCreated(String agentPackageName, IBinder agent) {
20779 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
20782 synchronized(this) {
20783 if (!agentPackageName.equals(mBackupAppName)) {
20784 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
20789 long oldIdent = Binder.clearCallingIdentity();
20791 IBackupManager bm = IBackupManager.Stub.asInterface(
20792 ServiceManager.getService(Context.BACKUP_SERVICE));
20793 bm.agentConnected(agentPackageName, agent);
20794 } catch (RemoteException e) {
20795 // can't happen; the backup manager service is local
20796 } catch (Exception e) {
20797 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
20798 e.printStackTrace();
20800 Binder.restoreCallingIdentity(oldIdent);
20804 // done with this agent
20805 public void unbindBackupAgent(ApplicationInfo appInfo) {
20806 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
20807 if (appInfo == null) {
20808 Slog.w(TAG, "unbind backup agent for null app");
20814 synchronized(this) {
20816 if (mBackupAppName == null) {
20817 Slog.w(TAG, "Unbinding backup agent with no active backup");
20821 if (!mBackupAppName.equals(appInfo.packageName)) {
20822 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
20826 // Not backing this app up any more; reset its OOM adjustment
20827 final ProcessRecord proc = mBackupTarget.app;
20828 updateOomAdjLocked(proc, true);
20829 proc.inFullBackup = false;
20831 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20833 // If the app crashed during backup, 'thread' will be null here
20834 if (proc.thread != null) {
20836 proc.thread.scheduleDestroyBackupAgent(appInfo,
20837 compatibilityInfoForPackageLocked(appInfo));
20838 } catch (Exception e) {
20839 Slog.e(TAG, "Exception when unbinding backup agent:");
20840 e.printStackTrace();
20844 mBackupTarget = null;
20845 mBackupAppName = null;
20849 if (oldBackupUid != -1) {
20850 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20851 js.removeBackingUpUid(oldBackupUid);
20855 // =========================================================
20857 // =========================================================
20859 private boolean isInstantApp(ProcessRecord record, @Nullable String callerPackage, int uid) {
20860 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
20863 // Easy case -- we have the app's ProcessRecord.
20864 if (record != null) {
20865 return record.info.isInstantApp();
20867 // Otherwise check with PackageManager.
20868 IPackageManager pm = AppGlobals.getPackageManager();
20870 if (callerPackage == null) {
20871 final String[] packageNames = pm.getPackagesForUid(uid);
20872 if (packageNames == null || packageNames.length == 0) {
20873 throw new IllegalArgumentException("Unable to determine caller package name");
20875 // Instant Apps can't use shared uids, so its safe to only check the first package.
20876 callerPackage = packageNames[0];
20878 mAppOpsService.checkPackage(uid, callerPackage);
20879 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
20880 } catch (RemoteException e) {
20881 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
20886 boolean isPendingBroadcastProcessLocked(int pid) {
20887 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20888 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
20891 void skipPendingBroadcastLocked(int pid) {
20892 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
20893 for (BroadcastQueue queue : mBroadcastQueues) {
20894 queue.skipPendingBroadcastLocked(pid);
20898 // The app just attached; send any pending broadcasts that it should receive
20899 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
20900 boolean didSomething = false;
20901 for (BroadcastQueue queue : mBroadcastQueues) {
20902 didSomething |= queue.sendPendingBroadcastsLocked(app);
20904 return didSomething;
20907 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20908 IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
20910 enforceNotIsolatedCaller("registerReceiver");
20911 ArrayList<Intent> stickyIntents = null;
20912 ProcessRecord callerApp = null;
20913 final boolean visibleToInstantApps
20914 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
20917 boolean instantApp;
20918 synchronized(this) {
20919 if (caller != null) {
20920 callerApp = getRecordForAppLocked(caller);
20921 if (callerApp == null) {
20922 throw new SecurityException(
20923 "Unable to find app for caller " + caller
20924 + " (pid=" + Binder.getCallingPid()
20925 + ") when registering receiver " + receiver);
20927 if (callerApp.info.uid != SYSTEM_UID &&
20928 !callerApp.pkgList.containsKey(callerPackage) &&
20929 !"android".equals(callerPackage)) {
20930 throw new SecurityException("Given caller package " + callerPackage
20931 + " is not running in process " + callerApp);
20933 callingUid = callerApp.info.uid;
20934 callingPid = callerApp.pid;
20936 callerPackage = null;
20937 callingUid = Binder.getCallingUid();
20938 callingPid = Binder.getCallingPid();
20941 instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20942 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20943 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
20945 Iterator<String> actions = filter.actionsIterator();
20946 if (actions == null) {
20947 ArrayList<String> noAction = new ArrayList<String>(1);
20948 noAction.add(null);
20949 actions = noAction.iterator();
20952 // Collect stickies of users
20953 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
20954 while (actions.hasNext()) {
20955 String action = actions.next();
20956 for (int id : userIds) {
20957 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
20958 if (stickies != null) {
20959 ArrayList<Intent> intents = stickies.get(action);
20960 if (intents != null) {
20961 if (stickyIntents == null) {
20962 stickyIntents = new ArrayList<Intent>();
20964 stickyIntents.addAll(intents);
20971 ArrayList<Intent> allSticky = null;
20972 if (stickyIntents != null) {
20973 final ContentResolver resolver = mContext.getContentResolver();
20974 // Look for any matching sticky broadcasts...
20975 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
20976 Intent intent = stickyIntents.get(i);
20977 // Don't provided intents that aren't available to instant apps.
20979 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
20982 // If intent has scheme "content", it will need to acccess
20983 // provider that needs to lock mProviderMap in ActivityThread
20984 // and also it may need to wait application response, so we
20985 // cannot lock ActivityManagerService here.
20986 if (filter.match(resolver, intent, true, TAG) >= 0) {
20987 if (allSticky == null) {
20988 allSticky = new ArrayList<Intent>();
20990 allSticky.add(intent);
20995 // The first sticky in the list is returned directly back to the client.
20996 Intent sticky = allSticky != null ? allSticky.get(0) : null;
20997 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
20998 if (receiver == null) {
21002 synchronized (this) {
21003 if (callerApp != null && (callerApp.thread == null
21004 || callerApp.thread.asBinder() != caller.asBinder())) {
21005 // Original caller already died
21008 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
21010 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
21012 if (rl.app != null) {
21013 final int totalReceiversForApp = rl.app.receivers.size();
21014 if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
21015 throw new IllegalStateException("Too many receivers, total of "
21016 + totalReceiversForApp + ", registered for pid: "
21017 + rl.pid + ", callerPackage: " + callerPackage);
21019 rl.app.receivers.add(rl);
21022 receiver.asBinder().linkToDeath(rl, 0);
21023 } catch (RemoteException e) {
21026 rl.linkedToDeath = true;
21028 mRegisteredReceivers.put(receiver.asBinder(), rl);
21029 } else if (rl.uid != callingUid) {
21030 throw new IllegalArgumentException(
21031 "Receiver requested to register for uid " + callingUid
21032 + " was previously registered for uid " + rl.uid
21033 + " callerPackage is " + callerPackage);
21034 } else if (rl.pid != callingPid) {
21035 throw new IllegalArgumentException(
21036 "Receiver requested to register for pid " + callingPid
21037 + " was previously registered for pid " + rl.pid
21038 + " callerPackage is " + callerPackage);
21039 } else if (rl.userId != userId) {
21040 throw new IllegalArgumentException(
21041 "Receiver requested to register for user " + userId
21042 + " was previously registered for user " + rl.userId
21043 + " callerPackage is " + callerPackage);
21045 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
21046 permission, callingUid, userId, instantApp, visibleToInstantApps);
21047 if (rl.containsFilter(filter)) {
21048 Slog.w(TAG, "Receiver with filter " + filter
21049 + " already registered for pid " + rl.pid
21050 + ", callerPackage is " + callerPackage);
21053 if (!bf.debugCheck()) {
21054 Slog.w(TAG, "==> For Dynamic broadcast");
21056 mReceiverResolver.addFilter(bf);
21059 // Enqueue broadcasts for all existing stickies that match
21061 if (allSticky != null) {
21062 ArrayList receivers = new ArrayList();
21065 final int stickyCount = allSticky.size();
21066 for (int i = 0; i < stickyCount; i++) {
21067 Intent intent = allSticky.get(i);
21068 BroadcastQueue queue = broadcastQueueForIntent(intent);
21069 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
21070 null, -1, -1, false, null, null, OP_NONE, null, receivers,
21071 null, 0, null, null, false, true, true, -1);
21072 queue.enqueueParallelBroadcastLocked(r);
21073 queue.scheduleBroadcastsLocked();
21081 public void unregisterReceiver(IIntentReceiver receiver) {
21082 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
21084 final long origId = Binder.clearCallingIdentity();
21086 boolean doTrim = false;
21088 synchronized(this) {
21089 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
21091 final BroadcastRecord r = rl.curBroadcast;
21092 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
21093 final boolean doNext = r.queue.finishReceiverLocked(
21094 r, r.resultCode, r.resultData, r.resultExtras,
21095 r.resultAbort, false);
21098 r.queue.processNextBroadcast(false);
21102 if (rl.app != null) {
21103 rl.app.receivers.remove(rl);
21105 removeReceiverLocked(rl);
21106 if (rl.linkedToDeath) {
21107 rl.linkedToDeath = false;
21108 rl.receiver.asBinder().unlinkToDeath(rl, 0);
21113 // If we actually concluded any broadcasts, we might now be able
21114 // to trim the recipients' apps from our working set
21116 trimApplications();
21121 Binder.restoreCallingIdentity(origId);
21125 void removeReceiverLocked(ReceiverList rl) {
21126 mRegisteredReceivers.remove(rl.receiver.asBinder());
21127 for (int i = rl.size() - 1; i >= 0; i--) {
21128 mReceiverResolver.removeFilter(rl.get(i));
21132 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
21133 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21134 ProcessRecord r = mLruProcesses.get(i);
21135 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
21137 r.thread.dispatchPackageBroadcast(cmd, packages);
21138 } catch (RemoteException ex) {
21144 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
21145 int callingUid, int[] users) {
21146 // TODO: come back and remove this assumption to triage all broadcasts
21147 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
21149 List<ResolveInfo> receivers = null;
21151 HashSet<ComponentName> singleUserReceivers = null;
21152 boolean scannedFirstReceivers = false;
21153 for (int user : users) {
21154 // Skip users that have Shell restrictions, with exception of always permitted
21155 // Shell broadcasts
21156 if (callingUid == SHELL_UID
21157 && mUserController.hasUserRestriction(
21158 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
21159 && !isPermittedShellBroadcast(intent)) {
21162 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
21163 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
21164 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
21165 // If this is not the system user, we need to check for
21166 // any receivers that should be filtered out.
21167 for (int i=0; i<newReceivers.size(); i++) {
21168 ResolveInfo ri = newReceivers.get(i);
21169 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
21170 newReceivers.remove(i);
21175 if (newReceivers != null && newReceivers.size() == 0) {
21176 newReceivers = null;
21178 if (receivers == null) {
21179 receivers = newReceivers;
21180 } else if (newReceivers != null) {
21181 // We need to concatenate the additional receivers
21182 // found with what we have do far. This would be easy,
21183 // but we also need to de-dup any receivers that are
21185 if (!scannedFirstReceivers) {
21186 // Collect any single user receivers we had already retrieved.
21187 scannedFirstReceivers = true;
21188 for (int i=0; i<receivers.size(); i++) {
21189 ResolveInfo ri = receivers.get(i);
21190 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
21191 ComponentName cn = new ComponentName(
21192 ri.activityInfo.packageName, ri.activityInfo.name);
21193 if (singleUserReceivers == null) {
21194 singleUserReceivers = new HashSet<ComponentName>();
21196 singleUserReceivers.add(cn);
21200 // Add the new results to the existing results, tracking
21201 // and de-dupping single user receivers.
21202 for (int i=0; i<newReceivers.size(); i++) {
21203 ResolveInfo ri = newReceivers.get(i);
21204 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
21205 ComponentName cn = new ComponentName(
21206 ri.activityInfo.packageName, ri.activityInfo.name);
21207 if (singleUserReceivers == null) {
21208 singleUserReceivers = new HashSet<ComponentName>();
21210 if (!singleUserReceivers.contains(cn)) {
21211 singleUserReceivers.add(cn);
21220 } catch (RemoteException ex) {
21221 // pm is in same process, this will never happen.
21226 private boolean isPermittedShellBroadcast(Intent intent) {
21227 // remote bugreport should always be allowed to be taken
21228 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
21231 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
21232 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
21233 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21234 // Don't yell about broadcasts sent via shell
21238 final String action = intent.getAction();
21239 if (isProtectedBroadcast
21240 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
21241 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
21242 || Intent.ACTION_MEDIA_BUTTON.equals(action)
21243 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
21244 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
21245 || Intent.ACTION_MASTER_CLEAR.equals(action)
21246 || Intent.ACTION_FACTORY_RESET.equals(action)
21247 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
21248 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
21249 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
21250 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
21251 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
21252 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
21253 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
21254 // Broadcast is either protected, or it's a public action that
21255 // we've relaxed, so it's fine for system internals to send.
21259 // This broadcast may be a problem... but there are often system components that
21260 // want to send an internal broadcast to themselves, which is annoying to have to
21261 // explicitly list each action as a protected broadcast, so we will check for that
21262 // one safe case and allow it: an explicit broadcast, only being received by something
21263 // that has protected itself.
21264 if (intent.getPackage() != null || intent.getComponent() != null) {
21265 if (receivers == null || receivers.size() == 0) {
21266 // Intent is explicit and there's no receivers.
21267 // This happens, e.g. , when a system component sends a broadcast to
21268 // its own runtime receiver, and there's no manifest receivers for it,
21269 // because this method is called twice for each broadcast,
21270 // for runtime receivers and manifest receivers and the later check would find
21274 boolean allProtected = true;
21275 for (int i = receivers.size()-1; i >= 0; i--) {
21276 Object target = receivers.get(i);
21277 if (target instanceof ResolveInfo) {
21278 ResolveInfo ri = (ResolveInfo)target;
21279 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
21280 allProtected = false;
21284 BroadcastFilter bf = (BroadcastFilter)target;
21285 if (bf.requiredPermission == null) {
21286 allProtected = false;
21291 if (allProtected) {
21297 // The vast majority of broadcasts sent from system internals
21298 // should be protected to avoid security holes, so yell loudly
21299 // to ensure we examine these cases.
21300 if (callerApp != null) {
21301 Log.wtf(TAG, "Sending non-protected broadcast " + action
21302 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
21305 Log.wtf(TAG, "Sending non-protected broadcast " + action
21306 + " from system uid " + UserHandle.formatUid(callingUid)
21307 + " pkg " + callerPackage,
21313 final int broadcastIntentLocked(ProcessRecord callerApp,
21314 String callerPackage, Intent intent, String resolvedType,
21315 IIntentReceiver resultTo, int resultCode, String resultData,
21316 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
21317 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
21318 intent = new Intent(intent);
21320 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
21321 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
21322 if (callerInstantApp) {
21323 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21326 // By default broadcasts do not go to stopped apps.
21327 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
21329 // If we have not finished booting, don't allow this to launch new processes.
21330 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
21331 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21334 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
21335 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
21336 + " ordered=" + ordered + " userid=" + userId);
21337 if ((resultTo != null) && !ordered) {
21338 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
21341 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
21342 ALLOW_NON_FULL, "broadcast", callerPackage);
21344 // Make sure that the user who is receiving this broadcast or its parent is running.
21345 // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
21346 if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
21347 if ((callingUid != SYSTEM_UID
21348 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
21349 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
21350 Slog.w(TAG, "Skipping broadcast of " + intent
21351 + ": user " + userId + " and its parent (if any) are stopped");
21352 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
21356 final String action = intent.getAction();
21357 BroadcastOptions brOptions = null;
21358 if (bOptions != null) {
21359 brOptions = new BroadcastOptions(bOptions);
21360 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
21361 // See if the caller is allowed to do this. Note we are checking against
21362 // the actual real caller (not whoever provided the operation as say a
21363 // PendingIntent), because that who is actually supplied the arguments.
21364 if (checkComponentPermission(
21365 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
21366 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
21367 != PackageManager.PERMISSION_GRANTED) {
21368 String msg = "Permission Denial: " + intent.getAction()
21369 + " broadcast from " + callerPackage + " (pid=" + callingPid
21370 + ", uid=" + callingUid + ")"
21372 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21374 throw new SecurityException(msg);
21377 if (brOptions.isDontSendToRestrictedApps()
21378 && !isUidActiveLocked(callingUid)
21379 && isBackgroundRestrictedNoCheck(callingUid, callerPackage)) {
21380 Slog.i(TAG, "Not sending broadcast " + action + " - app " + callerPackage
21381 + " has background restrictions");
21382 return ActivityManager.START_CANCELED;
21386 // Verify that protected broadcasts are only being sent by system code,
21387 // and that system code is only sending protected broadcasts.
21388 final boolean isProtectedBroadcast;
21390 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
21391 } catch (RemoteException e) {
21392 Slog.w(TAG, "Remote exception", e);
21393 return ActivityManager.BROADCAST_SUCCESS;
21396 final boolean isCallerSystem;
21397 switch (UserHandle.getAppId(callingUid)) {
21401 case BLUETOOTH_UID:
21404 isCallerSystem = true;
21407 isCallerSystem = (callerApp != null) && callerApp.persistent;
21411 // First line security check before anything else: stop non-system apps from
21412 // sending protected broadcasts.
21413 if (!isCallerSystem) {
21414 if (isProtectedBroadcast) {
21415 String msg = "Permission Denial: not allowed to send broadcast "
21416 + action + " from pid="
21417 + callingPid + ", uid=" + callingUid;
21419 throw new SecurityException(msg);
21421 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
21422 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
21423 // Special case for compatibility: we don't want apps to send this,
21424 // but historically it has not been protected and apps may be using it
21425 // to poke their own app widget. So, instead of making it protected,
21426 // just limit it to the caller.
21427 if (callerPackage == null) {
21428 String msg = "Permission Denial: not allowed to send broadcast "
21429 + action + " from unknown caller.";
21431 throw new SecurityException(msg);
21432 } else if (intent.getComponent() != null) {
21433 // They are good enough to send to an explicit component... verify
21434 // it is being sent to the calling app.
21435 if (!intent.getComponent().getPackageName().equals(
21437 String msg = "Permission Denial: not allowed to send broadcast "
21439 + intent.getComponent().getPackageName() + " from "
21442 throw new SecurityException(msg);
21445 // Limit broadcast to their own package.
21446 intent.setPackage(callerPackage);
21451 if (action != null) {
21452 if (getBackgroundLaunchBroadcasts().contains(action)) {
21453 if (DEBUG_BACKGROUND_CHECK) {
21454 Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
21456 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
21460 case Intent.ACTION_UID_REMOVED:
21461 case Intent.ACTION_PACKAGE_REMOVED:
21462 case Intent.ACTION_PACKAGE_CHANGED:
21463 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21464 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21465 case Intent.ACTION_PACKAGES_SUSPENDED:
21466 case Intent.ACTION_PACKAGES_UNSUSPENDED:
21467 // Handle special intents: if this broadcast is from the package
21468 // manager about a package being removed, we need to remove all of
21469 // its activities from the history stack.
21470 if (checkComponentPermission(
21471 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
21472 callingPid, callingUid, -1, true)
21473 != PackageManager.PERMISSION_GRANTED) {
21474 String msg = "Permission Denial: " + intent.getAction()
21475 + " broadcast from " + callerPackage + " (pid=" + callingPid
21476 + ", uid=" + callingUid + ")"
21478 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
21480 throw new SecurityException(msg);
21483 case Intent.ACTION_UID_REMOVED:
21484 final int uid = getUidFromIntent(intent);
21486 mBatteryStatsService.removeUid(uid);
21487 mAppOpsService.uidRemoved(uid);
21490 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21491 // If resources are unavailable just force stop all those packages
21492 // and flush the attribute cache as well.
21494 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21495 if (list != null && list.length > 0) {
21496 for (int i = 0; i < list.length; i++) {
21497 forceStopPackageLocked(list[i], -1, false, true, true,
21498 false, false, userId, "storage unmount");
21500 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21501 sendPackageBroadcastLocked(
21502 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
21506 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21507 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21509 case Intent.ACTION_PACKAGE_REMOVED:
21510 case Intent.ACTION_PACKAGE_CHANGED:
21511 Uri data = intent.getData();
21513 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
21514 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
21515 final boolean replacing =
21516 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21517 final boolean killProcess =
21518 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
21519 final boolean fullUninstall = removed && !replacing;
21522 forceStopPackageLocked(ssp, UserHandle.getAppId(
21523 intent.getIntExtra(Intent.EXTRA_UID, -1)),
21524 false, true, true, false, fullUninstall, userId,
21525 removed ? "pkg removed" : "pkg changed");
21527 final int cmd = killProcess
21528 ? ApplicationThreadConstants.PACKAGE_REMOVED
21529 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
21530 sendPackageBroadcastLocked(cmd,
21531 new String[] {ssp}, userId);
21532 if (fullUninstall) {
21533 mAppOpsService.packageRemoved(
21534 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
21536 // Remove all permissions granted from/to this package
21537 removeUriPermissionsForPackageLocked(ssp, userId, true,
21540 mRecentTasks.removeTasksByPackageName(ssp, userId);
21542 mServices.forceStopPackageLocked(ssp, userId);
21543 mAppWarnings.onPackageUninstalled(ssp);
21544 mCompatModePackages.handlePackageUninstalledLocked(ssp);
21545 mBatteryStatsService.notePackageUninstalled(ssp);
21549 killPackageProcessesLocked(ssp, UserHandle.getAppId(
21550 intent.getIntExtra(Intent.EXTRA_UID, -1)),
21551 userId, ProcessList.INVALID_ADJ,
21552 false, true, true, false, "change " + ssp);
21554 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
21555 intent.getStringArrayExtra(
21556 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
21560 case Intent.ACTION_PACKAGES_SUSPENDED:
21561 case Intent.ACTION_PACKAGES_UNSUSPENDED:
21562 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
21563 intent.getAction());
21564 final String[] packageNames = intent.getStringArrayExtra(
21565 Intent.EXTRA_CHANGED_PACKAGE_LIST);
21566 final int userHandle = intent.getIntExtra(
21567 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
21569 synchronized(ActivityManagerService.this) {
21570 mRecentTasks.onPackagesSuspendedChanged(
21571 packageNames, suspended, userHandle);
21576 case Intent.ACTION_PACKAGE_REPLACED:
21578 final Uri data = intent.getData();
21580 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21581 ApplicationInfo aInfo = null;
21583 aInfo = AppGlobals.getPackageManager()
21584 .getApplicationInfo(ssp, STOCK_PM_FLAGS, userId);
21585 } catch (RemoteException ignore) {}
21586 if (aInfo == null) {
21587 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
21588 + " ssp=" + ssp + " data=" + data);
21589 return ActivityManager.BROADCAST_SUCCESS;
21591 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
21592 mServices.updateServiceApplicationInfoLocked(aInfo);
21593 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
21594 new String[] {ssp}, userId);
21598 case Intent.ACTION_PACKAGE_ADDED:
21600 // Special case for adding a package: by default turn on compatibility mode.
21601 Uri data = intent.getData();
21603 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21604 final boolean replacing =
21605 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21606 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
21609 ApplicationInfo ai = AppGlobals.getPackageManager().
21610 getApplicationInfo(ssp, STOCK_PM_FLAGS, 0);
21611 mBatteryStatsService.notePackageInstalled(ssp,
21612 ai != null ? ai.versionCode : 0);
21613 } catch (RemoteException e) {
21618 case Intent.ACTION_PACKAGE_DATA_CLEARED:
21620 Uri data = intent.getData();
21622 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21623 mCompatModePackages.handlePackageDataClearedLocked(ssp);
21624 mAppWarnings.onPackageDataCleared(ssp);
21628 case Intent.ACTION_TIMEZONE_CHANGED:
21629 // If this is the time zone changed action, queue up a message that will reset
21630 // the timezone of all currently running processes. This message will get
21631 // queued up before the broadcast happens.
21632 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
21634 case Intent.ACTION_TIME_CHANGED:
21635 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
21636 // the tri-state value it may contain and "unknown".
21637 // For convenience we re-use the Intent extra values.
21638 final int NO_EXTRA_VALUE_FOUND = -1;
21639 final int timeFormatPreferenceMsgValue = intent.getIntExtra(
21640 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
21641 NO_EXTRA_VALUE_FOUND /* defaultValue */);
21642 // Only send a message if the time preference is available.
21643 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
21644 Message updateTimePreferenceMsg =
21645 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
21646 timeFormatPreferenceMsgValue, 0);
21647 mHandler.sendMessage(updateTimePreferenceMsg);
21649 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21650 synchronized (stats) {
21651 stats.noteCurrentTimeChangedLocked();
21654 case Intent.ACTION_CLEAR_DNS_CACHE:
21655 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
21657 case Proxy.PROXY_CHANGE_ACTION:
21658 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
21659 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
21661 case android.hardware.Camera.ACTION_NEW_PICTURE:
21662 case android.hardware.Camera.ACTION_NEW_VIDEO:
21663 // In N we just turned these off; in O we are turing them back on partly,
21664 // only for registered receivers. This will still address the main problem
21665 // (a spam of apps waking up when a picture is taken putting significant
21666 // memory pressure on the system at a bad point), while still allowing apps
21667 // that are already actively running to know about this happening.
21668 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21670 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
21671 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
21673 case "com.android.launcher.action.INSTALL_SHORTCUT":
21674 // As of O, we no longer support this broadcasts, even for pre-O apps.
21675 // Apps should now be using ShortcutManager.pinRequestShortcut().
21676 Log.w(TAG, "Broadcast " + action
21677 + " no longer supported. It will not be delivered.");
21678 return ActivityManager.BROADCAST_SUCCESS;
21681 if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
21682 Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
21683 Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
21684 final int uid = getUidFromIntent(intent);
21686 final UidRecord uidRec = mActiveUids.get(uid);
21687 if (uidRec != null) {
21688 uidRec.updateHasInternetPermission();
21694 // Add to the sticky list if requested.
21696 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
21697 callingPid, callingUid)
21698 != PackageManager.PERMISSION_GRANTED) {
21699 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
21700 + callingPid + ", uid=" + callingUid
21701 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21703 throw new SecurityException(msg);
21705 if (requiredPermissions != null && requiredPermissions.length > 0) {
21706 Slog.w(TAG, "Can't broadcast sticky intent " + intent
21707 + " and enforce permissions " + Arrays.toString(requiredPermissions));
21708 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
21710 if (intent.getComponent() != null) {
21711 throw new SecurityException(
21712 "Sticky broadcasts can't target a specific component");
21714 // We use userId directly here, since the "all" target is maintained
21715 // as a separate set of sticky broadcasts.
21716 if (userId != UserHandle.USER_ALL) {
21717 // But first, if this is not a broadcast to all users, then
21718 // make sure it doesn't conflict with an existing broadcast to
21720 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
21721 UserHandle.USER_ALL);
21722 if (stickies != null) {
21723 ArrayList<Intent> list = stickies.get(intent.getAction());
21724 if (list != null) {
21725 int N = list.size();
21727 for (i=0; i<N; i++) {
21728 if (intent.filterEquals(list.get(i))) {
21729 throw new IllegalArgumentException(
21730 "Sticky broadcast " + intent + " for user "
21731 + userId + " conflicts with existing global broadcast");
21737 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21738 if (stickies == null) {
21739 stickies = new ArrayMap<>();
21740 mStickyBroadcasts.put(userId, stickies);
21742 ArrayList<Intent> list = stickies.get(intent.getAction());
21743 if (list == null) {
21744 list = new ArrayList<>();
21745 stickies.put(intent.getAction(), list);
21747 final int stickiesCount = list.size();
21749 for (i = 0; i < stickiesCount; i++) {
21750 if (intent.filterEquals(list.get(i))) {
21751 // This sticky already exists, replace it.
21752 list.set(i, new Intent(intent));
21756 if (i >= stickiesCount) {
21757 list.add(new Intent(intent));
21762 if (userId == UserHandle.USER_ALL) {
21763 // Caller wants broadcast to go to all started users.
21764 users = mUserController.getStartedUserArray();
21766 // Caller wants broadcast to go to one specific user.
21767 users = new int[] {userId};
21770 // Figure out who all will receive this broadcast.
21771 List receivers = null;
21772 List<BroadcastFilter> registeredReceivers = null;
21773 // Need to resolve the intent to interested receivers...
21774 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
21776 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
21778 if (intent.getComponent() == null) {
21779 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
21780 // Query one target user at a time, excluding shell-restricted users
21781 for (int i = 0; i < users.length; i++) {
21782 if (mUserController.hasUserRestriction(
21783 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
21786 List<BroadcastFilter> registeredReceiversForUser =
21787 mReceiverResolver.queryIntent(intent,
21788 resolvedType, false /*defaultOnly*/, users[i]);
21789 if (registeredReceivers == null) {
21790 registeredReceivers = registeredReceiversForUser;
21791 } else if (registeredReceiversForUser != null) {
21792 registeredReceivers.addAll(registeredReceiversForUser);
21796 registeredReceivers = mReceiverResolver.queryIntent(intent,
21797 resolvedType, false /*defaultOnly*/, userId);
21801 final boolean replacePending =
21802 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
21804 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
21805 + " replacePending=" + replacePending);
21807 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
21808 if (!ordered && NR > 0) {
21809 // If we are not serializing this broadcast, then send the
21810 // registered receivers separately so they don't wait for the
21811 // components to be launched.
21812 if (isCallerSystem) {
21813 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21814 isProtectedBroadcast, registeredReceivers);
21816 final BroadcastQueue queue = broadcastQueueForIntent(intent);
21817 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21818 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21819 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
21820 resultCode, resultData, resultExtras, ordered, sticky, false, userId);
21821 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
21822 final boolean replaced = replacePending
21823 && (queue.replaceParallelBroadcastLocked(r) != null);
21824 // Note: We assume resultTo is null for non-ordered broadcasts.
21826 queue.enqueueParallelBroadcastLocked(r);
21827 queue.scheduleBroadcastsLocked();
21829 registeredReceivers = null;
21833 // Merge into one list.
21835 if (receivers != null) {
21836 // A special case for PACKAGE_ADDED: do not allow the package
21837 // being added to see this broadcast. This prevents them from
21838 // using this as a back door to get run as soon as they are
21839 // installed. Maybe in the future we want to have a special install
21840 // broadcast or such for apps, but we'd like to deliberately make
21842 String skipPackages[] = null;
21843 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
21844 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
21845 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
21846 Uri data = intent.getData();
21847 if (data != null) {
21848 String pkgName = data.getSchemeSpecificPart();
21849 if (pkgName != null) {
21850 skipPackages = new String[] { pkgName };
21853 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
21854 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21856 if (skipPackages != null && (skipPackages.length > 0)) {
21857 for (String skipPackage : skipPackages) {
21858 if (skipPackage != null) {
21859 int NT = receivers.size();
21860 for (int it=0; it<NT; it++) {
21861 ResolveInfo curt = (ResolveInfo)receivers.get(it);
21862 if (curt.activityInfo.packageName.equals(skipPackage)) {
21863 receivers.remove(it);
21872 int NT = receivers != null ? receivers.size() : 0;
21874 ResolveInfo curt = null;
21875 BroadcastFilter curr = null;
21876 while (it < NT && ir < NR) {
21877 if (curt == null) {
21878 curt = (ResolveInfo)receivers.get(it);
21880 if (curr == null) {
21881 curr = registeredReceivers.get(ir);
21883 if (curr.getPriority() >= curt.priority) {
21884 // Insert this broadcast record into the final list.
21885 receivers.add(it, curr);
21891 // Skip to the next ResolveInfo in the final list.
21898 if (receivers == null) {
21899 receivers = new ArrayList();
21901 receivers.add(registeredReceivers.get(ir));
21905 if (isCallerSystem) {
21906 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21907 isProtectedBroadcast, receivers);
21910 if ((receivers != null && receivers.size() > 0)
21911 || resultTo != null) {
21912 BroadcastQueue queue = broadcastQueueForIntent(intent);
21913 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21914 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21915 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
21916 resultData, resultExtras, ordered, sticky, false, userId);
21918 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
21919 + ": prev had " + queue.mOrderedBroadcasts.size());
21920 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
21921 "Enqueueing broadcast " + r.intent.getAction());
21923 final BroadcastRecord oldRecord =
21924 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
21925 if (oldRecord != null) {
21926 // Replaced, fire the result-to receiver.
21927 if (oldRecord.resultTo != null) {
21928 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
21930 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
21932 Activity.RESULT_CANCELED, null, null,
21933 false, false, oldRecord.userId);
21934 } catch (RemoteException e) {
21935 Slog.w(TAG, "Failure ["
21936 + queue.mQueueName + "] sending broadcast result of "
21942 queue.enqueueOrderedBroadcastLocked(r);
21943 queue.scheduleBroadcastsLocked();
21946 // There was nobody interested in the broadcast, but we still want to record
21947 // that it happened.
21948 if (intent.getComponent() == null && intent.getPackage() == null
21949 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21950 // This was an implicit broadcast... let's record it for posterity.
21951 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
21955 return ActivityManager.BROADCAST_SUCCESS;
21959 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21961 private int getUidFromIntent(Intent intent) {
21962 if (intent == null) {
21965 final Bundle intentExtras = intent.getExtras();
21966 return intent.hasExtra(Intent.EXTRA_UID)
21967 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
21970 final void rotateBroadcastStatsIfNeededLocked() {
21971 final long now = SystemClock.elapsedRealtime();
21972 if (mCurBroadcastStats == null ||
21973 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
21974 mLastBroadcastStats = mCurBroadcastStats;
21975 if (mLastBroadcastStats != null) {
21976 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
21977 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
21979 mCurBroadcastStats = new BroadcastStats();
21983 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
21984 int skipCount, long dispatchTime) {
21985 rotateBroadcastStatsIfNeededLocked();
21986 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
21989 final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21990 rotateBroadcastStatsIfNeededLocked();
21991 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
21994 final Intent verifyBroadcastLocked(Intent intent) {
21995 // Refuse possible leaked file descriptors
21996 if (intent != null && intent.hasFileDescriptors() == true) {
21997 throw new IllegalArgumentException("File descriptors passed in Intent");
22000 int flags = intent.getFlags();
22002 if (!mProcessesReady) {
22003 // if the caller really truly claims to know what they're doing, go
22004 // ahead and allow the broadcast without launching any receivers
22005 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
22006 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
22007 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
22008 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
22009 + " before boot completion");
22010 throw new IllegalStateException("Cannot broadcast before boot completed");
22014 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
22015 throw new IllegalArgumentException(
22016 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
22019 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
22020 switch (Binder.getCallingUid()) {
22025 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
22026 + Binder.getCallingUid());
22027 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
22035 public final int broadcastIntent(IApplicationThread caller,
22036 Intent intent, String resolvedType, IIntentReceiver resultTo,
22037 int resultCode, String resultData, Bundle resultExtras,
22038 String[] requiredPermissions, int appOp, Bundle bOptions,
22039 boolean serialized, boolean sticky, int userId) {
22040 enforceNotIsolatedCaller("broadcastIntent");
22041 synchronized(this) {
22042 intent = verifyBroadcastLocked(intent);
22044 final ProcessRecord callerApp = getRecordForAppLocked(caller);
22045 final int callingPid = Binder.getCallingPid();
22046 final int callingUid = Binder.getCallingUid();
22047 final long origId = Binder.clearCallingIdentity();
22048 int res = broadcastIntentLocked(callerApp,
22049 callerApp != null ? callerApp.info.packageName : null,
22050 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
22051 requiredPermissions, appOp, bOptions, serialized, sticky,
22052 callingPid, callingUid, userId);
22053 Binder.restoreCallingIdentity(origId);
22059 int broadcastIntentInPackage(String packageName, int uid,
22060 Intent intent, String resolvedType, IIntentReceiver resultTo,
22061 int resultCode, String resultData, Bundle resultExtras,
22062 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
22064 synchronized(this) {
22065 intent = verifyBroadcastLocked(intent);
22067 final long origId = Binder.clearCallingIdentity();
22068 String[] requiredPermissions = requiredPermission == null ? null
22069 : new String[] {requiredPermission};
22070 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
22071 resultTo, resultCode, resultData, resultExtras,
22072 requiredPermissions, OP_NONE, bOptions, serialized,
22073 sticky, -1, uid, userId);
22074 Binder.restoreCallingIdentity(origId);
22079 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
22080 // Refuse possible leaked file descriptors
22081 if (intent != null && intent.hasFileDescriptors() == true) {
22082 throw new IllegalArgumentException("File descriptors passed in Intent");
22085 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22086 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
22088 synchronized(this) {
22089 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
22090 != PackageManager.PERMISSION_GRANTED) {
22091 String msg = "Permission Denial: unbroadcastIntent() from pid="
22092 + Binder.getCallingPid()
22093 + ", uid=" + Binder.getCallingUid()
22094 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
22096 throw new SecurityException(msg);
22098 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
22099 if (stickies != null) {
22100 ArrayList<Intent> list = stickies.get(intent.getAction());
22101 if (list != null) {
22102 int N = list.size();
22104 for (i=0; i<N; i++) {
22105 if (intent.filterEquals(list.get(i))) {
22110 if (list.size() <= 0) {
22111 stickies.remove(intent.getAction());
22114 if (stickies.size() <= 0) {
22115 mStickyBroadcasts.remove(userId);
22121 void backgroundServicesFinishedLocked(int userId) {
22122 for (BroadcastQueue queue : mBroadcastQueues) {
22123 queue.backgroundServicesFinishedLocked(userId);
22127 public void finishReceiver(IBinder who, int resultCode, String resultData,
22128 Bundle resultExtras, boolean resultAbort, int flags) {
22129 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
22131 // Refuse possible leaked file descriptors
22132 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
22133 throw new IllegalArgumentException("File descriptors passed in Bundle");
22136 final long origId = Binder.clearCallingIdentity();
22138 boolean doNext = false;
22141 synchronized(this) {
22142 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
22143 ? mFgBroadcastQueue : mBgBroadcastQueue;
22144 r = queue.getMatchingOrderedReceiver(who);
22146 doNext = r.queue.finishReceiverLocked(r, resultCode,
22147 resultData, resultExtras, resultAbort, true);
22150 r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
22152 // updateOomAdjLocked() will be done here
22153 trimApplicationsLocked();
22157 Binder.restoreCallingIdentity(origId);
22161 // =========================================================
22163 // =========================================================
22165 public boolean startInstrumentation(ComponentName className,
22166 String profileFile, int flags, Bundle arguments,
22167 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
22168 int userId, String abiOverride) {
22169 enforceNotIsolatedCaller("startInstrumentation");
22170 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22171 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
22172 // Refuse possible leaked file descriptors
22173 if (arguments != null && arguments.hasFileDescriptors()) {
22174 throw new IllegalArgumentException("File descriptors passed in Bundle");
22177 synchronized(this) {
22178 InstrumentationInfo ii = null;
22179 ApplicationInfo ai = null;
22181 ii = mContext.getPackageManager().getInstrumentationInfo(
22182 className, STOCK_PM_FLAGS);
22183 ai = AppGlobals.getPackageManager().getApplicationInfo(
22184 ii.targetPackage, STOCK_PM_FLAGS, userId);
22185 } catch (PackageManager.NameNotFoundException e) {
22186 } catch (RemoteException e) {
22189 reportStartInstrumentationFailureLocked(watcher, className,
22190 "Unable to find instrumentation info for: " + className);
22194 reportStartInstrumentationFailureLocked(watcher, className,
22195 "Unable to find instrumentation target package: " + ii.targetPackage);
22198 if (!ai.hasCode()) {
22199 reportStartInstrumentationFailureLocked(watcher, className,
22200 "Instrumentation target has no code: " + ii.targetPackage);
22204 int match = mContext.getPackageManager().checkSignatures(
22205 ii.targetPackage, ii.packageName);
22206 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
22207 String msg = "Permission Denial: starting instrumentation "
22208 + className + " from pid="
22209 + Binder.getCallingPid()
22210 + ", uid=" + Binder.getCallingPid()
22211 + " not allowed because package " + ii.packageName
22212 + " does not have a signature matching the target "
22213 + ii.targetPackage;
22214 reportStartInstrumentationFailureLocked(watcher, className, msg);
22215 throw new SecurityException(msg);
22218 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
22219 activeInstr.mClass = className;
22220 String defProcess = ai.processName;;
22221 if (ii.targetProcesses == null) {
22222 activeInstr.mTargetProcesses = new String[]{ai.processName};
22223 } else if (ii.targetProcesses.equals("*")) {
22224 activeInstr.mTargetProcesses = new String[0];
22226 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
22227 defProcess = activeInstr.mTargetProcesses[0];
22229 activeInstr.mTargetInfo = ai;
22230 activeInstr.mProfileFile = profileFile;
22231 activeInstr.mArguments = arguments;
22232 activeInstr.mWatcher = watcher;
22233 activeInstr.mUiAutomationConnection = uiAutomationConnection;
22234 activeInstr.mResultClass = className;
22236 boolean disableHiddenApiChecks =
22237 (flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
22238 if (disableHiddenApiChecks) {
22239 enforceCallingPermission(android.Manifest.permission.DISABLE_HIDDEN_API_CHECKS,
22240 "disable hidden API checks");
22243 final long origId = Binder.clearCallingIdentity();
22244 // Instrumentation can kill and relaunch even persistent processes
22245 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
22247 // Inform usage stats to make the target package active
22248 if (mUsageStatsService != null) {
22249 mUsageStatsService.reportEvent(ii.targetPackage, userId,
22250 UsageEvents.Event.SYSTEM_INTERACTION);
22253 ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
22255 app.instr = activeInstr;
22256 activeInstr.mFinished = false;
22257 activeInstr.mRunningProcesses.add(app);
22258 if (!mActiveInstrumentation.contains(activeInstr)) {
22259 mActiveInstrumentation.add(activeInstr);
22261 Binder.restoreCallingIdentity(origId);
22268 * Report errors that occur while attempting to start Instrumentation. Always writes the
22269 * error to the logs, but if somebody is watching, send the report there too. This enables
22270 * the "am" command to report errors with more information.
22272 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
22273 * @param cn The component name of the instrumentation.
22274 * @param report The error report.
22276 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
22277 ComponentName cn, String report) {
22278 Slog.w(TAG, report);
22279 if (watcher != null) {
22280 Bundle results = new Bundle();
22281 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
22282 results.putString("Error", report);
22283 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
22287 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
22288 if (app.instr == null) {
22289 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
22293 if (!app.instr.mFinished && results != null) {
22294 if (app.instr.mCurResults == null) {
22295 app.instr.mCurResults = new Bundle(results);
22297 app.instr.mCurResults.putAll(results);
22302 public void addInstrumentationResults(IApplicationThread target, Bundle results) {
22303 int userId = UserHandle.getCallingUserId();
22304 // Refuse possible leaked file descriptors
22305 if (results != null && results.hasFileDescriptors()) {
22306 throw new IllegalArgumentException("File descriptors passed in Intent");
22309 synchronized(this) {
22310 ProcessRecord app = getRecordForAppLocked(target);
22312 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
22315 final long origId = Binder.clearCallingIdentity();
22316 addInstrumentationResultsLocked(app, results);
22317 Binder.restoreCallingIdentity(origId);
22322 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
22323 if (app.instr == null) {
22324 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
22328 if (!app.instr.mFinished) {
22329 if (app.instr.mWatcher != null) {
22330 Bundle finalResults = app.instr.mCurResults;
22331 if (finalResults != null) {
22332 if (app.instr.mCurResults != null && results != null) {
22333 finalResults.putAll(results);
22336 finalResults = results;
22338 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
22339 app.instr.mClass, resultCode, finalResults);
22342 // Can't call out of the system process with a lock held, so post a message.
22343 if (app.instr.mUiAutomationConnection != null) {
22344 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
22345 app.instr.mUiAutomationConnection).sendToTarget();
22347 app.instr.mFinished = true;
22350 app.instr.removeProcess(app);
22353 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
22357 public void finishInstrumentation(IApplicationThread target,
22358 int resultCode, Bundle results) {
22359 int userId = UserHandle.getCallingUserId();
22360 // Refuse possible leaked file descriptors
22361 if (results != null && results.hasFileDescriptors()) {
22362 throw new IllegalArgumentException("File descriptors passed in Intent");
22365 synchronized(this) {
22366 ProcessRecord app = getRecordForAppLocked(target);
22368 Slog.w(TAG, "finishInstrumentation: no app for " + target);
22371 final long origId = Binder.clearCallingIdentity();
22372 finishInstrumentationLocked(app, resultCode, results);
22373 Binder.restoreCallingIdentity(origId);
22377 // =========================================================
22379 // =========================================================
22381 public ConfigurationInfo getDeviceConfigurationInfo() {
22382 ConfigurationInfo config = new ConfigurationInfo();
22383 synchronized (this) {
22384 final Configuration globalConfig = getGlobalConfiguration();
22385 config.reqTouchScreen = globalConfig.touchscreen;
22386 config.reqKeyboardType = globalConfig.keyboard;
22387 config.reqNavigation = globalConfig.navigation;
22388 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
22389 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
22390 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
22392 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
22393 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
22394 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
22396 config.reqGlEsVersion = GL_ES_VERSION;
22401 ActivityStack getFocusedStack() {
22402 return mStackSupervisor.getFocusedStack();
22406 public StackInfo getFocusedStackInfo() throws RemoteException {
22407 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
22408 long ident = Binder.clearCallingIdentity();
22410 synchronized (this) {
22411 ActivityStack focusedStack = getFocusedStack();
22412 if (focusedStack != null) {
22413 return mStackSupervisor.getStackInfo(focusedStack.mStackId);
22418 Binder.restoreCallingIdentity(ident);
22422 public Configuration getConfiguration() {
22424 synchronized(this) {
22425 ci = new Configuration(getGlobalConfiguration());
22426 ci.userSetLocale = false;
22432 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
22433 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
22434 synchronized (this) {
22435 mSuppressResizeConfigChanges = suppress;
22440 * NOTE: For the pinned stack, this method is usually called after the bounds animation has
22441 * animated the stack to the fullscreen, but can also be called if we are relaunching an
22442 * activity and clearing the task at the same time.
22445 // TODO: API should just be about changing windowing modes...
22446 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
22447 enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
22448 "moveTasksToFullscreenStack()");
22449 synchronized (this) {
22450 final long origId = Binder.clearCallingIdentity();
22452 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
22453 if (stack != null){
22454 if (!stack.isActivityTypeStandardOrUndefined()) {
22455 throw new IllegalArgumentException(
22456 "You can't move tasks from non-standard stacks.");
22458 mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
22461 Binder.restoreCallingIdentity(origId);
22467 public void updatePersistentConfiguration(Configuration values) {
22468 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
22469 enforceWriteSettingsPermission("updatePersistentConfiguration()");
22470 if (values == null) {
22471 throw new NullPointerException("Configuration must not be null");
22474 int userId = UserHandle.getCallingUserId();
22476 synchronized(this) {
22477 updatePersistentConfigurationLocked(values, userId);
22481 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
22482 final long origId = Binder.clearCallingIdentity();
22484 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
22486 Binder.restoreCallingIdentity(origId);
22490 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
22491 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
22492 FONT_SCALE, 1.0f, userId);
22494 synchronized (this) {
22495 if (getGlobalConfiguration().fontScale == scaleFactor) {
22499 final Configuration configuration
22500 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22501 configuration.fontScale = scaleFactor;
22502 updatePersistentConfigurationLocked(configuration, userId);
22506 private void enforceWriteSettingsPermission(String func) {
22507 int uid = Binder.getCallingUid();
22508 if (uid == ROOT_UID) {
22512 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
22513 Settings.getPackageNameForUid(mContext, uid), false)) {
22517 String msg = "Permission Denial: " + func + " from pid="
22518 + Binder.getCallingPid()
22520 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
22522 throw new SecurityException(msg);
22526 public boolean updateConfiguration(Configuration values) {
22527 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
22529 synchronized(this) {
22530 if (values == null && mWindowManager != null) {
22531 // sentinel: fetch the current configuration from the window manager
22532 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22535 if (mWindowManager != null) {
22536 // Update OOM levels based on display size.
22537 mProcessList.applyDisplaySize(mWindowManager);
22540 final long origId = Binder.clearCallingIdentity();
22542 if (values != null) {
22543 Settings.System.clearConfiguration(values);
22545 updateConfigurationLocked(values, null, false, false /* persistent */,
22546 UserHandle.USER_NULL, false /* deferResume */,
22547 mTmpUpdateConfigurationResult);
22548 return mTmpUpdateConfigurationResult.changes != 0;
22550 Binder.restoreCallingIdentity(origId);
22555 void updateUserConfigurationLocked() {
22556 final Configuration configuration = new Configuration(getGlobalConfiguration());
22557 final int currentUserId = mUserController.getCurrentUserId();
22558 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
22559 currentUserId, Settings.System.canWrite(mContext));
22560 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
22561 false /* persistent */, currentUserId, false /* deferResume */);
22564 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22565 boolean initLocale) {
22566 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
22569 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22570 boolean initLocale, boolean deferResume) {
22571 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
22572 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
22573 UserHandle.USER_NULL, deferResume);
22576 // To cache the list of supported system locales
22577 private String[] mSupportedSystemLocales = null;
22579 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22580 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
22581 return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
22582 deferResume, null /* result */);
22586 * Do either or both things: (1) change the current configuration, and (2)
22587 * make sure the given activity is running with the (now) current
22588 * configuration. Returns true if the activity has been left running, or
22589 * false if <var>starting</var> is being destroyed to match the new
22592 * @param userId is only used when persistent parameter is set to true to persist configuration
22593 * for that particular user
22595 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22596 boolean initLocale, boolean persistent, int userId, boolean deferResume,
22597 UpdateConfigurationResult result) {
22599 boolean kept = true;
22601 if (mWindowManager != null) {
22602 mWindowManager.deferSurfaceLayout();
22605 if (values != null) {
22606 changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
22610 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22612 if (mWindowManager != null) {
22613 mWindowManager.continueSurfaceLayout();
22617 if (result != null) {
22618 result.changes = changes;
22619 result.activityRelaunched = !kept;
22625 * Returns true if this configuration change is interesting enough to send an
22626 * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
22628 private static boolean isSplitConfigurationChange(int configDiff) {
22629 return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
22632 /** Update default (global) configuration and notify listeners about changes. */
22633 private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
22634 boolean persistent, int userId, boolean deferResume) {
22635 mTempConfig.setTo(getGlobalConfiguration());
22636 final int changes = mTempConfig.updateFrom(values);
22637 if (changes == 0) {
22638 // Since calling to Activity.setRequestedOrientation leads to freezing the window with
22639 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
22640 // performDisplayOverrideConfigUpdate in order to send the new display configuration
22641 // (even if there are no actual changes) to unfreeze the window.
22642 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
22646 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
22647 "Updating global configuration to: " + values);
22649 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
22650 StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
22654 values.hardKeyboardHidden,
22656 values.keyboardHidden,
22660 values.navigationHidden,
22661 values.orientation,
22662 values.screenHeightDp,
22663 values.screenLayout,
22664 values.screenWidthDp,
22665 values.smallestScreenWidthDp,
22666 values.touchscreen,
22670 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
22671 final LocaleList locales = values.getLocales();
22672 int bestLocaleIndex = 0;
22673 if (locales.size() > 1) {
22674 if (mSupportedSystemLocales == null) {
22675 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
22677 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
22679 SystemProperties.set("persist.sys.locale",
22680 locales.get(bestLocaleIndex).toLanguageTag());
22681 LocaleList.setDefault(locales, bestLocaleIndex);
22682 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
22683 locales.get(bestLocaleIndex)));
22686 mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
22687 mTempConfig.seq = mConfigurationSeq;
22689 // Update stored global config and notify everyone about the change.
22690 mStackSupervisor.onConfigurationChanged(mTempConfig);
22692 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
22693 // TODO(multi-display): Update UsageEvents#Event to include displayId.
22694 mUsageStatsService.reportConfigurationChange(mTempConfig,
22695 mUserController.getCurrentUserId());
22697 // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
22698 updateShouldShowDialogsLocked(mTempConfig);
22700 AttributeCache ac = AttributeCache.instance();
22702 ac.updateConfiguration(mTempConfig);
22705 // Make sure all resources in our process are updated right now, so that anyone who is going
22706 // to retrieve resource values after we return will be sure to get the new ones. This is
22707 // especially important during boot, where the first config change needs to guarantee all
22708 // resources have that config before following boot code is executed.
22709 mSystemThread.applyConfigurationToResources(mTempConfig);
22711 // We need another copy of global config because we're scheduling some calls instead of
22712 // running them in place. We need to be sure that object we send will be handled unchanged.
22713 final Configuration configCopy = new Configuration(mTempConfig);
22714 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
22715 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
22716 msg.obj = configCopy;
22718 mHandler.sendMessage(msg);
22721 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22722 ProcessRecord app = mLruProcesses.get(i);
22724 if (app.thread != null) {
22725 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
22726 + app.processName + " new config " + configCopy);
22727 mLifecycleManager.scheduleTransaction(app.thread,
22728 ConfigurationChangeItem.obtain(configCopy));
22730 } catch (Exception e) {
22731 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
22735 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
22736 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
22737 | Intent.FLAG_RECEIVER_FOREGROUND
22738 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22739 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22740 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22741 UserHandle.USER_ALL);
22742 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
22743 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
22744 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
22745 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
22746 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22747 if (initLocale || !mProcessesReady) {
22748 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
22750 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22751 OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22752 UserHandle.USER_ALL);
22755 // Send a broadcast to PackageInstallers if the configuration change is interesting
22756 // for the purposes of installing additional splits.
22757 if (!initLocale && isSplitConfigurationChange(changes)) {
22758 intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
22759 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
22760 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
22762 // Typically only app stores will have this permission.
22763 String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
22764 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
22765 OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
22768 // Override configuration of the default display duplicates global config, so we need to
22769 // update it also. This will also notify WindowManager about changes.
22770 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
22777 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
22778 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
22780 synchronized (this) {
22781 // Check if display is initialized in AM.
22782 if (!mStackSupervisor.isDisplayAdded(displayId)) {
22783 // Call might come when display is not yet added or has already been removed.
22784 if (DEBUG_CONFIGURATION) {
22785 Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
22791 if (values == null && mWindowManager != null) {
22792 // sentinel: fetch the current configuration from the window manager
22793 values = mWindowManager.computeNewConfiguration(displayId);
22796 if (mWindowManager != null) {
22797 // Update OOM levels based on display size.
22798 mProcessList.applyDisplaySize(mWindowManager);
22801 final long origId = Binder.clearCallingIdentity();
22803 if (values != null) {
22804 Settings.System.clearConfiguration(values);
22806 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
22807 false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
22808 return mTmpUpdateConfigurationResult.changes != 0;
22810 Binder.restoreCallingIdentity(origId);
22815 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
22816 boolean deferResume, int displayId) {
22817 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
22818 displayId, null /* result */);
22822 * Updates override configuration specific for the selected display. If no config is provided,
22823 * new one will be computed in WM based on current display info.
22825 private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
22826 ActivityRecord starting, boolean deferResume, int displayId,
22827 UpdateConfigurationResult result) {
22829 boolean kept = true;
22831 if (mWindowManager != null) {
22832 mWindowManager.deferSurfaceLayout();
22835 if (values != null) {
22836 if (displayId == DEFAULT_DISPLAY) {
22837 // Override configuration of the default display duplicates global config, so
22838 // we're calling global config update instead for default display. It will also
22839 // apply the correct override config.
22840 changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
22841 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
22843 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
22847 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22849 if (mWindowManager != null) {
22850 mWindowManager.continueSurfaceLayout();
22854 if (result != null) {
22855 result.changes = changes;
22856 result.activityRelaunched = !kept;
22861 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
22863 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
22864 final int changes = mTempConfig.updateFrom(values);
22865 if (changes != 0) {
22866 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
22867 + mTempConfig + " for displayId=" + displayId);
22868 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
22870 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
22871 if (isDensityChange && displayId == DEFAULT_DISPLAY) {
22872 mAppWarnings.onDensityChanged();
22874 killAllBackgroundProcessesExcept(N,
22875 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
22879 // Update the configuration with WM first and check if any of the stacks need to be resized
22880 // due to the configuration change. If so, resize the stacks now and do any relaunches if
22881 // necessary. This way we don't need to relaunch again afterwards in
22882 // ensureActivityConfiguration().
22883 if (mWindowManager != null) {
22884 final int[] resizedStacks =
22885 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
22886 if (resizedStacks != null) {
22887 for (int stackId : resizedStacks) {
22888 resizeStackWithBoundsFromWindowManager(stackId, deferResume);
22896 /** Applies latest configuration and/or visibility updates if needed. */
22897 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
22898 boolean kept = true;
22899 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
22900 // mainStack is null during startup.
22901 if (mainStack != null) {
22902 if (changes != 0 && starting == null) {
22903 // If the configuration changed, and the caller is not already
22904 // in the process of starting an activity, then find the top
22905 // activity to check if its configuration needs to change.
22906 starting = mainStack.topRunningActivityLocked();
22909 if (starting != null) {
22910 kept = starting.ensureActivityConfiguration(changes,
22911 false /* preserveWindow */);
22912 // And we need to make sure at this point that all other activities
22913 // are made visible with the correct configuration.
22914 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
22915 !PRESERVE_WINDOWS);
22922 /** Helper method that requests bounds from WM and applies them to stack. */
22923 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
22924 final Rect newStackBounds = new Rect();
22925 final ActivityStack stack = mStackSupervisor.getStack(stackId);
22927 // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
22928 if (stack == null) {
22929 final StringWriter writer = new StringWriter();
22930 final PrintWriter printWriter = new PrintWriter(writer);
22931 mStackSupervisor.dumpDisplays(printWriter);
22932 printWriter.flush();
22934 Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
22937 stack.getBoundsForNewConfiguration(newStackBounds);
22938 mStackSupervisor.resizeStackLocked(
22939 stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
22940 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
22941 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
22945 * Decide based on the configuration whether we should show the ANR,
22946 * crash, etc dialogs. The idea is that if there is no affordance to
22947 * press the on-screen buttons, or the user experience would be more
22948 * greatly impacted than the crash itself, we shouldn't show the dialog.
22950 * A thought: SystemUI might also want to get told about this, the Power
22951 * dialog / global actions also might want different behaviors.
22953 private void updateShouldShowDialogsLocked(Configuration config) {
22954 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
22955 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
22956 && config.navigation == Configuration.NAVIGATION_NONAV);
22957 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
22958 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
22959 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
22960 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
22961 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
22962 final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
22963 HIDE_ERROR_DIALOGS, 0) != 0;
22964 mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
22968 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
22969 synchronized (this) {
22970 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
22971 if (srec != null) {
22972 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
22978 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22979 Intent resultData) {
22981 synchronized (this) {
22982 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22984 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22990 public int getLaunchedFromUid(IBinder activityToken) {
22991 ActivityRecord srec;
22992 synchronized (this) {
22993 srec = ActivityRecord.forTokenLocked(activityToken);
22995 if (srec == null) {
22998 return srec.launchedFromUid;
23001 public String getLaunchedFromPackage(IBinder activityToken) {
23002 ActivityRecord srec;
23003 synchronized (this) {
23004 srec = ActivityRecord.forTokenLocked(activityToken);
23006 if (srec == null) {
23009 return srec.launchedFromPackage;
23012 // =========================================================
23013 // LIFETIME MANAGEMENT
23014 // =========================================================
23016 // Returns whether the app is receiving broadcast.
23017 // If receiving, fetch all broadcast queues which the app is
23018 // the current [or imminent] receiver on.
23019 private boolean isReceivingBroadcastLocked(ProcessRecord app,
23020 ArraySet<BroadcastQueue> receivingQueues) {
23021 final int N = app.curReceivers.size();
23023 for (int i = 0; i < N; i++) {
23024 receivingQueues.add(app.curReceivers.valueAt(i).queue);
23029 // It's not the current receiver, but it might be starting up to become one
23030 for (BroadcastQueue queue : mBroadcastQueues) {
23031 final BroadcastRecord r = queue.mPendingBroadcast;
23032 if (r != null && r.curApp == app) {
23033 // found it; report which queue it's in
23034 receivingQueues.add(queue);
23038 return !receivingQueues.isEmpty();
23041 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
23042 int targetUid, ComponentName targetComponent, String targetProcess) {
23043 if (!mTrackingAssociations) {
23046 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
23047 = mAssociations.get(targetUid);
23048 if (components == null) {
23049 components = new ArrayMap<>();
23050 mAssociations.put(targetUid, components);
23052 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
23053 if (sourceUids == null) {
23054 sourceUids = new SparseArray<>();
23055 components.put(targetComponent, sourceUids);
23057 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
23058 if (sourceProcesses == null) {
23059 sourceProcesses = new ArrayMap<>();
23060 sourceUids.put(sourceUid, sourceProcesses);
23062 Association ass = sourceProcesses.get(sourceProcess);
23064 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
23066 sourceProcesses.put(sourceProcess, ass);
23070 if (ass.mNesting == 1) {
23071 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
23072 ass.mLastState = sourceState;
23077 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
23078 ComponentName targetComponent) {
23079 if (!mTrackingAssociations) {
23082 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
23083 = mAssociations.get(targetUid);
23084 if (components == null) {
23087 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
23088 if (sourceUids == null) {
23091 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
23092 if (sourceProcesses == null) {
23095 Association ass = sourceProcesses.get(sourceProcess);
23096 if (ass == null || ass.mNesting <= 0) {
23100 if (ass.mNesting == 0) {
23101 long uptime = SystemClock.uptimeMillis();
23102 ass.mTime += uptime - ass.mStartTime;
23103 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
23104 += uptime - ass.mLastStateUptime;
23105 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
23109 private void noteUidProcessState(final int uid, final int state) {
23110 mBatteryStatsService.noteUidProcessState(uid, state);
23111 mAppOpsService.updateUidProcState(uid, state);
23112 if (mTrackingAssociations) {
23113 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
23114 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
23115 = mAssociations.valueAt(i1);
23116 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
23117 SparseArray<ArrayMap<String, Association>> sourceUids
23118 = targetComponents.valueAt(i2);
23119 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
23120 if (sourceProcesses != null) {
23121 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
23122 Association ass = sourceProcesses.valueAt(i4);
23123 if (ass.mNesting >= 1) {
23124 // currently associated
23125 long uptime = SystemClock.uptimeMillis();
23126 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
23127 += uptime - ass.mLastStateUptime;
23128 ass.mLastState = state;
23129 ass.mLastStateUptime = uptime;
23138 private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
23139 boolean doingAll, long now) {
23140 if (mAdjSeq == app.adjSeq) {
23141 if (app.adjSeq == app.completedAdjSeq) {
23142 // This adjustment has already been computed successfully.
23145 // The process is being computed, so there is a cycle. We cannot
23146 // rely on this process's state.
23147 app.containsCycle = true;
23153 if (app.thread == null) {
23154 app.adjSeq = mAdjSeq;
23155 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23156 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23157 app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ;
23158 app.completedAdjSeq = app.adjSeq;
23162 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
23163 app.adjSource = null;
23164 app.adjTarget = null;
23166 app.cached = false;
23168 final int activitiesSize = app.activities.size();
23169 final int appUid = app.info.uid;
23170 final int logUid = mCurOomAdjUid;
23172 int prevAppAdj = app.curAdj;
23173 int prevProcState = app.curProcState;
23175 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
23176 // The max adjustment doesn't allow this app to be anything
23177 // below foreground, so it is not worth doing work for it.
23178 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23179 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making fixed: " + app);
23181 app.adjType = "fixed";
23182 app.adjSeq = mAdjSeq;
23183 app.curRawAdj = app.maxAdj;
23184 app.foregroundActivities = false;
23185 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23186 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
23187 // System processes can do UI, and when they do we want to have
23188 // them trim their memory after the user leaves the UI. To
23189 // facilitate this, here we need to determine whether or not it
23190 // is currently showing UI.
23191 app.systemNoUi = true;
23192 if (app == TOP_APP) {
23193 app.systemNoUi = false;
23194 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23195 app.adjType = "pers-top-activity";
23196 } else if (app.hasTopUi) {
23197 // sched group/proc state adjustment is below
23198 app.systemNoUi = false;
23199 app.adjType = "pers-top-ui";
23200 } else if (activitiesSize > 0) {
23201 for (int j = 0; j < activitiesSize; j++) {
23202 final ActivityRecord r = app.activities.get(j);
23204 app.systemNoUi = false;
23208 if (!app.systemNoUi) {
23209 if (mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE) {
23210 // screen on, promote UI
23211 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
23212 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23214 // screen off, restrict UI scheduling
23215 app.curProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23216 app.curSchedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
23219 app.curAdj = app.maxAdj;
23220 app.completedAdjSeq = app.adjSeq;
23221 // if curAdj is less than prevAppAdj, then this process was promoted
23222 return app.curAdj < prevAppAdj;
23225 app.systemNoUi = false;
23227 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
23229 // Determine the importance of the process, starting with most
23230 // important to least, and assign an appropriate OOM adjustment.
23236 boolean foregroundActivities = false;
23237 mTmpBroadcastQueue.clear();
23238 if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
23239 // The last app on the list is the foreground app.
23240 adj = ProcessList.FOREGROUND_APP_ADJ;
23241 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23242 app.adjType = "top-activity";
23243 foregroundActivities = true;
23244 procState = PROCESS_STATE_CUR_TOP;
23245 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23246 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
23248 } else if (app.runningRemoteAnimation) {
23249 adj = ProcessList.VISIBLE_APP_ADJ;
23250 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23251 app.adjType = "running-remote-anim";
23252 procState = PROCESS_STATE_CUR_TOP;
23253 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23254 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app);
23256 } else if (app.instr != null) {
23257 // Don't want to kill running instrumentation.
23258 adj = ProcessList.FOREGROUND_APP_ADJ;
23259 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23260 app.adjType = "instrumentation";
23261 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
23262 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23263 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app);
23265 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
23266 // An app that is currently receiving a broadcast also
23267 // counts as being in the foreground for OOM killer purposes.
23268 // It's placed in a sched group based on the nature of the
23269 // broadcast as reflected by which queue it's active in.
23270 adj = ProcessList.FOREGROUND_APP_ADJ;
23271 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
23272 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
23273 app.adjType = "broadcast";
23274 procState = ActivityManager.PROCESS_STATE_RECEIVER;
23275 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23276 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app);
23278 } else if (app.executingServices.size() > 0) {
23279 // An app that is currently executing a service callback also
23280 // counts as being in the foreground.
23281 adj = ProcessList.FOREGROUND_APP_ADJ;
23282 schedGroup = app.execServicesFg ?
23283 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
23284 app.adjType = "exec-service";
23285 procState = ActivityManager.PROCESS_STATE_SERVICE;
23286 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23287 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app);
23289 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
23290 } else if (app == TOP_APP) {
23291 adj = ProcessList.FOREGROUND_APP_ADJ;
23292 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23293 app.adjType = "top-sleeping";
23294 foregroundActivities = true;
23295 procState = PROCESS_STATE_CUR_TOP;
23296 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23297 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + app);
23300 // As far as we know the process is empty. We may change our mind later.
23301 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23302 // At this point we don't actually know the adjustment. Use the cached adj
23303 // value that the caller wants us to.
23305 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23308 app.adjType = "cch-empty";
23309 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23310 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app);
23314 // Examine all activities if not already foreground.
23315 if (!foregroundActivities && activitiesSize > 0) {
23316 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
23317 for (int j = 0; j < activitiesSize; j++) {
23318 final ActivityRecord r = app.activities.get(j);
23319 if (r.app != app) {
23320 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
23321 + " instead of expected " + app);
23322 if (r.app == null || (r.app.uid == app.uid)) {
23323 // Only fix things up when they look sane
23330 // App has a visible activity; only upgrade adjustment.
23331 if (adj > ProcessList.VISIBLE_APP_ADJ) {
23332 adj = ProcessList.VISIBLE_APP_ADJ;
23333 app.adjType = "vis-activity";
23334 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23335 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23336 "Raise adj to vis-activity: " + app);
23339 if (procState > PROCESS_STATE_CUR_TOP) {
23340 procState = PROCESS_STATE_CUR_TOP;
23341 app.adjType = "vis-activity";
23342 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23343 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23344 "Raise procstate to vis-activity (top): " + app);
23347 if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23348 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23350 app.cached = false;
23352 foregroundActivities = true;
23353 final TaskRecord task = r.getTask();
23354 if (task != null && minLayer > 0) {
23355 final int layer = task.mLayerRank;
23356 if (layer >= 0 && minLayer > layer) {
23361 } else if (r.isState(ActivityState.PAUSING, ActivityState.PAUSED)) {
23362 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23363 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23364 app.adjType = "pause-activity";
23365 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23366 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23367 "Raise adj to pause-activity: " + app);
23370 if (procState > PROCESS_STATE_CUR_TOP) {
23371 procState = PROCESS_STATE_CUR_TOP;
23372 app.adjType = "pause-activity";
23373 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23374 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23375 "Raise procstate to pause-activity (top): " + app);
23378 if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23379 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23381 app.cached = false;
23383 foregroundActivities = true;
23384 } else if (r.isState(ActivityState.STOPPING)) {
23385 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23386 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23387 app.adjType = "stop-activity";
23388 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23389 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23390 "Raise adj to stop-activity: " + app);
23393 // For the process state, we will at this point consider the
23394 // process to be cached. It will be cached either as an activity
23395 // or empty depending on whether the activity is finishing. We do
23396 // this so that we can treat the process as cached for purposes of
23397 // memory trimming (determing current memory level, trim command to
23398 // send to process) since there can be an arbitrary number of stopping
23399 // processes and they should soon all go into the cached state.
23400 if (!r.finishing) {
23401 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23402 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23403 app.adjType = "stop-activity";
23404 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23405 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23406 "Raise procstate to stop-activity: " + app);
23410 app.cached = false;
23412 foregroundActivities = true;
23414 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23415 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23416 app.adjType = "cch-act";
23417 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23418 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23419 "Raise procstate to cached activity: " + app);
23424 if (adj == ProcessList.VISIBLE_APP_ADJ) {
23428 if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
23429 procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
23430 app.adjType = "cch-rec";
23431 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23432 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to cached recent: " + app);
23436 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
23437 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
23438 if (app.foregroundServices) {
23439 // The user is aware of this app, so make it visible.
23440 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23441 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
23442 app.cached = false;
23443 app.adjType = "fg-service";
23444 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23445 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23446 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to fg service: " + app);
23448 } else if (app.hasOverlayUi) {
23449 // The process is display an overlay UI.
23450 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23451 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23452 app.cached = false;
23453 app.adjType = "has-overlay-ui";
23454 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23455 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23456 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to overlay ui: " + app);
23461 // If the app was recently in the foreground and moved to a foreground service status,
23462 // allow it to get a higher rank in memory for some time, compared to other foreground
23463 // services so that it can finish performing any persistence/processing of in-memory state.
23464 if (app.foregroundServices && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
23465 && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now
23466 || app.setProcState <= ActivityManager.PROCESS_STATE_TOP)) {
23467 adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
23468 app.adjType = "fg-service-act";
23469 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23470 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app);
23474 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
23475 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23476 if (app.forcingToImportant != null) {
23477 // This is currently used for toasts... they are not interactive, and
23478 // we don't want them to cause the app to become fully foreground (and
23479 // thus out of background check), so we yes the best background level we can.
23480 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23481 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23482 app.cached = false;
23483 app.adjType = "force-imp";
23484 app.adjSource = app.forcingToImportant;
23485 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23486 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23487 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to force imp: " + app);
23492 if (app == mHeavyWeightProcess) {
23493 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
23494 // We don't want to kill the current heavy-weight process.
23495 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
23496 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23497 app.cached = false;
23498 app.adjType = "heavy";
23499 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23500 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to heavy: " + app);
23503 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
23504 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
23505 app.adjType = "heavy";
23506 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23507 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to heavy: " + app);
23512 if (app == mHomeProcess) {
23513 if (adj > ProcessList.HOME_APP_ADJ) {
23514 // This process is hosting what we currently consider to be the
23515 // home app, so we don't want to let it go into the background.
23516 adj = ProcessList.HOME_APP_ADJ;
23517 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23518 app.cached = false;
23519 app.adjType = "home";
23520 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23521 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to home: " + app);
23524 if (procState > ActivityManager.PROCESS_STATE_HOME) {
23525 procState = ActivityManager.PROCESS_STATE_HOME;
23526 app.adjType = "home";
23527 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23528 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to home: " + app);
23533 if (app == mPreviousProcess && app.activities.size() > 0) {
23534 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23535 // This was the previous process that showed UI to the user.
23536 // We want to try to keep it around more aggressively, to give
23537 // a good experience around switching between two apps.
23538 adj = ProcessList.PREVIOUS_APP_ADJ;
23539 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23540 app.cached = false;
23541 app.adjType = "previous";
23542 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23543 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app);
23546 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23547 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23548 app.adjType = "previous";
23549 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23550 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app);
23555 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
23556 + " reason=" + app.adjType);
23558 // By default, we use the computed adjustment. It may be changed if
23559 // there are applications dependent on our services or providers, but
23560 // this gives us a baseline and makes sure we don't get into an
23561 // infinite recursion.
23562 app.curRawAdj = adj;
23563 app.hasStartedServices = false;
23564 app.adjSeq = mAdjSeq;
23566 if (mBackupTarget != null && app == mBackupTarget.app) {
23567 // If possible we want to avoid killing apps while they're being backed up
23568 if (adj > ProcessList.BACKUP_APP_ADJ) {
23569 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
23570 adj = ProcessList.BACKUP_APP_ADJ;
23571 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23572 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23574 app.adjType = "backup";
23575 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23576 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app);
23578 app.cached = false;
23580 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
23581 procState = ActivityManager.PROCESS_STATE_BACKUP;
23582 app.adjType = "backup";
23583 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23584 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to backup: " + app);
23589 boolean mayBeTop = false;
23590 String mayBeTopType = null;
23591 Object mayBeTopSource = null;
23592 Object mayBeTopTarget = null;
23594 for (int is = app.services.size()-1;
23595 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23596 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23597 || procState > ActivityManager.PROCESS_STATE_TOP);
23599 ServiceRecord s = app.services.valueAt(is);
23600 if (s.startRequested) {
23601 app.hasStartedServices = true;
23602 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
23603 procState = ActivityManager.PROCESS_STATE_SERVICE;
23604 app.adjType = "started-services";
23605 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23606 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23607 "Raise procstate to started service: " + app);
23610 if (app.hasShownUi && app != mHomeProcess) {
23611 // If this process has shown some UI, let it immediately
23612 // go to the LRU list because it may be pretty heavy with
23613 // UI stuff. We'll tag it with a label just to help
23614 // debug and understand what is going on.
23615 if (adj > ProcessList.SERVICE_ADJ) {
23616 app.adjType = "cch-started-ui-services";
23619 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23620 // This service has seen some activity within
23621 // recent memory, so we will keep its process ahead
23622 // of the background processes.
23623 if (adj > ProcessList.SERVICE_ADJ) {
23624 adj = ProcessList.SERVICE_ADJ;
23625 app.adjType = "started-services";
23626 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23627 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23628 "Raise adj to started service: " + app);
23630 app.cached = false;
23633 // If we have let the service slide into the background
23634 // state, still have some text describing what it is doing
23635 // even though the service no longer has an impact.
23636 if (adj > ProcessList.SERVICE_ADJ) {
23637 app.adjType = "cch-started-services";
23642 for (int conni = s.connections.size()-1;
23643 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23644 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23645 || procState > ActivityManager.PROCESS_STATE_TOP);
23647 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
23649 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
23650 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23651 || procState > ActivityManager.PROCESS_STATE_TOP);
23653 // XXX should compute this based on the max of
23654 // all connected clients.
23655 ConnectionRecord cr = clist.get(i);
23656 if (cr.binding.client == app) {
23657 // Binding to ourself is not interesting.
23661 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
23662 ProcessRecord client = cr.binding.client;
23663 computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23664 if (client.containsCycle) {
23665 // We've detected a cycle. We should retry computeOomAdjLocked later in
23666 // case a later-checked connection from a client would raise its
23667 // priority legitimately.
23668 app.containsCycle = true;
23669 // If the client has not been completely evaluated, skip using its
23670 // priority. Else use the conservative value for now and look for a
23671 // better state in the next iteration.
23672 if (client.completedAdjSeq < mAdjSeq) {
23676 int clientAdj = client.curRawAdj;
23677 int clientProcState = client.curProcState;
23678 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23679 // If the other app is cached for any reason, for purposes here
23680 // we are going to consider it empty. The specific cached state
23681 // doesn't propagate except under certain conditions.
23682 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23684 String adjType = null;
23685 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
23686 // Not doing bind OOM management, so treat
23687 // this guy more like a started service.
23688 if (app.hasShownUi && app != mHomeProcess) {
23689 // If this process has shown some UI, let it immediately
23690 // go to the LRU list because it may be pretty heavy with
23691 // UI stuff. We'll tag it with a label just to help
23692 // debug and understand what is going on.
23693 if (adj > clientAdj) {
23694 adjType = "cch-bound-ui-services";
23696 app.cached = false;
23698 clientProcState = procState;
23700 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23701 // This service has not seen activity within
23702 // recent memory, so allow it to drop to the
23703 // LRU list if there is no other reason to keep
23704 // it around. We'll also tag it with a label just
23705 // to help debug and undertand what is going on.
23706 if (adj > clientAdj) {
23707 adjType = "cch-bound-services";
23713 if (adj > clientAdj) {
23714 // If this process has recently shown UI, and
23715 // the process that is binding to it is less
23716 // important than being visible, then we don't
23717 // care about the binding as much as we care
23718 // about letting this process get into the LRU
23719 // list to be killed and restarted if needed for
23721 if (app.hasShownUi && app != mHomeProcess
23722 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23723 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
23724 adjType = "cch-bound-ui-services";
23728 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
23729 |Context.BIND_IMPORTANT)) != 0) {
23730 if (clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
23731 newAdj = clientAdj;
23733 // make this service persistent
23734 newAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
23735 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23736 procState = ActivityManager.PROCESS_STATE_PERSISTENT;
23738 } else if ((cr.flags & Context.BIND_ADJUST_BELOW_PERCEPTIBLE) != 0
23739 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
23740 && adj > ProcessList.PERCEPTIBLE_APP_ADJ + 1) {
23741 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ + 1;
23742 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
23743 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
23744 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23745 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
23746 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
23747 newAdj = clientAdj;
23749 if (adj > ProcessList.VISIBLE_APP_ADJ) {
23750 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
23755 if (!client.cached) {
23756 app.cached = false;
23758 if (adj > newAdj) {
23760 adjType = "service";
23764 if ((cr.flags & (Context.BIND_NOT_FOREGROUND
23765 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
23766 // This will treat important bound services identically to
23767 // the top app, which may behave differently than generic
23768 // foreground work.
23769 if (client.curSchedGroup > schedGroup) {
23770 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23771 schedGroup = client.curSchedGroup;
23773 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23776 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23777 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23778 // Special handling of clients who are in the top state.
23779 // We *may* want to consider this process to be in the
23780 // top state as well, but only if there is not another
23781 // reason for it to be running. Being on the top is a
23782 // special state, meaning you are specifically running
23783 // for the current top app. If the process is already
23784 // running in the background for some other reason, it
23785 // is more important to continue considering it to be
23786 // in the background state.
23788 mayBeTopType = "service";
23789 mayBeTopSource = cr.binding.client;
23790 mayBeTopTarget = s.name;
23791 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23793 // Special handling for above-top states (persistent
23794 // processes). These should not bring the current process
23795 // into the top state, since they are not on top. Instead
23796 // give them the best state after that.
23797 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
23799 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23800 } else if (mWakefulness
23801 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
23802 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
23805 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23808 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23812 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
23813 if (clientProcState <
23814 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23816 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23819 if (clientProcState <
23820 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
23822 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
23825 if (procState > clientProcState) {
23826 procState = clientProcState;
23827 if (adjType == null) {
23828 adjType = "service";
23831 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
23832 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
23833 app.pendingUiClean = true;
23835 if (adjType != null) {
23836 app.adjType = adjType;
23837 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23838 .REASON_SERVICE_IN_USE;
23839 app.adjSource = cr.binding.client;
23840 app.adjSourceProcState = clientProcState;
23841 app.adjTarget = s.name;
23842 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23843 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
23844 + ": " + app + ", due to " + cr.binding.client
23845 + " adj=" + adj + " procState="
23846 + ProcessList.makeProcStateString(procState));
23850 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
23851 app.treatLikeActivity = true;
23853 final ActivityRecord a = cr.activity;
23854 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
23855 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible
23856 || a.isState(ActivityState.RESUMED, ActivityState.PAUSING))) {
23857 adj = ProcessList.FOREGROUND_APP_ADJ;
23858 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
23859 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23860 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
23862 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23865 app.cached = false;
23866 app.adjType = "service";
23867 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23868 .REASON_SERVICE_IN_USE;
23870 app.adjSourceProcState = procState;
23871 app.adjTarget = s.name;
23872 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23873 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23874 "Raise to service w/activity: " + app);
23882 for (int provi = app.pubProviders.size()-1;
23883 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23884 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23885 || procState > ActivityManager.PROCESS_STATE_TOP);
23887 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
23888 for (int i = cpr.connections.size()-1;
23889 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23890 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23891 || procState > ActivityManager.PROCESS_STATE_TOP);
23893 ContentProviderConnection conn = cpr.connections.get(i);
23894 ProcessRecord client = conn.client;
23895 if (client == app) {
23896 // Being our own client is not interesting.
23899 computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23900 if (client.containsCycle) {
23901 // We've detected a cycle. We should retry computeOomAdjLocked later in
23902 // case a later-checked connection from a client would raise its
23903 // priority legitimately.
23904 app.containsCycle = true;
23905 // If the client has not been completely evaluated, skip using its
23906 // priority. Else use the conservative value for now and look for a
23907 // better state in the next iteration.
23908 if (client.completedAdjSeq < mAdjSeq) {
23912 int clientAdj = client.curRawAdj;
23913 int clientProcState = client.curProcState;
23914 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23915 // If the other app is cached for any reason, for purposes here
23916 // we are going to consider it empty.
23917 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23919 String adjType = null;
23920 if (adj > clientAdj) {
23921 if (app.hasShownUi && app != mHomeProcess
23922 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23923 adjType = "cch-ui-provider";
23925 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
23926 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
23927 adjType = "provider";
23929 app.cached &= client.cached;
23931 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23932 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23933 // Special handling of clients who are in the top state.
23934 // We *may* want to consider this process to be in the
23935 // top state as well, but only if there is not another
23936 // reason for it to be running. Being on the top is a
23937 // special state, meaning you are specifically running
23938 // for the current top app. If the process is already
23939 // running in the background for some other reason, it
23940 // is more important to continue considering it to be
23941 // in the background state.
23943 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23944 mayBeTopType = adjType = "provider-top";
23945 mayBeTopSource = client;
23946 mayBeTopTarget = cpr.name;
23948 // Special handling for above-top states (persistent
23949 // processes). These should not bring the current process
23950 // into the top state, since they are not on top. Instead
23951 // give them the best state after that.
23953 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23954 if (adjType == null) {
23955 adjType = "provider";
23959 if (procState > clientProcState) {
23960 procState = clientProcState;
23962 if (client.curSchedGroup > schedGroup) {
23963 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23965 if (adjType != null) {
23966 app.adjType = adjType;
23967 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23968 .REASON_PROVIDER_IN_USE;
23969 app.adjSource = client;
23970 app.adjSourceProcState = clientProcState;
23971 app.adjTarget = cpr.name;
23972 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23973 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
23974 + ": " + app + ", due to " + client
23975 + " adj=" + adj + " procState="
23976 + ProcessList.makeProcStateString(procState));
23980 // If the provider has external (non-framework) process
23981 // dependencies, ensure that its adjustment is at least
23982 // FOREGROUND_APP_ADJ.
23983 if (cpr.hasExternalProcessHandles()) {
23984 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
23985 adj = ProcessList.FOREGROUND_APP_ADJ;
23986 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23987 app.cached = false;
23988 app.adjType = "ext-provider";
23989 app.adjTarget = cpr.name;
23990 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23991 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23992 "Raise adj to external provider: " + app);
23995 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23996 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23997 reportOomAdjMessageLocked(TAG_OOM_ADJ,
23998 "Raise procstate to external provider: " + app);
24003 if (app.lastProviderTime > 0 &&
24004 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
24005 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
24006 adj = ProcessList.PREVIOUS_APP_ADJ;
24007 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
24008 app.cached = false;
24009 app.adjType = "recent-provider";
24010 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
24011 reportOomAdjMessageLocked(TAG_OOM_ADJ,
24012 "Raise adj to recent provider: " + app);
24015 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
24016 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
24017 app.adjType = "recent-provider";
24018 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
24019 reportOomAdjMessageLocked(TAG_OOM_ADJ,
24020 "Raise procstate to recent provider: " + app);
24025 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
24026 // A client of one of our services or providers is in the top state. We
24027 // *may* want to be in the top state, but not if we are already running in
24028 // the background for some other reason. For the decision here, we are going
24029 // to pick out a few specific states that we want to remain in when a client
24030 // is top (states that tend to be longer-term) and otherwise allow it to go
24031 // to the top state.
24032 switch (procState) {
24033 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
24034 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
24035 // Something else is keeping it at this level, just leave it.
24037 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
24038 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
24039 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
24040 case ActivityManager.PROCESS_STATE_SERVICE:
24041 // These all are longer-term states, so pull them up to the top
24042 // of the background states, but not all the way to the top state.
24043 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
24044 app.adjType = mayBeTopType;
24045 app.adjSource = mayBeTopSource;
24046 app.adjTarget = mayBeTopTarget;
24047 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
24048 reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
24049 + ": " + app + ", due to " + mayBeTopSource
24050 + " adj=" + adj + " procState="
24051 + ProcessList.makeProcStateString(procState));
24055 // Otherwise, top is a better choice, so take it.
24056 procState = ActivityManager.PROCESS_STATE_TOP;
24057 app.adjType = mayBeTopType;
24058 app.adjSource = mayBeTopSource;
24059 app.adjTarget = mayBeTopTarget;
24060 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
24061 reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
24062 + ": " + app + ", due to " + mayBeTopSource
24063 + " adj=" + adj + " procState="
24064 + ProcessList.makeProcStateString(procState));
24070 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
24071 if (app.hasClientActivities) {
24072 // This is a cached process, but with client activities. Mark it so.
24073 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
24074 app.adjType = "cch-client-act";
24075 } else if (app.treatLikeActivity) {
24076 // This is a cached process, but somebody wants us to treat it like it has
24077 // an activity, okay!
24078 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
24079 app.adjType = "cch-as-act";
24083 if (adj == ProcessList.SERVICE_ADJ) {
24085 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
24086 mNewNumServiceProcs++;
24087 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
24088 if (!app.serviceb) {
24089 // This service isn't far enough down on the LRU list to
24090 // normally be a B service, but if we are low on RAM and it
24091 // is large we want to force it down since we would prefer to
24092 // keep launcher over it.
24093 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
24094 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
24095 app.serviceHighRam = true;
24096 app.serviceb = true;
24097 //Slog.i(TAG, "ADJ " + app + " high ram!");
24099 mNewNumAServiceProcs++;
24100 //Slog.i(TAG, "ADJ " + app + " not high ram!");
24103 app.serviceHighRam = false;
24106 if (app.serviceb) {
24107 adj = ProcessList.SERVICE_B_ADJ;
24111 app.curRawAdj = adj;
24113 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
24114 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
24115 if (adj > app.maxAdj) {
24117 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
24118 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
24122 // Put bound foreground services in a special sched group for additional
24123 // restrictions on screen off
24124 if (procState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE &&
24125 mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) {
24126 if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) {
24127 schedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
24131 // Do final modification to adj. Everything we do between here and applying
24132 // the final setAdj must be done in this function, because we will also use
24133 // it when computing the final cached adj later. Note that we don't need to
24134 // worry about this for max adj above, since max adj will always be used to
24135 // keep it out of the cached vaues.
24136 app.curAdj = app.modifyRawOomAdj(adj);
24137 app.curSchedGroup = schedGroup;
24138 app.curProcState = procState;
24139 app.foregroundActivities = foregroundActivities;
24140 app.completedAdjSeq = mAdjSeq;
24142 // if curAdj or curProcState improved, then this process was promoted
24143 return app.curAdj < prevAppAdj || app.curProcState < prevProcState;
24147 * Record new PSS sample for a process.
24149 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
24150 long rss, int statType, long pssDuration, long now) {
24151 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
24152 swapPss * 1024, rss * 1024, statType, procState, pssDuration);
24153 proc.lastPssTime = now;
24154 proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
24155 if (DEBUG_PSS) Slog.d(TAG_PSS,
24156 "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
24157 + " state=" + ProcessList.makeProcStateString(procState));
24158 if (proc.initialIdlePss == 0) {
24159 proc.initialIdlePss = pss;
24161 proc.lastPss = pss;
24162 proc.lastSwapPss = swapPss;
24163 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
24164 proc.lastCachedPss = pss;
24165 proc.lastCachedSwapPss = swapPss;
24168 final SparseArray<Pair<Long, String>> watchUids
24169 = mMemWatchProcesses.getMap().get(proc.processName);
24171 if (watchUids != null) {
24172 Pair<Long, String> val = watchUids.get(proc.uid);
24174 val = watchUids.get(0);
24180 if (check != null) {
24181 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
24182 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24183 if (!isDebuggable) {
24184 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
24185 isDebuggable = true;
24188 if (isDebuggable) {
24189 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
24190 final ProcessRecord myProc = proc;
24191 final File heapdumpFile = DumpHeapProvider.getJavaFile();
24192 mMemWatchDumpProcName = proc.processName;
24193 mMemWatchDumpFile = heapdumpFile.toString();
24194 mMemWatchDumpPid = proc.pid;
24195 mMemWatchDumpUid = proc.uid;
24196 BackgroundThread.getHandler().post(new Runnable() {
24198 public void run() {
24199 revokeUriPermission(ActivityThread.currentActivityThread()
24200 .getApplicationThread(),
24201 null, DumpHeapActivity.JAVA_URI,
24202 Intent.FLAG_GRANT_READ_URI_PERMISSION
24203 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
24204 UserHandle.myUserId());
24205 ParcelFileDescriptor fd = null;
24207 heapdumpFile.delete();
24208 fd = ParcelFileDescriptor.open(heapdumpFile,
24209 ParcelFileDescriptor.MODE_CREATE |
24210 ParcelFileDescriptor.MODE_TRUNCATE |
24211 ParcelFileDescriptor.MODE_WRITE_ONLY |
24212 ParcelFileDescriptor.MODE_APPEND);
24213 IApplicationThread thread = myProc.thread;
24214 if (thread != null) {
24216 if (DEBUG_PSS) Slog.d(TAG_PSS,
24217 "Requesting dump heap from "
24218 + myProc + " to " + heapdumpFile);
24219 thread.dumpHeap(/* managed= */ true,
24220 /* mallocInfo= */ false, /* runGc= */ false,
24221 heapdumpFile.toString(), fd);
24222 } catch (RemoteException e) {
24225 } catch (FileNotFoundException e) {
24226 e.printStackTrace();
24231 } catch (IOException e) {
24238 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
24239 + ", but debugging not enabled");
24246 * Schedule PSS collection of a process.
24248 boolean requestPssLocked(ProcessRecord proc, int procState) {
24249 if (mPendingPssProcesses.contains(proc)) {
24252 if (mPendingPssProcesses.size() == 0) {
24253 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
24255 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
24256 proc.pssProcState = procState;
24257 proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
24258 mPendingPssProcesses.add(proc);
24263 * Schedule PSS collection of all processes.
24265 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
24267 if (now < (mLastFullPssTime +
24268 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
24269 : mConstants.FULL_PSS_MIN_INTERVAL))) {
24273 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs! memLowered=" + memLowered);
24274 mLastFullPssTime = now;
24275 mFullPssPending = true;
24276 for (int i = mPendingPssProcesses.size() - 1; i >= 0; i--) {
24277 ProcessList.abortNextPssTime(mPendingPssProcesses.get(i).procStateMemTracker);;
24279 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
24280 mPendingPssProcesses.clear();
24281 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24282 ProcessRecord app = mLruProcesses.get(i);
24283 if (app.thread == null
24284 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
24287 if (memLowered || (always && now >
24288 app.lastStateTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
24289 || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
24290 app.pssProcState = app.setProcState;
24291 app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
24292 : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
24293 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24294 app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24295 mPendingPssProcesses.add(app);
24298 if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) {
24299 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
24303 public void setTestPssMode(boolean enabled) {
24304 synchronized (this) {
24305 mTestPssMode = enabled;
24307 // Whenever we enable the mode, we want to take a snapshot all of current
24308 // process mem use.
24309 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
24315 * Ask a given process to GC right now.
24317 final void performAppGcLocked(ProcessRecord app) {
24319 app.lastRequestedGc = SystemClock.uptimeMillis();
24320 if (app.thread != null) {
24321 if (app.reportLowMemory) {
24322 app.reportLowMemory = false;
24323 app.thread.scheduleLowMemory();
24325 app.thread.processInBackground();
24328 } catch (Exception e) {
24334 * Returns true if things are idle enough to perform GCs.
24336 private final boolean canGcNowLocked() {
24337 boolean processingBroadcasts = false;
24338 for (BroadcastQueue q : mBroadcastQueues) {
24339 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
24340 processingBroadcasts = true;
24343 return !processingBroadcasts
24344 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
24348 * Perform GCs on all processes that are waiting for it, but only
24349 * if things are idle.
24351 final void performAppGcsLocked() {
24352 final int N = mProcessesToGc.size();
24356 if (canGcNowLocked()) {
24357 while (mProcessesToGc.size() > 0) {
24358 ProcessRecord proc = mProcessesToGc.remove(0);
24359 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
24360 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
24361 <= SystemClock.uptimeMillis()) {
24362 // To avoid spamming the system, we will GC processes one
24363 // at a time, waiting a few seconds between each.
24364 performAppGcLocked(proc);
24365 scheduleAppGcsLocked();
24368 // It hasn't been long enough since we last GCed this
24369 // process... put it in the list to wait for its time.
24370 addProcessToGcListLocked(proc);
24376 scheduleAppGcsLocked();
24381 * If all looks good, perform GCs on all processes waiting for them.
24383 final void performAppGcsIfAppropriateLocked() {
24384 if (canGcNowLocked()) {
24385 performAppGcsLocked();
24388 // Still not idle, wait some more.
24389 scheduleAppGcsLocked();
24393 * Schedule the execution of all pending app GCs.
24395 final void scheduleAppGcsLocked() {
24396 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
24398 if (mProcessesToGc.size() > 0) {
24399 // Schedule a GC for the time to the next process.
24400 ProcessRecord proc = mProcessesToGc.get(0);
24401 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
24403 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
24404 long now = SystemClock.uptimeMillis();
24405 if (when < (now+mConstants.GC_TIMEOUT)) {
24406 when = now + mConstants.GC_TIMEOUT;
24408 mHandler.sendMessageAtTime(msg, when);
24413 * Add a process to the array of processes waiting to be GCed. Keeps the
24414 * list in sorted order by the last GC time. The process can't already be
24417 final void addProcessToGcListLocked(ProcessRecord proc) {
24418 boolean added = false;
24419 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
24420 if (mProcessesToGc.get(i).lastRequestedGc <
24421 proc.lastRequestedGc) {
24423 mProcessesToGc.add(i+1, proc);
24428 mProcessesToGc.add(0, proc);
24433 * Set up to ask a process to GC itself. This will either do it
24434 * immediately, or put it on the list of processes to gc the next
24435 * time things are idle.
24437 final void scheduleAppGcLocked(ProcessRecord app) {
24438 long now = SystemClock.uptimeMillis();
24439 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
24442 if (!mProcessesToGc.contains(app)) {
24443 addProcessToGcListLocked(app);
24444 scheduleAppGcsLocked();
24448 final void checkExcessivePowerUsageLocked() {
24449 updateCpuStatsNow();
24451 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
24452 boolean doCpuKills = true;
24453 if (mLastPowerCheckUptime == 0) {
24454 doCpuKills = false;
24456 final long curUptime = SystemClock.uptimeMillis();
24457 final long uptimeSince = curUptime - mLastPowerCheckUptime;
24458 mLastPowerCheckUptime = curUptime;
24459 int i = mLruProcesses.size();
24462 ProcessRecord app = mLruProcesses.get(i);
24463 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24464 if (app.lastCpuTime <= 0) {
24467 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
24469 StringBuilder sb = new StringBuilder(128);
24470 sb.append("CPU for ");
24471 app.toShortString(sb);
24472 sb.append(": over ");
24473 TimeUtils.formatDuration(uptimeSince, sb);
24474 sb.append(" used ");
24475 TimeUtils.formatDuration(cputimeUsed, sb);
24477 sb.append((cputimeUsed*100)/uptimeSince);
24479 Slog.i(TAG_POWER, sb.toString());
24481 // If the process has used too much CPU over the last duration, the
24482 // user probably doesn't want this, so kill!
24483 if (doCpuKills && uptimeSince > 0) {
24484 // What is the limit for this process?
24486 long checkDur = curUptime - app.whenUnimportant;
24487 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
24488 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
24489 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
24490 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
24491 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
24492 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
24493 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
24495 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
24497 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
24498 synchronized (stats) {
24499 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
24500 uptimeSince, cputimeUsed);
24502 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
24503 + " dur=" + checkDur + " limit=" + cpuLimit, true);
24504 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
24507 app.lastCpuTime = app.curCpuTime;
24512 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
24514 boolean success = true;
24516 if (app.curRawAdj != app.setRawAdj) {
24517 app.setRawAdj = app.curRawAdj;
24522 if (app.curAdj != app.setAdj) {
24523 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
24524 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
24525 String msg = "Set " + app.pid + " " + app.processName + " adj "
24526 + app.curAdj + ": " + app.adjType;
24527 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24529 app.setAdj = app.curAdj;
24530 app.verifiedAdj = ProcessList.INVALID_ADJ;
24533 if (app.setSchedGroup != app.curSchedGroup) {
24534 int oldSchedGroup = app.setSchedGroup;
24535 app.setSchedGroup = app.curSchedGroup;
24536 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24537 String msg = "Setting sched group of " + app.processName
24538 + " to " + app.curSchedGroup + ": " + app.adjType;
24539 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24541 if (app.waitingToKill != null && app.curReceivers.isEmpty()
24542 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
24543 app.kill(app.waitingToKill, true);
24547 switch (app.curSchedGroup) {
24548 case ProcessList.SCHED_GROUP_BACKGROUND:
24549 processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
24551 case ProcessList.SCHED_GROUP_TOP_APP:
24552 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
24553 processGroup = THREAD_GROUP_TOP_APP;
24555 case ProcessList.SCHED_GROUP_RESTRICTED:
24556 processGroup = THREAD_GROUP_RESTRICTED;
24559 processGroup = THREAD_GROUP_DEFAULT;
24562 long oldId = Binder.clearCallingIdentity();
24564 setProcessGroup(app.pid, processGroup);
24565 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
24566 // do nothing if we already switched to RT
24567 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
24568 mVrController.onTopProcChangedLocked(app);
24569 if (mUseFifoUiScheduling) {
24570 // Switch UI pipeline for app to SCHED_FIFO
24571 app.savedPriority = Process.getThreadPriority(app.pid);
24572 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
24573 if (app.renderThreadTid != 0) {
24574 scheduleAsFifoPriority(app.renderThreadTid,
24575 /* suppressLogs */true);
24576 if (DEBUG_OOM_ADJ) {
24577 Slog.d("UI_FIFO", "Set RenderThread (TID " +
24578 app.renderThreadTid + ") to FIFO");
24581 if (DEBUG_OOM_ADJ) {
24582 Slog.d("UI_FIFO", "Not setting RenderThread TID");
24586 // Boost priority for top app UI and render threads
24587 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
24588 if (app.renderThreadTid != 0) {
24590 setThreadPriority(app.renderThreadTid,
24591 TOP_APP_PRIORITY_BOOST);
24592 } catch (IllegalArgumentException e) {
24593 // thread died, ignore
24598 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
24599 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
24600 mVrController.onTopProcChangedLocked(app);
24601 if (mUseFifoUiScheduling) {
24603 // Reset UI pipeline to SCHED_OTHER
24604 setThreadScheduler(app.pid, SCHED_OTHER, 0);
24605 setThreadPriority(app.pid, app.savedPriority);
24606 if (app.renderThreadTid != 0) {
24607 setThreadScheduler(app.renderThreadTid,
24609 setThreadPriority(app.renderThreadTid, -4);
24611 } catch (IllegalArgumentException e) {
24613 "Failed to set scheduling policy, thread does not exist:\n"
24615 } catch (SecurityException e) {
24616 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
24619 // Reset priority for top app UI and render threads
24620 setThreadPriority(app.pid, 0);
24621 if (app.renderThreadTid != 0) {
24622 setThreadPriority(app.renderThreadTid, 0);
24626 } catch (Exception e) {
24628 Slog.w(TAG, "Failed setting process group of " + app.pid
24629 + " to " + app.curSchedGroup);
24630 Slog.w(TAG, "at location", e);
24633 Binder.restoreCallingIdentity(oldId);
24637 if (app.repForegroundActivities != app.foregroundActivities) {
24638 app.repForegroundActivities = app.foregroundActivities;
24639 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
24641 if (app.repProcState != app.curProcState) {
24642 app.repProcState = app.curProcState;
24643 if (app.thread != null) {
24646 //RuntimeException h = new RuntimeException("here");
24647 Slog.i(TAG, "Sending new process state " + app.repProcState
24648 + " to " + app /*, h*/);
24650 app.thread.setProcessState(app.repProcState);
24651 } catch (RemoteException e) {
24655 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
24656 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
24657 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
24658 // Experimental code to more aggressively collect pss while
24659 // running test... the problem is that this tends to collect
24660 // the data right when a process is transitioning between process
24661 // states, which will tend to give noisy data.
24662 long start = SystemClock.uptimeMillis();
24663 long startTime = SystemClock.currentThreadTimeMillis();
24664 long pss = Debug.getPss(app.pid, mTmpLong, null);
24665 long endTime = SystemClock.currentThreadTimeMillis();
24666 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
24667 mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
24668 mPendingPssProcesses.remove(app);
24669 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
24670 + " to " + app.curProcState + ": "
24671 + (SystemClock.uptimeMillis()-start) + "ms");
24673 app.lastStateTime = now;
24674 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24675 app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24676 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
24677 + ProcessList.makeProcStateString(app.setProcState) + " to "
24678 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
24679 + (app.nextPssTime-now) + ": " + app);
24681 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
24682 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
24684 if (requestPssLocked(app, app.setProcState)) {
24685 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24686 app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24688 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
24689 "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
24691 if (app.setProcState != app.curProcState) {
24692 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24693 String msg = "Proc state change of " + app.processName
24694 + " to " + ProcessList.makeProcStateString(app.curProcState)
24695 + " (" + app.curProcState + ")" + ": " + app.adjType;
24696 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24698 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
24699 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
24700 if (setImportant && !curImportant) {
24701 // This app is no longer something we consider important enough to allow to
24702 // use arbitrary amounts of battery power. Note
24703 // its current CPU time to later know to kill it if
24704 // it is not behaving well.
24705 app.whenUnimportant = now;
24706 app.lastCpuTime = 0;
24708 // Inform UsageStats of important process state change
24709 // Must be called before updating setProcState
24710 maybeUpdateUsageStatsLocked(app, nowElapsed);
24712 maybeUpdateLastTopTime(app, now);
24714 app.setProcState = app.curProcState;
24715 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24716 app.notCachedSinceIdle = false;
24719 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
24721 app.procStateChanged = true;
24723 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
24724 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
24725 // For apps that sit around for a long time in the interactive state, we need
24726 // to report this at least once a day so they don't go idle.
24727 maybeUpdateUsageStatsLocked(app, nowElapsed);
24730 if (changes != 0) {
24731 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24732 "Changes in " + app + ": " + changes);
24733 int i = mPendingProcessChanges.size()-1;
24734 ProcessChangeItem item = null;
24736 item = mPendingProcessChanges.get(i);
24737 if (item.pid == app.pid) {
24738 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24739 "Re-using existing item: " + item);
24745 // No existing item in pending changes; need a new one.
24746 final int NA = mAvailProcessChanges.size();
24748 item = mAvailProcessChanges.remove(NA-1);
24749 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24750 "Retrieving available item: " + item);
24752 item = new ProcessChangeItem();
24753 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24754 "Allocating new item: " + item);
24757 item.pid = app.pid;
24758 item.uid = app.info.uid;
24759 if (mPendingProcessChanges.size() == 0) {
24760 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24761 "*** Enqueueing dispatch processes changed!");
24762 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
24764 mPendingProcessChanges.add(item);
24766 item.changes |= changes;
24767 item.foregroundActivities = app.repForegroundActivities;
24768 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24769 "Item " + Integer.toHexString(System.identityHashCode(item))
24770 + " " + app.toShortString() + ": changes=" + item.changes
24771 + " foreground=" + item.foregroundActivities
24772 + " type=" + app.adjType + " source=" + app.adjSource
24773 + " target=" + app.adjTarget);
24779 private boolean isEphemeralLocked(int uid) {
24780 String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
24781 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
24784 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
24789 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
24790 final UidRecord.ChangeItem pendingChange;
24791 if (uidRec == null || uidRec.pendingChange == null) {
24792 if (mPendingUidChanges.size() == 0) {
24793 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24794 "*** Enqueueing dispatch uid changed!");
24795 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
24797 final int NA = mAvailUidChanges.size();
24799 pendingChange = mAvailUidChanges.remove(NA-1);
24800 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24801 "Retrieving available item: " + pendingChange);
24803 pendingChange = new UidRecord.ChangeItem();
24804 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24805 "Allocating new item: " + pendingChange);
24807 if (uidRec != null) {
24808 uidRec.pendingChange = pendingChange;
24809 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
24810 // If this uid is going away, and we haven't yet reported it is gone,
24812 change |= UidRecord.CHANGE_IDLE;
24814 } else if (uid < 0) {
24815 throw new IllegalArgumentException("No UidRecord or uid");
24817 pendingChange.uidRecord = uidRec;
24818 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
24819 mPendingUidChanges.add(pendingChange);
24821 pendingChange = uidRec.pendingChange;
24822 // If there is no change in idle or active state, then keep whatever was pending.
24823 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
24824 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
24825 | UidRecord.CHANGE_ACTIVE));
24827 // If there is no change in cached or uncached state, then keep whatever was pending.
24828 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
24829 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
24830 | UidRecord.CHANGE_UNCACHED));
24832 // If this is a report of the UID being gone, then we shouldn't keep any previous
24833 // report of it being active or cached. (That is, a gone uid is never active,
24834 // and never cached.)
24835 if ((change & UidRecord.CHANGE_GONE) != 0) {
24836 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
24837 if (!uidRec.idle) {
24838 // If this uid is going away, and we haven't yet reported it is gone,
24840 change |= UidRecord.CHANGE_IDLE;
24844 pendingChange.change = change;
24845 pendingChange.processState = uidRec != null
24846 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
24847 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
24848 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
24849 if (uidRec != null) {
24850 uidRec.lastReportedChange = change;
24851 uidRec.updateLastDispatchedProcStateSeq(change);
24854 // Directly update the power manager, since we sit on top of it and it is critical
24855 // it be kept in sync (so wake locks will be held as soon as appropriate).
24856 if (mLocalPowerManager != null) {
24857 // TO DO: dispatch cached/uncached changes here, so we don't need to report
24858 // all proc state changes.
24859 if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
24860 mLocalPowerManager.uidActive(pendingChange.uid);
24862 if ((change & UidRecord.CHANGE_IDLE) != 0) {
24863 mLocalPowerManager.uidIdle(pendingChange.uid);
24865 if ((change & UidRecord.CHANGE_GONE) != 0) {
24866 mLocalPowerManager.uidGone(pendingChange.uid);
24868 mLocalPowerManager.updateUidProcState(pendingChange.uid,
24869 pendingChange.processState);
24874 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
24875 String authority) {
24876 if (app == null) return;
24877 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
24878 UserState userState = mUserController.getStartedUserState(app.userId);
24879 if (userState == null) return;
24880 final long now = SystemClock.elapsedRealtime();
24881 Long lastReported = userState.mProviderLastReportedFg.get(authority);
24882 if (lastReported == null || lastReported < now - 60 * 1000L) {
24883 if (mSystemReady) {
24884 // Cannot touch the user stats if not system ready
24885 mUsageStatsService.reportContentProviderUsage(
24886 authority, providerPkgName, app.userId);
24888 userState.mProviderLastReportedFg.put(authority, now);
24893 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
24894 if (DEBUG_USAGE_STATS) {
24895 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
24896 + "] state changes: old = " + app.setProcState + ", new = "
24897 + app.curProcState);
24899 if (mUsageStatsService == null) {
24902 boolean isInteraction;
24903 // To avoid some abuse patterns, we are going to be careful about what we consider
24904 // to be an app interaction. Being the top activity doesn't count while the display
24905 // is sleeping, nor do short foreground services.
24906 if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
24907 isInteraction = true;
24908 app.fgInteractionTime = 0;
24909 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
24910 if (app.fgInteractionTime == 0) {
24911 app.fgInteractionTime = nowElapsed;
24912 isInteraction = false;
24914 isInteraction = nowElapsed > app.fgInteractionTime
24915 + mConstants.SERVICE_USAGE_INTERACTION_TIME;
24918 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
24919 app.fgInteractionTime = 0;
24921 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
24922 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
24923 app.interactionEventTime = nowElapsed;
24924 String[] packages = app.getPackageList();
24925 if (packages != null) {
24926 for (int i = 0; i < packages.length; i++) {
24927 mUsageStatsService.reportEvent(packages[i], app.userId,
24928 UsageEvents.Event.SYSTEM_INTERACTION);
24932 app.reportedInteraction = isInteraction;
24933 if (!isInteraction) {
24934 app.interactionEventTime = 0;
24938 private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) {
24939 if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP
24940 && app.curProcState > ActivityManager.PROCESS_STATE_TOP) {
24941 app.lastTopTime = nowUptime;
24945 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
24946 if (proc.thread != null) {
24947 if (proc.baseProcessTracker != null) {
24948 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
24953 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
24954 ProcessRecord TOP_APP, boolean doingAll, long now) {
24955 if (app.thread == null) {
24959 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
24961 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
24965 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
24967 if (isForeground != proc.foregroundServices) {
24968 proc.foregroundServices = isForeground;
24969 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
24971 if (isForeground) {
24972 if (curProcs == null) {
24973 curProcs = new ArrayList<ProcessRecord>();
24974 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
24976 if (!curProcs.contains(proc)) {
24977 curProcs.add(proc);
24978 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
24979 proc.info.packageName, proc.info.uid);
24982 if (curProcs != null) {
24983 if (curProcs.remove(proc)) {
24984 mBatteryStatsService.noteEvent(
24985 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
24986 proc.info.packageName, proc.info.uid);
24987 if (curProcs.size() <= 0) {
24988 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
24994 updateOomAdjLocked();
24999 private final ActivityRecord resumedAppLocked() {
25000 ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
25004 pkg = act.packageName;
25005 uid = act.info.applicationInfo.uid;
25010 // Has the UID or resumed package name changed?
25011 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
25012 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
25013 if (mCurResumedPackage != null) {
25014 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
25015 mCurResumedPackage, mCurResumedUid);
25017 mCurResumedPackage = pkg;
25018 mCurResumedUid = uid;
25019 if (mCurResumedPackage != null) {
25020 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
25021 mCurResumedPackage, mCurResumedUid);
25028 * Update OomAdj for a specific process.
25029 * @param app The process to update
25030 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
25031 * if necessary, or skip.
25032 * @return whether updateOomAdjLocked(app) was successful.
25035 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
25036 final ActivityRecord TOP_ACT = resumedAppLocked();
25037 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
25038 final boolean wasCached = app.cached;
25042 // This is the desired cached adjusment we want to tell it to use.
25043 // If our app is currently cached, we know it, and that is it. Otherwise,
25044 // we don't know it yet, and it needs to now be cached we will then
25045 // need to do a complete oom adj.
25046 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
25047 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
25048 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
25049 SystemClock.uptimeMillis());
25051 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
25052 // Changed to/from cached state, so apps after it in the LRU
25053 // list may also be changed.
25054 updateOomAdjLocked();
25060 final void updateOomAdjLocked() {
25061 final ActivityRecord TOP_ACT = resumedAppLocked();
25062 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
25063 final long now = SystemClock.uptimeMillis();
25064 final long nowElapsed = SystemClock.elapsedRealtime();
25065 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
25066 final int N = mLruProcesses.size();
25069 RuntimeException e = new RuntimeException();
25070 e.fillInStackTrace();
25071 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
25074 // Reset state in all uid records.
25075 for (int i=mActiveUids.size()-1; i>=0; i--) {
25076 final UidRecord uidRec = mActiveUids.valueAt(i);
25077 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
25078 "Starting update of " + uidRec);
25082 mStackSupervisor.rankTaskLayersIfNeeded();
25085 mNewNumServiceProcs = 0;
25086 mNewNumAServiceProcs = 0;
25088 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
25089 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
25091 // Let's determine how many processes we have running vs.
25092 // how many slots we have for background processes; we may want
25093 // to put multiple processes in a slot of there are enough of
25095 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
25096 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
25097 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
25098 if (numEmptyProcs > cachedProcessLimit) {
25099 // If there are more empty processes than our limit on cached
25100 // processes, then use the cached process limit for the factor.
25101 // This ensures that the really old empty processes get pushed
25102 // down to the bottom, so if we are running low on memory we will
25103 // have a better chance at keeping around more cached processes
25104 // instead of a gazillion empty processes.
25105 numEmptyProcs = cachedProcessLimit;
25107 int emptyFactor = numEmptyProcs/numSlots;
25108 if (emptyFactor < 1) emptyFactor = 1;
25109 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
25110 if (cachedFactor < 1) cachedFactor = 1;
25111 int stepCached = 0;
25115 int numTrimming = 0;
25117 mNumNonCachedProcs = 0;
25118 mNumCachedHiddenProcs = 0;
25120 // First update the OOM adjustment for each of the
25121 // application processes based on their current state.
25122 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
25123 int nextCachedAdj = curCachedAdj+1;
25124 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
25125 int nextEmptyAdj = curEmptyAdj+2;
25127 boolean retryCycles = false;
25129 // need to reset cycle state before calling computeOomAdjLocked because of service connections
25130 for (int i=N-1; i>=0; i--) {
25131 ProcessRecord app = mLruProcesses.get(i);
25132 app.containsCycle = false;
25134 for (int i=N-1; i>=0; i--) {
25135 ProcessRecord app = mLruProcesses.get(i);
25136 if (!app.killedByAm && app.thread != null) {
25137 app.procStateChanged = false;
25138 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
25140 // if any app encountered a cycle, we need to perform an additional loop later
25141 retryCycles |= app.containsCycle;
25143 // If we haven't yet assigned the final cached adj
25144 // to the process, do that now.
25145 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
25146 switch (app.curProcState) {
25147 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
25148 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
25149 case ActivityManager.PROCESS_STATE_CACHED_RECENT:
25150 // This process is a cached process holding activities...
25151 // assign it the next cached value for that type, and then
25152 // step that cached level.
25153 app.curRawAdj = curCachedAdj;
25154 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
25155 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
25156 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
25158 if (curCachedAdj != nextCachedAdj) {
25160 if (stepCached >= cachedFactor) {
25162 curCachedAdj = nextCachedAdj;
25163 nextCachedAdj += 2;
25164 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
25165 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
25171 // For everything else, assign next empty cached process
25172 // level and bump that up. Note that this means that
25173 // long-running services that have dropped down to the
25174 // cached level will be treated as empty (since their process
25175 // state is still as a service), which is what we want.
25176 app.curRawAdj = curEmptyAdj;
25177 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
25178 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
25179 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
25181 if (curEmptyAdj != nextEmptyAdj) {
25183 if (stepEmpty >= emptyFactor) {
25185 curEmptyAdj = nextEmptyAdj;
25187 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
25188 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
25201 // - Retry computing any process that has encountered a cycle.
25202 // - Continue retrying until no process was promoted.
25203 // - Iterate from least important to most important.
25204 int cycleCount = 0;
25205 while (retryCycles && cycleCount < 10) {
25207 retryCycles = false;
25209 for (int i=0; i<N; i++) {
25210 ProcessRecord app = mLruProcesses.get(i);
25211 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
25213 app.completedAdjSeq--;
25217 for (int i=0; i<N; i++) {
25218 ProcessRecord app = mLruProcesses.get(i);
25219 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
25221 if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now)) {
25222 retryCycles = true;
25228 for (int i=N-1; i>=0; i--) {
25229 ProcessRecord app = mLruProcesses.get(i);
25230 if (!app.killedByAm && app.thread != null) {
25231 applyOomAdjLocked(app, true, now, nowElapsed);
25233 // Count the number of process types.
25234 switch (app.curProcState) {
25235 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
25236 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
25237 mNumCachedHiddenProcs++;
25239 if (numCached > cachedProcessLimit) {
25240 app.kill("cached #" + numCached, true);
25243 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
25244 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
25245 && app.lastActivityTime < oldTime) {
25246 app.kill("empty for "
25247 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
25248 / 1000) + "s", true);
25251 if (numEmpty > emptyProcessLimit) {
25252 app.kill("empty #" + numEmpty, true);
25257 mNumNonCachedProcs++;
25261 if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
25262 // If this is an isolated process, there are no services
25263 // running in it, and it's not a special process with a
25264 // custom entry point, then the process is no longer
25265 // needed. We agressively kill these because we can by
25266 // definition not re-use the same process again, and it is
25267 // good to avoid having whatever code was running in them
25268 // left sitting around after no longer needed.
25269 app.kill("isolated not needed", true);
25271 // Keeping this process, update its uid.
25272 final UidRecord uidRec = app.uidRecord;
25273 if (uidRec != null) {
25274 uidRec.ephemeral = app.info.isInstantApp();
25275 if (uidRec.curProcState > app.curProcState) {
25276 uidRec.curProcState = app.curProcState;
25278 if (app.foregroundServices) {
25279 uidRec.foregroundServices = true;
25284 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
25285 && !app.killedByAm) {
25291 incrementProcStateSeqAndNotifyAppsLocked();
25293 mNumServiceProcs = mNewNumServiceProcs;
25295 // Now determine the memory trimming level of background processes.
25296 // Unfortunately we need to start at the back of the list to do this
25297 // properly. We only do this if the number of background apps we
25298 // are managing to keep around is less than half the maximum we desire;
25299 // if we are keeping a good number around, we'll let them use whatever
25300 // memory they want.
25301 final int numCachedAndEmpty = numCached + numEmpty;
25303 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
25304 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
25305 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
25306 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
25307 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
25308 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
25310 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
25313 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
25315 // We always allow the memory level to go up (better). We only allow it to go
25316 // down if we are in a state where that is allowed, *and* the total number of processes
25317 // has gone down since last time.
25318 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
25319 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
25320 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
25321 if (memFactor > mLastMemoryLevel) {
25322 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
25323 memFactor = mLastMemoryLevel;
25324 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
25327 if (memFactor != mLastMemoryLevel) {
25328 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
25330 mLastMemoryLevel = memFactor;
25331 mLastNumProcesses = mLruProcesses.size();
25332 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
25333 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
25334 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
25335 if (mLowRamStartTime == 0) {
25336 mLowRamStartTime = now;
25340 switch (memFactor) {
25341 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
25342 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
25344 case ProcessStats.ADJ_MEM_FACTOR_LOW:
25345 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
25348 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
25351 int factor = numTrimming/3;
25353 if (mHomeProcess != null) minFactor++;
25354 if (mPreviousProcess != null) minFactor++;
25355 if (factor < minFactor) factor = minFactor;
25356 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
25357 for (int i=N-1; i>=0; i--) {
25358 ProcessRecord app = mLruProcesses.get(i);
25359 if (allChanged || app.procStateChanged) {
25360 setProcessTrackerStateLocked(app, trackerMemFactor, now);
25361 app.procStateChanged = false;
25363 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
25364 && !app.killedByAm) {
25365 if (app.trimMemoryLevel < curLevel && app.thread != null) {
25367 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25368 "Trimming memory of " + app.processName + " to " + curLevel);
25369 app.thread.scheduleTrimMemory(curLevel);
25370 } catch (RemoteException e) {
25373 // For now we won't do this; our memory trimming seems
25374 // to be good enough at this point that destroying
25375 // activities causes more harm than good.
25376 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
25377 && app != mHomeProcess && app != mPreviousProcess) {
25378 // Need to do this on its own message because the stack may not
25379 // be in a consistent state at this point.
25380 // For these apps we will also finish their activities
25381 // to help them free memory.
25382 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
25386 app.trimMemoryLevel = curLevel;
25388 if (step >= factor) {
25390 switch (curLevel) {
25391 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
25392 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
25394 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
25395 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
25399 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
25400 && !app.killedByAm) {
25401 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
25402 && app.thread != null) {
25404 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25405 "Trimming memory of heavy-weight " + app.processName
25406 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
25407 app.thread.scheduleTrimMemory(
25408 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
25409 } catch (RemoteException e) {
25412 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
25414 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
25415 || app.systemNoUi) && app.pendingUiClean) {
25416 // If this application is now in the background and it
25417 // had done UI, then give it the special trim level to
25418 // have it free UI resources.
25419 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
25420 if (app.trimMemoryLevel < level && app.thread != null) {
25422 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25423 "Trimming memory of bg-ui " + app.processName
25425 app.thread.scheduleTrimMemory(level);
25426 } catch (RemoteException e) {
25429 app.pendingUiClean = false;
25431 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
25433 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25434 "Trimming memory of fg " + app.processName
25435 + " to " + fgTrimLevel);
25436 app.thread.scheduleTrimMemory(fgTrimLevel);
25437 } catch (RemoteException e) {
25440 app.trimMemoryLevel = fgTrimLevel;
25444 if (mLowRamStartTime != 0) {
25445 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
25446 mLowRamStartTime = 0;
25448 for (int i=N-1; i>=0; i--) {
25449 ProcessRecord app = mLruProcesses.get(i);
25450 if (allChanged || app.procStateChanged) {
25451 setProcessTrackerStateLocked(app, trackerMemFactor, now);
25452 app.procStateChanged = false;
25454 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
25455 || app.systemNoUi) && app.pendingUiClean) {
25456 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
25457 && app.thread != null) {
25459 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25460 "Trimming memory of ui hidden " + app.processName
25461 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
25462 app.thread.scheduleTrimMemory(
25463 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
25464 } catch (RemoteException e) {
25467 app.pendingUiClean = false;
25469 app.trimMemoryLevel = 0;
25473 if (mAlwaysFinishActivities) {
25474 // Need to do this on its own message because the stack may not
25475 // be in a consistent state at this point.
25476 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
25480 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
25483 ArrayList<UidRecord> becameIdle = null;
25485 // Update from any uid changes.
25486 if (mLocalPowerManager != null) {
25487 mLocalPowerManager.startUidChanges();
25489 for (int i=mActiveUids.size()-1; i>=0; i--) {
25490 final UidRecord uidRec = mActiveUids.valueAt(i);
25491 int uidChange = UidRecord.CHANGE_PROCSTATE;
25492 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
25493 && (uidRec.setProcState != uidRec.curProcState
25494 || uidRec.setWhitelist != uidRec.curWhitelist)) {
25495 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
25496 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
25497 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
25498 + " to " + uidRec.curWhitelist);
25499 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
25500 && !uidRec.curWhitelist) {
25501 // UID is now in the background (and not on the temp whitelist). Was it
25502 // previously in the foreground (or on the temp whitelist)?
25503 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
25504 || uidRec.setWhitelist) {
25505 uidRec.lastBackgroundTime = nowElapsed;
25506 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
25507 // Note: the background settle time is in elapsed realtime, while
25508 // the handler time base is uptime. All this means is that we may
25509 // stop background uids later than we had intended, but that only
25510 // happens because the device was sleeping so we are okay anyway.
25511 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
25512 mConstants.BACKGROUND_SETTLE_TIME);
25515 if (uidRec.idle && !uidRec.setIdle) {
25516 uidChange = UidRecord.CHANGE_IDLE;
25517 if (becameIdle == null) {
25518 becameIdle = new ArrayList<>();
25520 becameIdle.add(uidRec);
25524 uidChange = UidRecord.CHANGE_ACTIVE;
25525 EventLogTags.writeAmUidActive(uidRec.uid);
25526 uidRec.idle = false;
25528 uidRec.lastBackgroundTime = 0;
25530 final boolean wasCached = uidRec.setProcState
25531 > ActivityManager.PROCESS_STATE_RECEIVER;
25532 final boolean isCached = uidRec.curProcState
25533 > ActivityManager.PROCESS_STATE_RECEIVER;
25534 if (wasCached != isCached ||
25535 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
25536 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
25538 uidRec.setProcState = uidRec.curProcState;
25539 uidRec.setWhitelist = uidRec.curWhitelist;
25540 uidRec.setIdle = uidRec.idle;
25541 enqueueUidChangeLocked(uidRec, -1, uidChange);
25542 noteUidProcessState(uidRec.uid, uidRec.curProcState);
25543 if (uidRec.foregroundServices) {
25544 mServices.foregroundServiceProcStateChangedLocked(uidRec);
25548 if (mLocalPowerManager != null) {
25549 mLocalPowerManager.finishUidChanges();
25552 if (becameIdle != null) {
25553 // If we have any new uids that became idle this time, we need to make sure
25554 // they aren't left with running services.
25555 for (int i = becameIdle.size() - 1; i >= 0; i--) {
25556 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
25560 if (mProcessStats.shouldWriteNowLocked(now)) {
25561 mHandler.post(new Runnable() {
25562 @Override public void run() {
25563 synchronized (ActivityManagerService.this) {
25564 mProcessStats.writeStateAsyncLocked();
25570 if (DEBUG_OOM_ADJ) {
25571 final long duration = SystemClock.uptimeMillis() - now;
25573 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
25574 new RuntimeException("here").fillInStackTrace());
25576 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
25582 public void makePackageIdle(String packageName, int userId) {
25583 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
25584 != PackageManager.PERMISSION_GRANTED) {
25585 String msg = "Permission Denial: makePackageIdle() from pid="
25586 + Binder.getCallingPid()
25587 + ", uid=" + Binder.getCallingUid()
25588 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
25590 throw new SecurityException(msg);
25592 final int callingPid = Binder.getCallingPid();
25593 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
25594 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
25595 long callingId = Binder.clearCallingIdentity();
25596 synchronized(this) {
25598 IPackageManager pm = AppGlobals.getPackageManager();
25601 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
25602 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
25603 } catch (RemoteException e) {
25605 if (pkgUid == -1) {
25606 throw new IllegalArgumentException("Unknown package name " + packageName);
25609 if (mLocalPowerManager != null) {
25610 mLocalPowerManager.startUidChanges();
25612 final int appId = UserHandle.getAppId(pkgUid);
25613 final int N = mActiveUids.size();
25614 for (int i=N-1; i>=0; i--) {
25615 final UidRecord uidRec = mActiveUids.valueAt(i);
25616 final long bgTime = uidRec.lastBackgroundTime;
25617 if (bgTime > 0 && !uidRec.idle) {
25618 if (UserHandle.getAppId(uidRec.uid) == appId) {
25619 if (userId == UserHandle.USER_ALL ||
25620 userId == UserHandle.getUserId(uidRec.uid)) {
25621 EventLogTags.writeAmUidIdle(uidRec.uid);
25622 uidRec.idle = true;
25623 uidRec.setIdle = true;
25624 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
25625 + " from package " + packageName + " user " + userId);
25626 doStopUidLocked(uidRec.uid, uidRec);
25632 if (mLocalPowerManager != null) {
25633 mLocalPowerManager.finishUidChanges();
25635 Binder.restoreCallingIdentity(callingId);
25640 final void idleUids() {
25641 synchronized (this) {
25642 final int N = mActiveUids.size();
25646 final long nowElapsed = SystemClock.elapsedRealtime();
25647 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
25649 if (mLocalPowerManager != null) {
25650 mLocalPowerManager.startUidChanges();
25652 for (int i=N-1; i>=0; i--) {
25653 final UidRecord uidRec = mActiveUids.valueAt(i);
25654 final long bgTime = uidRec.lastBackgroundTime;
25655 if (bgTime > 0 && !uidRec.idle) {
25656 if (bgTime <= maxBgTime) {
25657 EventLogTags.writeAmUidIdle(uidRec.uid);
25658 uidRec.idle = true;
25659 uidRec.setIdle = true;
25660 doStopUidLocked(uidRec.uid, uidRec);
25662 if (nextTime == 0 || nextTime > bgTime) {
25668 if (mLocalPowerManager != null) {
25669 mLocalPowerManager.finishUidChanges();
25671 if (nextTime > 0) {
25672 mHandler.removeMessages(IDLE_UIDS_MSG);
25673 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
25674 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
25680 * Checks if any uid is coming from background to foreground or vice versa and if so, increments
25681 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
25682 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
25686 void incrementProcStateSeqAndNotifyAppsLocked() {
25687 if (mWaitForNetworkTimeoutMs <= 0) {
25690 // Used for identifying which uids need to block for network.
25691 ArrayList<Integer> blockingUids = null;
25692 for (int i = mActiveUids.size() - 1; i >= 0; --i) {
25693 final UidRecord uidRec = mActiveUids.valueAt(i);
25694 // If the network is not restricted for uid, then nothing to do here.
25695 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
25698 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
25701 // If process state is not changed, then there's nothing to do.
25702 if (uidRec.setProcState == uidRec.curProcState) {
25705 final int blockState = getBlockStateForUid(uidRec);
25706 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
25707 // there's nothing the app needs to do in this scenario.
25708 if (blockState == NETWORK_STATE_NO_CHANGE) {
25711 synchronized (uidRec.networkStateLock) {
25712 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
25713 if (blockState == NETWORK_STATE_BLOCK) {
25714 if (blockingUids == null) {
25715 blockingUids = new ArrayList<>();
25717 blockingUids.add(uidRec.uid);
25719 if (DEBUG_NETWORK) {
25720 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
25721 + " threads for uid: " + uidRec);
25723 if (uidRec.waitingForNetwork) {
25724 uidRec.networkStateLock.notifyAll();
25730 // There are no uids that need to block, so nothing more to do.
25731 if (blockingUids == null) {
25735 for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
25736 final ProcessRecord app = mLruProcesses.get(i);
25737 if (!blockingUids.contains(app.uid)) {
25740 if (!app.killedByAm && app.thread != null) {
25741 final UidRecord uidRec = mActiveUids.get(app.uid);
25743 if (DEBUG_NETWORK) {
25744 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
25747 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
25748 } catch (RemoteException ignored) {
25755 * Checks if the uid is coming from background to foreground or vice versa and returns
25756 * appropriate block state based on this.
25758 * @return blockState based on whether the uid is coming from background to foreground or
25759 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
25760 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
25761 * {@link #NETWORK_STATE_NO_CHANGE}.
25764 int getBlockStateForUid(UidRecord uidRec) {
25765 // Denotes whether uid's process state is currently allowed network access.
25766 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
25767 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
25768 // Denotes whether uid's process state was previously allowed network access.
25769 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
25770 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
25772 // When the uid is coming to foreground, AMS should inform the app thread that it should
25773 // block for the network rules to get updated before launching an activity.
25774 if (!wasAllowed && isAllowed) {
25775 return NETWORK_STATE_BLOCK;
25777 // When the uid is going to background, AMS should inform the app thread that if an
25778 // activity launch is blocked for the network rules to get updated, it should be unblocked.
25779 if (wasAllowed && !isAllowed) {
25780 return NETWORK_STATE_UNBLOCK;
25782 return NETWORK_STATE_NO_CHANGE;
25785 final void runInBackgroundDisabled(int uid) {
25786 synchronized (this) {
25787 UidRecord uidRec = mActiveUids.get(uid);
25788 if (uidRec != null) {
25789 // This uid is actually running... should it be considered background now?
25791 doStopUidLocked(uidRec.uid, uidRec);
25794 // This uid isn't actually running... still send a report about it being "stopped".
25795 doStopUidLocked(uid, null);
25801 * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
25803 void doStopUidForIdleUidsLocked() {
25804 final int size = mActiveUids.size();
25805 for (int i = 0; i < size; i++) {
25806 final int uid = mActiveUids.keyAt(i);
25807 if (UserHandle.isCore(uid)) {
25810 final UidRecord uidRec = mActiveUids.valueAt(i);
25811 if (!uidRec.idle) {
25814 doStopUidLocked(uidRec.uid, uidRec);
25818 final void doStopUidLocked(int uid, final UidRecord uidRec) {
25819 mServices.stopInBackgroundLocked(uid);
25820 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
25824 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25827 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
25828 long duration, String tag) {
25829 if (DEBUG_WHITELISTS) {
25830 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
25831 + targetUid + ", " + duration + ")");
25834 synchronized (mPidsSelfLocked) {
25835 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
25837 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
25841 if (!pr.whitelistManager) {
25842 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
25843 != PackageManager.PERMISSION_GRANTED) {
25844 if (DEBUG_WHITELISTS) {
25845 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
25846 + ": pid " + callerPid + " is not allowed");
25853 tempWhitelistUidLocked(targetUid, duration, tag);
25857 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25860 void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
25861 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
25862 setUidTempWhitelistStateLocked(targetUid, true);
25863 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
25866 void pushTempWhitelist() {
25868 final PendingTempWhitelist[] list;
25870 // First copy out the pending changes... we need to leave them in the map for now,
25871 // in case someone needs to check what is coming up while we don't have the lock held.
25872 synchronized(this) {
25873 N = mPendingTempWhitelist.size();
25874 list = new PendingTempWhitelist[N];
25875 for (int i = 0; i < N; i++) {
25876 list[i] = mPendingTempWhitelist.valueAt(i);
25880 // Now safely dispatch changes to device idle controller.
25881 for (int i = 0; i < N; i++) {
25882 PendingTempWhitelist ptw = list[i];
25883 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
25884 ptw.duration, true, ptw.tag);
25887 // And now we can safely remove them from the map.
25888 synchronized(this) {
25889 for (int i = 0; i < N; i++) {
25890 PendingTempWhitelist ptw = list[i];
25891 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
25892 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
25893 mPendingTempWhitelist.removeAt(index);
25900 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
25901 boolean changed = false;
25902 for (int i=mActiveUids.size()-1; i>=0; i--) {
25903 final UidRecord uidRec = mActiveUids.valueAt(i);
25904 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
25905 uidRec.curWhitelist = onWhitelist;
25910 updateOomAdjLocked();
25915 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
25916 boolean changed = false;
25917 final UidRecord uidRec = mActiveUids.get(uid);
25918 if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
25919 uidRec.curWhitelist = onWhitelist;
25920 updateOomAdjLocked();
25924 final void trimApplications() {
25925 synchronized (this) {
25926 trimApplicationsLocked();
25930 final void trimApplicationsLocked() {
25931 // First remove any unused application processes whose package
25932 // has been removed.
25933 for (int i=mRemovedProcesses.size()-1; i>=0; i--) {
25934 final ProcessRecord app = mRemovedProcesses.get(i);
25935 if (app.activities.size() == 0 && app.recentTasks.size() == 0
25936 && app.curReceivers.isEmpty() && app.services.size() == 0) {
25938 TAG, "Exiting empty application process "
25939 + app.toShortString() + " ("
25940 + (app.thread != null ? app.thread.asBinder() : null)
25942 if (app.pid > 0 && app.pid != MY_PID) {
25943 app.kill("empty", false);
25944 } else if (app.thread != null) {
25946 app.thread.scheduleExit();
25947 } catch (Exception e) {
25948 // Ignore exceptions.
25951 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
25952 mRemovedProcesses.remove(i);
25954 if (app.persistent) {
25955 addAppLocked(app.info, null, false, null /* ABI override */);
25960 // Now update the oom adj for all processes. Don't skip this, since other callers
25961 // might be depending on it.
25962 updateOomAdjLocked();
25965 /** This method sends the specified signal to each of the persistent apps */
25966 public void signalPersistentProcesses(int sig) throws RemoteException {
25967 if (sig != SIGNAL_USR1) {
25968 throw new SecurityException("Only SIGNAL_USR1 is allowed");
25971 synchronized (this) {
25972 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
25973 != PackageManager.PERMISSION_GRANTED) {
25974 throw new SecurityException("Requires permission "
25975 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
25978 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
25979 ProcessRecord r = mLruProcesses.get(i);
25980 if (r.thread != null && r.persistent) {
25981 sendSignal(r.pid, sig);
25987 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
25988 if (proc == null || proc == mProfileProc) {
25989 proc = mProfileProc;
25990 profileType = mProfileType;
25991 clearProfilerLocked();
25993 if (proc == null) {
25997 proc.thread.profilerControl(false, null, profileType);
25998 } catch (RemoteException e) {
25999 throw new IllegalStateException("Process disappeared");
26003 private void clearProfilerLocked() {
26004 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
26006 mProfilerInfo.profileFd.close();
26007 } catch (IOException e) {
26010 mProfileApp = null;
26011 mProfileProc = null;
26012 mProfilerInfo = null;
26015 public boolean profileControl(String process, int userId, boolean start,
26016 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
26019 synchronized (this) {
26020 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
26021 // its own permission.
26022 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26023 != PackageManager.PERMISSION_GRANTED) {
26024 throw new SecurityException("Requires permission "
26025 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26028 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
26029 throw new IllegalArgumentException("null profile info or fd");
26032 ProcessRecord proc = null;
26033 if (process != null) {
26034 proc = findProcessLocked(process, userId, "profileControl");
26037 if (start && (proc == null || proc.thread == null)) {
26038 throw new IllegalArgumentException("Unknown process: " + process);
26042 stopProfilerLocked(null, 0);
26043 setProfileApp(proc.info, proc.processName, profilerInfo);
26044 mProfileProc = proc;
26045 mProfileType = profileType;
26046 ParcelFileDescriptor fd = profilerInfo.profileFd;
26049 } catch (IOException e) {
26052 profilerInfo.profileFd = fd;
26053 proc.thread.profilerControl(start, profilerInfo, profileType);
26056 mProfilerInfo.profileFd.close();
26057 } catch (IOException e) {
26059 mProfilerInfo.profileFd = null;
26061 if (proc.pid == MY_PID) {
26062 // When profiling the system server itself, avoid closing the file
26063 // descriptor, as profilerControl will not create a copy.
26064 // Note: it is also not correct to just set profileFd to null, as the
26065 // whole ProfilerInfo instance is passed down!
26066 profilerInfo = null;
26069 stopProfilerLocked(proc, profileType);
26070 if (profilerInfo != null && profilerInfo.profileFd != null) {
26072 profilerInfo.profileFd.close();
26073 } catch (IOException e) {
26080 } catch (RemoteException e) {
26081 throw new IllegalStateException("Process disappeared");
26083 if (profilerInfo != null && profilerInfo.profileFd != null) {
26085 profilerInfo.profileFd.close();
26086 } catch (IOException e) {
26092 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
26093 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
26094 userId, true, ALLOW_FULL_ONLY, callName, null);
26095 ProcessRecord proc = null;
26097 int pid = Integer.parseInt(process);
26098 synchronized (mPidsSelfLocked) {
26099 proc = mPidsSelfLocked.get(pid);
26101 } catch (NumberFormatException e) {
26104 if (proc == null) {
26105 ArrayMap<String, SparseArray<ProcessRecord>> all
26106 = mProcessNames.getMap();
26107 SparseArray<ProcessRecord> procs = all.get(process);
26108 if (procs != null && procs.size() > 0) {
26109 proc = procs.valueAt(0);
26110 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
26111 for (int i=1; i<procs.size(); i++) {
26112 ProcessRecord thisProc = procs.valueAt(i);
26113 if (thisProc.userId == userId) {
26125 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
26126 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
26129 synchronized (this) {
26130 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
26131 // its own permission (same as profileControl).
26132 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26133 != PackageManager.PERMISSION_GRANTED) {
26134 throw new SecurityException("Requires permission "
26135 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26139 throw new IllegalArgumentException("null fd");
26142 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
26143 if (proc == null || proc.thread == null) {
26144 throw new IllegalArgumentException("Unknown process: " + process);
26147 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26148 if (!isDebuggable) {
26149 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26150 throw new SecurityException("Process not debuggable: " + proc);
26154 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
26158 } catch (RemoteException e) {
26159 throw new IllegalStateException("Process disappeared");
26164 } catch (IOException e) {
26171 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
26172 String reportPackage) {
26173 if (processName != null) {
26174 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
26175 "setDumpHeapDebugLimit()");
26177 synchronized (mPidsSelfLocked) {
26178 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
26179 if (proc == null) {
26180 throw new SecurityException("No process found for calling pid "
26181 + Binder.getCallingPid());
26183 if (!Build.IS_DEBUGGABLE
26184 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26185 throw new SecurityException("Not running a debuggable build");
26187 processName = proc.processName;
26189 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
26190 throw new SecurityException("Package " + reportPackage + " is not running in "
26195 synchronized (this) {
26196 if (maxMemSize > 0) {
26197 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
26200 mMemWatchProcesses.remove(processName, uid);
26202 mMemWatchProcesses.getMap().remove(processName);
26209 public void dumpHeapFinished(String path) {
26210 synchronized (this) {
26211 if (Binder.getCallingPid() != mMemWatchDumpPid) {
26212 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
26213 + " does not match last pid " + mMemWatchDumpPid);
26216 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
26217 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
26218 + " does not match last path " + mMemWatchDumpFile);
26221 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
26222 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
26224 // Forced gc to clean up the remnant hprof fd.
26225 Runtime.getRuntime().gc();
26229 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
26230 public void monitor() {
26231 synchronized (this) { }
26234 void onCoreSettingsChange(Bundle settings) {
26235 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
26236 ProcessRecord processRecord = mLruProcesses.get(i);
26238 if (processRecord.thread != null) {
26239 processRecord.thread.setCoreSettings(settings);
26241 } catch (RemoteException re) {
26247 // Multi-user methods
26250 * Start user, if its not already running, but don't bring it to foreground.
26253 public boolean startUserInBackground(final int userId) {
26254 return startUserInBackgroundWithListener(userId, null);
26258 public boolean startUserInBackgroundWithListener(final int userId,
26259 @Nullable IProgressListener unlockListener) {
26260 return mUserController.startUser(userId, /* foreground */ false, unlockListener);
26264 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
26265 return mUserController.unlockUser(userId, token, secret, listener);
26269 public boolean switchUser(final int targetUserId) {
26270 return mUserController.switchUser(targetUserId);
26274 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
26275 return mUserController.stopUser(userId, force, callback);
26279 public UserInfo getCurrentUser() {
26280 return mUserController.getCurrentUser();
26283 String getStartedUserState(int userId) {
26284 final UserState userState = mUserController.getStartedUserState(userId);
26285 return UserState.stateToString(userState.state);
26289 public boolean isUserRunning(int userId, int flags) {
26290 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
26291 && checkCallingPermission(INTERACT_ACROSS_USERS)
26292 != PackageManager.PERMISSION_GRANTED) {
26293 String msg = "Permission Denial: isUserRunning() from pid="
26294 + Binder.getCallingPid()
26295 + ", uid=" + Binder.getCallingUid()
26296 + " requires " + INTERACT_ACROSS_USERS;
26298 throw new SecurityException(msg);
26300 return mUserController.isUserRunning(userId, flags);
26304 public int[] getRunningUserIds() {
26305 if (checkCallingPermission(INTERACT_ACROSS_USERS)
26306 != PackageManager.PERMISSION_GRANTED) {
26307 String msg = "Permission Denial: isUserRunning() from pid="
26308 + Binder.getCallingPid()
26309 + ", uid=" + Binder.getCallingUid()
26310 + " requires " + INTERACT_ACROSS_USERS;
26312 throw new SecurityException(msg);
26314 return mUserController.getStartedUserArray();
26318 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
26319 mUserController.registerUserSwitchObserver(observer, name);
26323 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
26324 mUserController.unregisterUserSwitchObserver(observer);
26327 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
26328 if (info == null) return null;
26329 ApplicationInfo newInfo = new ApplicationInfo(info);
26330 newInfo.initForUser(userId);
26334 public boolean isUserStopped(int userId) {
26335 return mUserController.getStartedUserState(userId) == null;
26338 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
26340 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
26344 ActivityInfo info = new ActivityInfo(aInfo);
26345 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
26349 private boolean processSanityChecksLocked(ProcessRecord process) {
26350 if (process == null || process.thread == null) {
26354 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26355 if (!isDebuggable) {
26356 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26364 public boolean startBinderTracking() throws RemoteException {
26365 synchronized (this) {
26366 mBinderTransactionTrackingEnabled = true;
26367 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
26368 // permission (same as profileControl).
26369 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26370 != PackageManager.PERMISSION_GRANTED) {
26371 throw new SecurityException("Requires permission "
26372 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26375 for (int i = 0; i < mLruProcesses.size(); i++) {
26376 ProcessRecord process = mLruProcesses.get(i);
26377 if (!processSanityChecksLocked(process)) {
26381 process.thread.startBinderTracking();
26382 } catch (RemoteException e) {
26383 Log.v(TAG, "Process disappared");
26390 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
26392 synchronized (this) {
26393 mBinderTransactionTrackingEnabled = false;
26394 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
26395 // permission (same as profileControl).
26396 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26397 != PackageManager.PERMISSION_GRANTED) {
26398 throw new SecurityException("Requires permission "
26399 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26403 throw new IllegalArgumentException("null fd");
26406 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
26407 pw.println("Binder transaction traces for all processes.\n");
26408 for (ProcessRecord process : mLruProcesses) {
26409 if (!processSanityChecksLocked(process)) {
26413 pw.println("Traces for process: " + process.processName);
26416 TransferPipe tp = new TransferPipe();
26418 process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
26419 tp.go(fd.getFileDescriptor());
26423 } catch (IOException e) {
26424 pw.println("Failure while dumping IPC traces from " + process +
26425 ". Exception: " + e);
26427 } catch (RemoteException e) {
26428 pw.println("Got a RemoteException while dumping IPC traces from " +
26429 process + ". Exception: " + e);
26440 } catch (IOException e) {
26447 final class LocalService extends ActivityManagerInternal {
26449 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
26450 int targetUserId) {
26451 synchronized (ActivityManagerService.this) {
26452 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
26453 targetPkg, intent, null, targetUserId);
26458 public String checkContentProviderAccess(String authority, int userId) {
26459 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
26463 public void onWakefulnessChanged(int wakefulness) {
26464 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
26468 public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
26469 String processName, String abiOverride, int uid, Runnable crashHandler) {
26470 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
26471 processName, abiOverride, uid, crashHandler);
26475 public SleepToken acquireSleepToken(String tag, int displayId) {
26476 Preconditions.checkNotNull(tag);
26477 return ActivityManagerService.this.acquireSleepToken(tag, displayId);
26481 public ComponentName getHomeActivityForUser(int userId) {
26482 synchronized (ActivityManagerService.this) {
26483 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
26484 return homeActivity == null ? null : homeActivity.realActivity;
26489 public void onUserRemoved(int userId) {
26490 synchronized (ActivityManagerService.this) {
26491 ActivityManagerService.this.onUserStoppedLocked(userId);
26493 mBatteryStatsService.onUserRemoved(userId);
26494 mUserController.onUserRemoved(userId);
26498 public void onLocalVoiceInteractionStarted(IBinder activity,
26499 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
26500 synchronized (ActivityManagerService.this) {
26501 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
26502 voiceSession, voiceInteractor);
26507 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
26508 synchronized (ActivityManagerService.this) {
26509 mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
26510 reasons, timestamp);
26515 public void notifyAppTransitionFinished() {
26516 synchronized (ActivityManagerService.this) {
26517 mStackSupervisor.notifyAppTransitionDone();
26522 public void notifyAppTransitionCancelled() {
26523 synchronized (ActivityManagerService.this) {
26524 mStackSupervisor.notifyAppTransitionDone();
26529 public List<IBinder> getTopVisibleActivities() {
26530 synchronized (ActivityManagerService.this) {
26531 return mStackSupervisor.getTopVisibleActivities();
26536 public void notifyDockedStackMinimizedChanged(boolean minimized) {
26537 synchronized (ActivityManagerService.this) {
26538 mStackSupervisor.setDockedStackMinimized(minimized);
26543 public void killForegroundAppsForUser(int userHandle) {
26544 synchronized (ActivityManagerService.this) {
26545 final ArrayList<ProcessRecord> procs = new ArrayList<>();
26546 final int NP = mProcessNames.getMap().size();
26547 for (int ip = 0; ip < NP; ip++) {
26548 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
26549 final int NA = apps.size();
26550 for (int ia = 0; ia < NA; ia++) {
26551 final ProcessRecord app = apps.valueAt(ia);
26552 if (app.persistent) {
26553 // We don't kill persistent processes.
26558 } else if (app.userId == userHandle && app.foregroundActivities) {
26559 app.removed = true;
26565 final int N = procs.size();
26566 for (int i = 0; i < N; i++) {
26567 removeProcessLocked(procs.get(i), false, true, "kill all fg");
26573 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
26575 if (!(target instanceof PendingIntentRecord)) {
26576 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
26579 synchronized (ActivityManagerService.this) {
26580 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
26585 public void setDeviceIdleWhitelist(int[] allAppids, int[] exceptIdleAppids) {
26586 synchronized (ActivityManagerService.this) {
26587 mDeviceIdleWhitelist = allAppids;
26588 mDeviceIdleExceptIdleWhitelist = exceptIdleAppids;
26593 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
26594 synchronized (ActivityManagerService.this) {
26595 mDeviceIdleTempWhitelist = appids;
26596 setAppIdTempWhitelistStateLocked(changingAppId, adding);
26601 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
26603 Preconditions.checkNotNull(values, "Configuration must not be null");
26604 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
26605 synchronized (ActivityManagerService.this) {
26606 updateConfigurationLocked(values, null, false, true, userId,
26607 false /* deferResume */);
26612 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
26614 Preconditions.checkNotNull(intents, "intents");
26615 final String[] resolvedTypes = new String[intents.length];
26617 // UID of the package on user userId.
26618 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
26619 // packageUid may not be initialized.
26620 int packageUid = 0;
26621 final long ident = Binder.clearCallingIdentity();
26624 for (int i = 0; i < intents.length; i++) {
26626 intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
26629 packageUid = AppGlobals.getPackageManager().getPackageUid(
26630 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
26631 } catch (RemoteException e) {
26632 // Shouldn't happen.
26634 Binder.restoreCallingIdentity(ident);
26637 synchronized (ActivityManagerService.this) {
26638 return mActivityStartController.startActivitiesInPackage(
26639 packageUid, packageName,
26640 intents, resolvedTypes, null /* resultTo */,
26641 SafeActivityOptions.fromBundle(bOptions), userId,
26642 false /* validateIncomingUser */, null /* originatingPendingIntent */);
26647 public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
26648 Intent intent, Bundle options, int userId) {
26649 return ActivityManagerService.this.startActivityAsUser(
26650 caller, callerPacakge, intent,
26651 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
26652 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
26653 false /*validateIncomingUser*/);
26657 public int getUidProcessState(int uid) {
26658 return getUidState(uid);
26662 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
26663 synchronized (ActivityManagerService.this) {
26665 // We might change the visibilities here, so prepare an empty app transition which
26666 // might be overridden later if we actually change visibilities.
26667 final boolean wasTransitionSet =
26668 mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
26669 if (!wasTransitionSet) {
26670 mWindowManager.prepareAppTransition(TRANSIT_NONE,
26671 false /* alwaysKeepCurrent */);
26673 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26675 // If there was a transition set already we don't want to interfere with it as we
26676 // might be starting it too early.
26677 if (!wasTransitionSet) {
26678 mWindowManager.executeAppTransition();
26681 if (callback != null) {
26687 public boolean isSystemReady() {
26688 // no need to synchronize(this) just to read & return the value
26689 return mSystemReady;
26693 public void notifyKeyguardTrustedChanged() {
26694 synchronized (ActivityManagerService.this) {
26695 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
26696 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26702 * Sets if the given pid has an overlay UI or not.
26704 * @param pid The pid we are setting overlay UI for.
26705 * @param hasOverlayUi True if the process has overlay UI.
26706 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
26709 public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
26710 synchronized (ActivityManagerService.this) {
26711 final ProcessRecord pr;
26712 synchronized (mPidsSelfLocked) {
26713 pr = mPidsSelfLocked.get(pid);
26715 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
26719 if (pr.hasOverlayUi == hasOverlayUi) {
26722 pr.hasOverlayUi = hasOverlayUi;
26723 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
26724 updateOomAdjLocked(pr, true);
26729 public void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
26730 ActivityManagerService.this.setRunningRemoteAnimation(pid, runningRemoteAnimation);
26734 * Called after the network policy rules are updated by
26735 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
26736 * and {@param procStateSeq}.
26739 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
26740 if (DEBUG_NETWORK) {
26741 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
26742 + uid + " seq: " + procStateSeq);
26745 synchronized (ActivityManagerService.this) {
26746 record = mActiveUids.get(uid);
26747 if (record == null) {
26748 if (DEBUG_NETWORK) {
26749 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
26750 + " procStateSeq: " + procStateSeq);
26755 synchronized (record.networkStateLock) {
26756 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26757 if (DEBUG_NETWORK) {
26758 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
26759 + " been handled for uid: " + uid);
26763 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
26764 if (record.curProcStateSeq > procStateSeq) {
26765 if (DEBUG_NETWORK) {
26766 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
26767 + ", curProcstateSeq: " + record.curProcStateSeq
26768 + ", procStateSeq: " + procStateSeq);
26772 if (record.waitingForNetwork) {
26773 if (DEBUG_NETWORK) {
26774 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
26775 + ", procStateSeq: " + procStateSeq);
26777 record.networkStateLock.notifyAll();
26783 public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
26784 synchronized (ActivityManagerService.this) {
26785 mActiveVoiceInteractionServiceComponent = component;
26790 * Called after virtual display Id is updated by
26791 * {@link com.android.server.vr.Vr2dDisplay} with a specific
26792 * {@param vrVr2dDisplayId}.
26795 public void setVr2dDisplayId(int vr2dDisplayId) {
26797 Slog.d(TAG, "setVr2dDisplayId called for: " +
26800 synchronized (ActivityManagerService.this) {
26801 mVr2dDisplayId = vr2dDisplayId;
26806 public void saveANRState(String reason) {
26807 synchronized (ActivityManagerService.this) {
26808 final StringWriter sw = new StringWriter();
26809 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
26810 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
26811 if (reason != null) {
26812 pw.println(" Reason: " + reason);
26815 mActivityStartController.dump(pw, " ", null);
26817 pw.println("-------------------------------------------------------------------------------");
26818 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
26819 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
26824 mLastANRState = sw.toString();
26829 public void clearSavedANRState() {
26830 synchronized (ActivityManagerService.this) {
26831 mLastANRState = null;
26836 public void setFocusedActivity(IBinder token) {
26837 synchronized (ActivityManagerService.this) {
26838 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
26840 throw new IllegalArgumentException(
26841 "setFocusedActivity: No activity record matching token=" + token);
26843 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
26844 r, "setFocusedActivity")) {
26845 mStackSupervisor.resumeFocusedStackTopActivityLocked();
26851 public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
26852 synchronized (ActivityManagerService.this) {
26853 if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
26854 ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
26855 if (types == null) {
26859 types = new ArrayMap<>();
26860 mAllowAppSwitchUids.put(userId, types);
26863 types.remove(type);
26865 types.put(type, uid);
26872 public boolean isRuntimeRestarted() {
26873 return mSystemServiceManager.isRuntimeRestarted();
26877 public boolean hasRunningActivity(int uid, @Nullable String packageName) {
26878 if (packageName == null) return false;
26880 synchronized (ActivityManagerService.this) {
26881 for (int i = 0; i < mLruProcesses.size(); i++) {
26882 final ProcessRecord processRecord = mLruProcesses.get(i);
26883 if (processRecord.uid == uid) {
26884 for (int j = 0; j < processRecord.activities.size(); j++) {
26885 final ActivityRecord activityRecord = processRecord.activities.get(j);
26886 if (packageName.equals(activityRecord.packageName)) {
26897 public void registerScreenObserver(ScreenObserver observer) {
26898 mScreenObservers.add(observer);
26902 public boolean canStartMoreUsers() {
26903 return mUserController.canStartMoreUsers();
26907 public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
26908 mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
26912 public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
26913 mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
26917 public int getMaxRunningUsers() {
26918 return mUserController.mMaxRunningUsers;
26922 public boolean isCallerRecents(int callingUid) {
26923 return getRecentTasks().isCallerRecents(callingUid);
26927 public boolean isRecentsComponentHomeActivity(int userId) {
26928 return getRecentTasks().isRecentsComponentHomeActivity(userId);
26932 public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
26933 ActivityManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
26937 public boolean isUidActive(int uid) {
26938 synchronized (ActivityManagerService.this) {
26939 return isUidActiveLocked(uid);
26944 public List<ProcessMemoryState> getMemoryStateForProcesses() {
26945 List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
26946 synchronized (mPidsSelfLocked) {
26947 for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
26948 final ProcessRecord r = mPidsSelfLocked.valueAt(i);
26949 final int pid = r.pid;
26950 final int uid = r.uid;
26951 final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
26952 if (memoryStat == null) {
26955 ProcessMemoryState processMemoryState =
26956 new ProcessMemoryState(uid,
26959 memoryStat.pgfault,
26960 memoryStat.pgmajfault,
26961 memoryStat.rssInBytes,
26962 memoryStat.cacheInBytes,
26963 memoryStat.swapInBytes);
26964 processMemoryStates.add(processMemoryState);
26967 return processMemoryStates;
26971 public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
26972 ActivityManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
26976 public Intent getHomeIntent() {
26977 synchronized (ActivityManagerService.this) {
26978 return ActivityManagerService.this.getHomeIntent();
26983 public void notifyDefaultDisplaySizeChanged() {
26984 synchronized (ActivityManagerService.this) {
26985 if (mSystemServiceManager.isBootCompleted() && mHomeProcess != null) {
26987 // TODO: Ugly hack to unblock the release
26988 Slog.i(TAG, "Killing home process because of display size change");
26989 removeProcessLocked(mHomeProcess, false, true, "kill home screen size");
26996 * Called by app main thread to wait for the network policy rules to get updated.
26998 * @param procStateSeq The sequence number indicating the process state change that the main
26999 * thread is interested in.
27002 public void waitForNetworkStateUpdate(long procStateSeq) {
27003 final int callingUid = Binder.getCallingUid();
27004 if (DEBUG_NETWORK) {
27005 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
27008 synchronized (this) {
27009 record = mActiveUids.get(callingUid);
27010 if (record == null) {
27014 synchronized (record.networkStateLock) {
27015 if (record.lastDispatchedProcStateSeq < procStateSeq) {
27016 if (DEBUG_NETWORK) {
27017 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
27018 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
27019 + " lastProcStateSeqDispatchedToObservers: "
27020 + record.lastDispatchedProcStateSeq);
27024 if (record.curProcStateSeq > procStateSeq) {
27025 if (DEBUG_NETWORK) {
27026 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
27027 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
27028 + ", procStateSeq: " + procStateSeq);
27032 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
27033 if (DEBUG_NETWORK) {
27034 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
27035 + procStateSeq + ", so no need to wait. Uid: "
27036 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
27037 + record.lastNetworkUpdatedProcStateSeq);
27042 if (DEBUG_NETWORK) {
27043 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
27044 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
27046 final long startTime = SystemClock.uptimeMillis();
27047 record.waitingForNetwork = true;
27048 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
27049 record.waitingForNetwork = false;
27050 final long totalTime = SystemClock.uptimeMillis() - startTime;
27051 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
27052 Slog.w(TAG_NETWORK, "Total time waited for network rules to get updated: "
27053 + totalTime + ". Uid: " + callingUid + " procStateSeq: "
27054 + procStateSeq + " UidRec: " + record
27055 + " validateUidRec: " + mValidateUids.get(callingUid));
27057 } catch (InterruptedException e) {
27058 Thread.currentThread().interrupt();
27063 public void waitForBroadcastIdle(PrintWriter pw) {
27064 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
27066 boolean idle = true;
27067 synchronized (this) {
27068 for (BroadcastQueue queue : mBroadcastQueues) {
27069 if (!queue.isIdle()) {
27070 final String msg = "Waiting for queue " + queue + " to become idle...";
27080 final String msg = "All broadcast queues are idle!";
27086 SystemClock.sleep(1000);
27092 * Return the user id of the last resumed activity.
27095 public @UserIdInt int getLastResumedActivityUserId() {
27096 enforceCallingPermission(
27097 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
27098 synchronized (this) {
27099 if (mLastResumedActivity == null) {
27100 return mUserController.getCurrentUserId();
27102 return mLastResumedActivity.userId;
27107 * Kill processes for the user with id userId and that depend on the package named packageName
27110 public void killPackageDependents(String packageName, int userId) {
27111 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
27112 if (packageName == null) {
27113 throw new NullPointerException(
27114 "Cannot kill the dependents of a package without its name.");
27117 long callingId = Binder.clearCallingIdentity();
27118 IPackageManager pm = AppGlobals.getPackageManager();
27121 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
27122 } catch (RemoteException e) {
27124 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
27125 throw new IllegalArgumentException(
27126 "Cannot kill dependents of non-existing package " + packageName);
27129 synchronized(this) {
27130 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
27131 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
27132 "dep: " + packageName);
27135 Binder.restoreCallingIdentity(callingId);
27140 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
27141 CharSequence message) throws RemoteException {
27142 if (message != null) {
27143 enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
27144 "dismissKeyguard()");
27146 final long callingId = Binder.clearCallingIdentity();
27148 mKeyguardController.dismissKeyguard(token, callback, message);
27150 Binder.restoreCallingIdentity(callingId);
27155 public int restartUserInBackground(final int userId) {
27156 return mUserController.restartUser(userId, /* foreground */ false);
27160 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
27161 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
27162 "scheduleApplicationInfoChanged()");
27164 synchronized (this) {
27165 final long origId = Binder.clearCallingIdentity();
27167 updateApplicationInfoLocked(packageNames, userId);
27169 Binder.restoreCallingIdentity(origId);
27174 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
27175 final boolean updateFrameworkRes = packagesToUpdate.contains("android");
27176 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
27177 final ProcessRecord app = mLruProcesses.get(i);
27178 if (app.thread == null) {
27182 if (userId != UserHandle.USER_ALL && app.userId != userId) {
27186 final int packageCount = app.pkgList.size();
27187 for (int j = 0; j < packageCount; j++) {
27188 final String packageName = app.pkgList.keyAt(j);
27189 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
27191 final ApplicationInfo ai = AppGlobals.getPackageManager()
27192 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
27194 app.thread.scheduleApplicationInfoChanged(ai);
27196 } catch (RemoteException e) {
27197 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
27198 packageName, app));
27203 if (updateFrameworkRes) {
27204 // Update system server components that need to know about changed overlays. Because the
27205 // overlay is applied in ActivityThread, we need to serialize through its thread too.
27206 final Executor executor = ActivityThread.currentActivityThread().getExecutor();
27207 final DisplayManagerInternal display =
27208 LocalServices.getService(DisplayManagerInternal.class);
27209 if (display != null) {
27210 executor.execute(display::onOverlayChanged);
27212 if (mWindowManager != null) {
27213 executor.execute(mWindowManager::onOverlayChanged);
27219 * Attach an agent to the specified process (proces name or PID)
27221 public void attachAgent(String process, String path) {
27223 synchronized (this) {
27224 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
27225 if (proc == null || proc.thread == null) {
27226 throw new IllegalArgumentException("Unknown process: " + process);
27229 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
27230 if (!isDebuggable) {
27231 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
27232 throw new SecurityException("Process not debuggable: " + proc);
27236 proc.thread.attachAgent(path);
27238 } catch (RemoteException e) {
27239 throw new IllegalStateException("Process disappeared");
27244 public static class Injector {
27245 private NetworkManagementInternal mNmi;
27247 public Context getContext() {
27251 public AppOpsService getAppOpsService(File file, Handler handler) {
27252 return new AppOpsService(file, handler);
27255 public Handler getUiHandler(ActivityManagerService service) {
27256 return service.new UiHandler();
27259 public boolean isNetworkRestrictedForUid(int uid) {
27260 if (ensureHasNetworkManagementInternal()) {
27261 return mNmi.isNetworkRestrictedForUid(uid);
27266 private boolean ensureHasNetworkManagementInternal() {
27267 if (mNmi == null) {
27268 mNmi = LocalServices.getService(NetworkManagementInternal.class);
27270 return mNmi != null;
27275 public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
27276 throws RemoteException {
27277 synchronized (this) {
27278 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27282 final long origId = Binder.clearCallingIdentity();
27284 r.setShowWhenLocked(showWhenLocked);
27286 Binder.restoreCallingIdentity(origId);
27292 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
27293 synchronized (this) {
27294 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27298 final long origId = Binder.clearCallingIdentity();
27300 r.setTurnScreenOn(turnScreenOn);
27302 Binder.restoreCallingIdentity(origId);
27308 public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
27309 throws RemoteException {
27310 enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
27311 "registerRemoteAnimations");
27312 definition.setCallingPid(Binder.getCallingPid());
27313 synchronized (this) {
27314 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27318 final long origId = Binder.clearCallingIdentity();
27320 r.registerRemoteAnimations(definition);
27322 Binder.restoreCallingIdentity(origId);
27328 public void registerRemoteAnimationForNextActivityStart(String packageName,
27329 RemoteAnimationAdapter adapter) throws RemoteException {
27330 enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
27331 "registerRemoteAnimationForNextActivityStart");
27332 adapter.setCallingPid(Binder.getCallingPid());
27333 synchronized (this) {
27334 final long origId = Binder.clearCallingIdentity();
27336 mActivityStartController.registerRemoteAnimationForNextActivityStart(packageName,
27339 Binder.restoreCallingIdentity(origId);
27344 /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
27346 public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
27347 synchronized (this) {
27348 final long origId = Binder.clearCallingIdentity();
27350 mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
27352 Binder.restoreCallingIdentity(origId);